5.TDD实现10回合保龄球比赛

1.题目
题目地址:http://cyber-dojo.org/setup_default_start_point/show/?from=individual

Write a program to score a game of Ten-Pin Bowling.
Input: string (described below) representing a bowling game
Ouput: integer score
The scoring rules:
Each game, or “line” of bowling, includes ten turns, or “frames” for the bowler.In each frame, the bowler gets up to two tries to knock down all ten pins.
  If the first ball in a frame knocks down all ten pins,this is called a “strike”. The frame is over. The score for the frame is ten plus the total of the pins knocked down in the next two balls.
  If the second ball in a frame knocks down all ten pins,this is called a “spare”. The frame is over. The score for the frame is ten plus the number of pins knocked down in the next ball.
  If, after both balls, there is still at least one of theten pins standing the score for that frame is simply the total number of pins knocked down in those two balls.
  If you get a spare in the last (10th) frame you get one more bonus ball. If you get a strike in the last (10th) frame you get two more bonus balls.These bonus throws are taken as part of the same turn.
  If a bonus ball knocks down all the pins, the process does not repeat. The bonus balls are only used to calculate the score of the final frame.
The game score is the total of all frame scores.
Examples:
X indicates a strike
/ indicates a spare
- indicates a miss
| indicates a frame boundary
The characters after the || indicate bonus balls
X|X|X|X|X|X|X|X|X|X||XX
Ten strikes on the first ball of all ten frames.
Two bonus balls, both strikes.
Score for each frame == 10 + score for next two
balls == 10 + 10 + 10 == 30
Total score == 10 frames x 30 == 300
9-|9-|9-|9-|9-|9-|9-|9-|9-|9-||
Nine pins hit on the first ball of all ten frames.
Second ball of each frame misses last remaining pin.
No bonus balls.
Score for each frame == 9
Total score == 10 frames x 9 == 90
5/|5/|5/|5/|5/|5/|5/|5/|5/|5/||5
Five pins on the first ball of all ten frames.
Second ball of each frame hits all five remaining
pins, a spare.
One bonus ball, hits five pins.
Score for each frame == 10 + score for next one
ball == 10 + 5 == 15
Total score == 10 frames x 15 == 150
X|7/|9-|X|-8|8/|-6|X|X|X||81
Total score == 167

写一个程序来得判决十杆保龄球比赛。
* 输入:字符串(描述如下)表示保龄球游戏
* 输出:整数的分数
*
* 评分规则:
* 保龄球的每一场比赛,或称“直线”,包括10圈,或者是投球手的“框架”。 在
* 每一轮中,投球手会尝试两次 把十个球都打掉。 如果一轮中的第一个球击倒了所有10个球, 这就是所谓的“击球”。框架结束了,这个框架的得分是10加上被击倒的总杆数 接下来一轮。
* 如果在一个框架内的第二个球击倒了所有10个引脚, 这就是所谓的“备用件”,这轮结束了,这个框架的得分是10加上下一球击中的得分数。
* 如果在两个球之后,仍然有至少一个球没有被击倒,这轮的分数是简单的 :那两个球中被击倒球的总数。
* 如果你在最后(第10)帧中得到一个备胎,你就会得到一个额外的球,更多的奖金。如果你在最后(10次)罢工 框架你得到两个额外的球。 这些额外的投掷是同一个回合的一部分。
* 如果一个额外的球击倒所有的引脚,整个过程 不重复。奖励球只被使用过 计算最终帧的分数。 游戏得分是所有框架得分的总和。
* 例子: X表示击球 /表示有备件 -表示遗漏 |表示一个框架边界 ||之后的字符表示奖励球
* X|X|X| X|X|X| X|X|X|X| || XX
* 在所有的10局中,第一个球被击中10次。两个额外的球,都是好球。
* 每一帧的分数== 10 +下两球的分数球== 10 + 10 + 10 = 30
* 总分= 10帧x 30 = 300
* 9-|9-|9-|9-|9-|9-|9-|9-|9-|9-||
* 第一个球击中了9个球。 每一帧的第二个球错过最后的剩余球。没有额外的球。
* 每帧得分== 9 总分= 10帧x 9 = 90
* 5/|5/|5/| 5/|5/|5/| 5/|5/|5/|5/||5
* 第一个球击中了5个引脚,第二个球击中了之后的引脚。
* 每一帧得分=10 + 下一球球==10 + 5 = 15
* 总分= 10帧x15 = 150
*
* X| 7/| 9-|x|-8 | 8/ |-6|X|X|X||81
* 总分= 10+10 + 10+9 + 9 + 10+8 + 8 + 10+0 + 6 + 10+10+10 + 10+10+8 +10+8+1
* =90 + 77
* = 167
* 20 39 48 66 74 84 90 120 148 167

2.测试

package cs.game.bowling;

import org.junit.Test;

import junit.framework.Assert;

