###如下部分为实现主体类
package ideal4j.imp.bigscreen.dailypattern.utils.test.tdd.bowlingGame;
/**
* @Author: Jolly
* @Date: 2019/11/5 0005 18:54
* @Project: demo
* @Version: 1.0
* @Description: 这里是基于TDD规则完成保龄球案例的一个实现类
*/
public class BowlingGame {
/**
* 第二次重构之前
*/
public void roll(int count) {
}
public int score() {
return 0;
}
/**
* 第二次重构,roll点同时计算得分
*/
private int score =0;
public void rollV2(int count) {
score += count;
}
public int scoreV2() {
return score;
}
/**
* 第四次重构,roll点同时计算得分
*/
private int rolls[] =new int[21];
private int currentRoll =0;
public void rollV4(int count) {
rolls[currentRoll++] = count;
}
public int scoreV4() {
int score =0;
for (int i =0; i
//考虑数组越界可能,从倒数第二个倒球数开始计算
//倒数第二轮,针对case出现一次STRIKE或者SPARE,后续为0,简化,不出现此种情况
if (i >=0 && i <18) {
//前18轮,针对case出现一次STRIKE或者SPARE,后续为0,实际中出现下一轮或者下两轮的得分计算
if (validateStrike(rolls[i])) {
score +=10 +rolls[i +1] +rolls[i +2];
}else if (validateSpare(rolls[i],rolls[i +1]) && (!validateStrike(rolls[i]) && (!validateStrike(rolls[i +1])))) {
score +=10 +rolls[i +2];
//出现spare,当前轮两次击球总数为10,第二次击球数已经计算过,跳过第二次,故此i++
i++;
}else {
score +=rolls[i];
}
}else if (i >=18 && i <20) {
//TODO 此处待验证,针对末尾一轮出现STRIKE或者SPARE的case
if (validateStrike(rolls[i])) {
score +=10 +rolls[i +1] +rolls[i +2];
return score;
}else if (validateSpare(rolls[i],rolls[i +1])) {
score +=10 + +rolls[i +2];
return score;
}else {
//score += rolls[i];
//最后一次出现Spare或者Strike,前十轮计算分数完结,后面多打的不用再额外累加.
return score;
}
}else {
;
}
}
return score;
}
/**
* 添加STRIKE的计算方法
*/
public Boolean validateStrike(int firstRollCount) {
if (10 == firstRollCount) {
return true;
}
return false;
}
/**
* 添加SPARE的计算方法
*/
public Boolean validateSpare(int firstRollCount,int secondRollCount) {
if (10 == firstRollCount + secondRollCount) {
return true;
}
return false;
}
/**
* @desc 此处省略中间N次重构过程,推演出最终一次重构方法
*/
//用来存放投掷击倒的数目
public int rollSummary[] =new int[21];
//数组下标
int ball =0;
//分数
int scoreSummary;
//记录当前是第几轮
int countRound =0;
//判断第一次投球,默认依次加载数据,第一次算作true
boolean firstThrow =true;
//当前一轮得分
private int currentRollSum =0;
/**
* @desc 用来判断是否是第一次投球
*/
private void judgeFirstThrow(int count) {
if (firstThrow) {
if (count ==10) {
countRound++;
}else {
firstThrow =false;
}
}else {
firstThrow =true;
countRound++;
}
}
/**
* @desc 添加分数 将分数添加到数组中
*/
public void rollSummary(int count) {
rollSummary[ball++] = count;
judgeFirstThrow(count);
}
/**
* @desc 返回这是第几轮
*/
public int getCurrentRound() {
return countRound;
}
/**
* @desc 当前轮的计算方法循环当前轮的次数
* a[0]赋值第一次击球firstThrow 然后下标自增一;判断第一次都不是击倒了10个
* 规则 保龄球一轮两个球 第一个全中就是之前的分数+10+后面两次投掷的分数
* 补中 两次一共击倒10个 之前的分数加两次击倒的10分加后面一次的的分数
*/
public int scoreSummary(int currentRound) {
int scoreSummary =0;
int ball =0;
for (int countRound =0; countRound < currentRound; countRound++) {
int firstThrow =rollSummary[ball++];
if (firstThrow ==10) {
scoreSummary = scoreSummary +10 +rollSummary[ball] +rollSummary[ball +1];
}else {
int secondThrow =rollSummary[ball++];
int currentRollSum = firstThrow + secondThrow;
if (currentRollSum ==10) {
scoreSummary = currentRollSum +rollSummary[ball] + scoreSummary;
}else {
scoreSummary = currentRollSum + scoreSummary;
}
}
}
return scoreSummary;
}
}