public class BowlingGameTest {
    @Test
    public void 只有一个球() {
        //given
        String givenStr = "X|";
        int expectedScore = 10;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有两个球() {
        //given
        String givenStr = "X|9-|";
        int expectedScore = 28;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有三个球_1() {
        //given
        String givenStr = "X|9-|8-|";
        int expectedScore = 36;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有三个球_2() {
        //given
        String givenStr = "X|X|8-|";
        int expectedScore = 54;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有三个球_3() {
        //given
        String givenStr = "X|-9|8-|";
        int expectedScore = 36;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有三个球_4() {
        //given
        String givenStr = "8/|9/|8-|";
        int expectedScore = 45;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有十个球_1() {
        //given
        String givenStr = "5/|5/|5/|5/|5/|5/|5/|5/|5/|5/||5";
        int expectedScore = 150;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有十个球_2() {
        //given
        String givenStr = "X|7/|9-|X|-8|8/|-6|X|X|X|81";
        int expectedScore = 167;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }

    @Test
    public void 有十个球_3() {
        //given
        String givenStr = "X|X|X|X|X|X|X|X|X|X||XX";
        int expectedScore = 300;
        BowlingGame bowlingGame = new BowlingGame();

        //when
        int actualScore = bowlingGame.caculateScore(givenStr);

        //then
        Assert.assertEquals(expectedScore, actualScore);
    }
}

3.实现代码

package cs.game.bowling;

/**
 * 
 * @author shuai.chen
 * @date 2018年9月12日
 * @Description
 * 
 *              Write a program to score a game of Ten-Pin Bowling.
 *              Input: string (described below) representing a bowling game 
 *              Ouput: integer score
 * 
 *              The scoring rules:
 *              Each game, or "line" of bowling, includes ten turns, or "frames" for the bowler.
 *              In each frame, the bowler gets up to two tries to knock down all ten pins.
 *              If the first ball in a frame knocks down all ten pins, this is called a "strike".
 *              The frame is over. The score for the frame is ten plus the total of the pins knocked
 *              down in the next two balls.
 * 
 *              If the second ball in a frame knocks down all ten pins, this is called a "spare".
 *              The frame is over. The score for the frame is ten plus the number of pins knocked
 *              down in the next ball.
 * 
 *              If, after both balls, there is still at least one of the ten pins standing the score
 *              for that frame is simply the total number of pins knocked down in those two balls.
 * 
 *              If you get a spare in the last (10th) frame you get one more bonus ball. If you get
 *              a strike in the last (10th) frame you get two more bonus balls. These bonus throws
 *              are taken as part of the same turn. If a bonus ball knocks down all the pins, the
 *              process does not repeat. The bonus balls are only used to calculate the score of the
 *              final frame.
 * 
 *              The game score is the total of all frame scores.
 * 
 *              Examples:
 * 
 *              X indicates a strike / indicates a spare - indicates a miss | indicates a frame
 *              boundary The characters after the || indicate bonus balls
 * 
 *              X|X|X|X|X|X|X|X|X|X||XX Ten strikes on the first ball of all ten frames. Two bonus
 *              balls, both strikes. Score for each frame == 10 + score for next two balls == 10 +
 *              10 + 10 == 30 Total score == 10 frames x 30 == 300
 * 
 *              9-|9-|9-|9-|9-|9-|9-|9-|9-|9-|| Nine pins hit on the first ball of all ten frames.
 *              Second ball of each frame misses last remaining pin. No bonus balls. Score for each
 *              frame == 9 Total score == 10 frames x 9 == 90
 * 
 *              5/|5/|5/|5/|5/|5/|5/|5/|5/|5/||5 Five pins on the first ball of all ten frames.
 *              Second ball of each frame hits all five remaining pins, a spare. One bonus ball,
 *              hits five pins. Score for each frame == 10 + score for next one ball == 10 + 5 == 15
 *              Total score == 10 frames x 15 == 150
 * 
 *              X|7/|9-|X|-8|8/|-6|X|X|X||81 Total score == 167
 * 
 *            写一个程序来得判决十杆保龄球比赛。
 *            输入:字符串(描述如下)表示保龄球游戏
 *            输出:整数的分数 
 *              
 *            评分规则: 
 *              保龄球的每一场比赛,或称“直线”,包括10圈,或者是投球手的“框架”。 在
 *              每一轮中,投球手会尝试两次 把十个球都打掉。 如果一轮中的第一个球击倒了所有10个球, 这就是所谓的“击球”。框架结束了,这个框架的得分是10加上被击倒的总杆数 接下来一轮。 
 *              如果在一个框架内的第二个球击倒了所有10个引脚, 这就是所谓的“备用件”,这轮结束了,这个框架的得分是10加上下一球击中的得分数。 
 *              如果在两个球之后,仍然有至少一个球没有被击倒,这轮的分数是简单的 :那两个球中被击倒球的总数。
 *              如果你在最后(第10)帧中得到一个备胎,你就会得到一个额外的球,更多的奖金。如果你在最后(10次)罢工 框架你得到两个额外的球。 这些额外的投掷是同一个回合的一部分。
 *              如果一个额外的球击倒所有的引脚,整个过程 不重复。奖励球只被使用过 计算最终帧的分数。 游戏得分是所有框架得分的总和。 
 *              例子: X表示击球 /表示有备件 -表示遗漏   |表示一个框架边界  ||之后的字符表示奖励球
 *              
 *               X|X|X| X|X|X| X|X|X|X| || XX
 *               在所有的10局中,第一个球被击中10次。两个额外的球,都是好球。
 *               每一帧的分数== 10 +下两球的分数球== 10 + 10 + 10 = 30 
 *               总分= 10帧x 30 = 300 
 *                
 *                9-|9-|9-|9-|9-|9-|9-|9-|9-|9-||
 *                第一个球击中了9个球。 每一帧的第二个球错过最后的剩余球。没有额外的球。 
 *                每帧得分== 9 总分= 10帧x 9 = 90 
 *                
 *                5/|5/|5/| 5/|5/|5/| 5/|5/|5/|5/||5
 *              第一个球击中了5个引脚,第二个球击中了之后的引脚。
 *              每一帧得分=10 + 下一球球==10 + 5 = 15 
 *              总分= 10帧x15 = 150 
 *              
 *              X| 7/| 9-|x|-8 | 8/ |-6|X|X|X||81
 *              总分= 10+10  + 10+9 + 9     + 10+8 + 8 + 10+0 + 6 +     10+10+10 + 10+10+8 +10+8+1 
 *                =90 + 77
 *                = 167
 *              20   39   48   66   74   84   90    120   148   167 
 * 
 * 
 */
public class BowlingGame {
    public int caculateScore(String str) {
        /**总分数*/
        int totalScore = 0;
        /**总回合数,只要使用一种策略,就自增*/
        int totalShot = 0;

        for(int i = 0; i < str.length(); i++) {
            int score = 0;

            if(totalShot < 10) {
                /**策略一:X 则加后面两球*/
                if("X".equals(str.charAt(i) + "")) {
                    totalShot++;
                    score += 10;
                    int index = 0;
                    for (int j = i + 1; j < str.length(); j++) {
                        if(2 == index) {
                            break;
                        }
                        if(str.charAt(j) >= 49 && str.charAt(j) <= 57) {
                            score += str.charAt(j) - 48;
                            index++;
                        }
                        if(str.charAt(j) == '-') {
                            index++;
                        }
                        if(str.charAt(j) == 'X') {
                            score += 10;
                            index++;
                        }
                        if(str.charAt(j) == '/') {
                            score = score - (str.charAt(--j) - 48) + 10;
                            j++;
                            index++;
                        }

                    }
                }

                /** 策略二、三*/
                if (str.charAt(i) >= 49 && str.charAt(i) <= 57) {
                    score += str.charAt(i) - 48;
                    int index = 0;
                    char ch = str.charAt(i);
                    char cha = str.charAt(i + 1);
                    /** 策略二:两球10分加后面一球*/
                    if(str.charAt(i+1) == '/') {
                        totalShot++;
                        score = score - (str.charAt(i) - 48) + 10;
                        for (int j = i+2; j < str.length(); j++) {
                            if(index == 1) {
                                break;
                            }
                            if(str.charAt(j) == '-') {
                                index++;
                            }
                            if(str.charAt(j) >= 49 && str.charAt(j) <= 57) {
                                score += str.charAt(j) - 48;
                                index++;
                            }
                            if(str.charAt(j) == 'X') {
                                score += 10;
                                index++;
                            }
                        }
                    }
                    /** 策略三:2球未全中则不加后面*/
                    if(str.charAt(i+1) == '-') {
                        totalShot++;
                        score += 0;
                    }
                }

                /** 策略四、五、六*/
                if (str.charAt(i) == '-') {
                    int index = 0;
                    /** 策略四:第一球未中,第二球未中*/
                    if(str.charAt(i+1) == '-') {
                        totalShot++;
                    }

                    /** 策略五:第一球未中,第二球未全中*/
                    if(str.charAt(i+1) >= 49 && str.charAt(i+1) <= 57) {
                        totalShot++;
                        score += str.charAt(i+1) - 48;
                    }

                    /** 策略六:第一球未中,第二球全中*/
                    if(str.charAt(i+1) == 'X') {
                        totalShot++;
                        score += 10;
                        for (int j = i+2; j < str.length(); j++) {
                            if(index == 1) {
                                break;
                            }
                            if(str.charAt(j) == '-') {
                                index++;
                            }
                            if(str.charAt(j) >= 49 && str.charAt(j) <= 57) {
                                score += str.charAt(j) - 48;
                                index++;
                            }
                            if(str.charAt(j) == 'X') {
                                score += 10;
                                index++;
                            }
                        }
                    }
                    //自增是因为-是第一个球,下一个可能是1-9的数字或X,不自增就会多加一次
                    i++;
                }
            }

            totalScore += score;
        }
        return totalScore;
    }

    public static void main(String[] args) {
        System.out.println('1' - 48);
    }
}

猜你喜欢

转载自blog.csdn.net/u010986518/article/details/82693941