实践题目:保龄球比赛计分
保龄球比赛一般分十局,每局最多可扔两个球,如果第一个球将所有的瓶子打倒了,就没必要打第二个球。但每局的计分可能会依赖后面的扔球得分,即如果这局扔第一个球得了10分,我们称全中,那个这局的得分=10分+后面扔的两球的得分,如果这局扔两球共得10分,我们称补中,那个这局的得分=10分+后面扔的一球的得分。
如下为敏捷培训时教练画的图:
答案有很多种,如下是我个人的做法,具体过程就不展示了。直接附上代码:
BowlingGameTest.java
package com.bijian.study.bowling.test; import org.junit.Assert; import org.junit.Test; import com.bijian.study.bowling.Game; public class BowlingGameTest { @Test public void normal_roll_should_return_sum_of_tow_rolls() { Game game = new Game(20); game.roll(4); game.roll(5); Assert.assertEquals(4+5,game.getFramescore(1)); Assert.assertEquals(4+5,game.getTotalscore()); } @Test public void spare_roll_should_return_sum_contain_next_roll() { Game game = new Game(20); game.roll(5); game.roll(5); game.roll(4); game.roll(5); Assert.assertEquals(5+5+4,game.getFramescore(2)); Assert.assertEquals((5+5+4)+(4+5),game.getTotalscore()); } @Test public void strike_roll_should_return_sum_contain_next_two_rolls() { Game game = new Game(20); game.roll(10); game.roll(5); game.roll(4); Assert.assertEquals(10+5+4,game.getFramescore(1)); Assert.assertEquals(5+4,game.getFramescore(2)); Assert.assertEquals((10+5+4)+(5+4),game.getTotalscore()); } @Test public void last_normal_roll_should_return_last_frame() { Game game = new Game(20); game.roll(10); game.roll(5); game.roll(4); game.roll(3); game.roll(4); game.roll(10); game.roll(3); game.roll(3); game.roll(0); game.roll(3); game.roll(2); game.roll(8); game.roll(10); game.roll(10); game.roll(2); game.roll(3); Assert.assertEquals(10+5+4,game.getFramescore(2)); Assert.assertEquals(3+4,game.getFramescore(3)); Assert.assertEquals(10+3+3,game.getFramescore(4)); Assert.assertEquals(3+3,game.getFramescore(5)); Assert.assertEquals(0+3,game.getFramescore(6)); Assert.assertEquals(2+8+10,game.getFramescore(7)); Assert.assertEquals(10+10+2,game.getFramescore(8)); Assert.assertEquals(10+2+3,game.getFramescore(9)); Assert.assertEquals(2+3,game.getFramescore(10)); Assert.assertEquals((10+5+4)+(5+4)+(3+4)+(10+3+3)+(3+3)+(0+3)+(2+8+10)+(10+10+2)+(10+2+3)+(2+3),game.getTotalscore()); } @Test public void last_spare_roll_should_return_last_frame_with_add_one_roll() { Game game = new Game(20); game.roll(10); game.roll(5); game.roll(4); game.roll(10); game.roll(5); game.roll(4); game.roll(0); game.roll(0); game.roll(10); game.roll(5); game.roll(4); game.roll(10); game.roll(10); game.roll(2); game.roll(8); game.roll(9); Assert.assertEquals(2+8+9,game.getFramescore(10)); Assert.assertEquals((10+5+4)+(5+4)+(10+5+4)+(5+4)+(0+0)+(10+5+4)+(5+4)+(10+10+2)+(10+2+8)+(2+8+9),game.getTotalscore()); } @Test public void last_strike_roll_should_return_last_frame_with_add_two_roll() { Game game = new Game(20); game.roll(10); game.roll(5); game.roll(4); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(5); game.roll(4); game.roll(10); game.roll(10); game.roll(10); game.roll(8); game.roll(2); //多投算无效球 game.roll(3); Assert.assertEquals(10+5+4,game.getFramescore(2)); Assert.assertEquals(10+10+10,game.getFramescore(3)); Assert.assertEquals(10+10+10,game.getFramescore(4)); Assert.assertEquals(10+10+5,game.getFramescore(5)); Assert.assertEquals(10+5+4,game.getFramescore(6)); Assert.assertEquals(5+4,game.getFramescore(7)); Assert.assertEquals(10+10+10,game.getFramescore(8)); Assert.assertEquals(10+10+8,game.getFramescore(9)); Assert.assertEquals(10+8+2,game.getFramescore(10)); //只有10局 Assert.assertEquals(0,game.getFramescore(11)); Assert.assertEquals((10+5+4)+(5+4)+(10+10+10)+(10+10+10)+(10+10+5)+(10+5+4)+(5+4)+(10+10+10)+(10+10+8)+(10+8+2),game.getTotalscore()); } @Test public void last_strike_roll_should_return_last_frame_with_add_two_max_score_roll() { Game game = new Game(20); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(5); game.roll(5); game.roll(5); game.roll(4); game.roll(10); game.roll(5); game.roll(4); game.roll(10); game.roll(10); game.roll(10); game.roll(10); //多投无效球 game.roll(10); Assert.assertEquals(0+0,game.getFramescore(1)); Assert.assertEquals(0+0,game.getFramescore(2)); Assert.assertEquals(0+0,game.getFramescore(3)); Assert.assertEquals(5+5+5,game.getFramescore(4)); Assert.assertEquals(5+4,game.getFramescore(8)); Assert.assertEquals(10+10+10,game.getFramescore(9)); Assert.assertEquals(10+10,game.getFramescore(10)); Assert.assertEquals((0+0)+(0+0)+(0+0)+(5+5+5)+(5+4)+(10+5+4)+(5+4)+(10+10+10)+(10+10+10)+(10+10),game.getTotalscore()); } @Test public void all_strike_roll_should_return_all_roll_with_last_two_max_score() { Game game = new Game(20); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(10); game.roll(10); //多投算无效球 game.roll(5); Assert.assertEquals(10+10+10,game.getFramescore(1)); Assert.assertEquals(10+10+10,game.getFramescore(4)); Assert.assertEquals(10+10+10,game.getFramescore(6)); Assert.assertEquals(10+10+10,game.getFramescore(10)); Assert.assertEquals((10+10+10)+(10+10+10)+(10+10+10)+(10+10+10)+(10+10+10)+(10+10+10)+(10+10+10)+(10+10+10)+(10+10+10)+(10+10),game.getTotalscore()); } @Test public void all_zero_roll_should_return_zero_score() { Game game = new Game(20); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); game.roll(0); Assert.assertEquals(0+0+0,game.getFramescore(1));//0 Assert.assertEquals(0+0+0,game.getFramescore(2));//0 Assert.assertEquals(0+0+0,game.getFramescore(3));//0 Assert.assertEquals(0+0+0,game.getFramescore(4));//0 Assert.assertEquals(0+0+0,game.getFramescore(5));//0 Assert.assertEquals(0+0+0,game.getFramescore(6));//0 Assert.assertEquals(0+0+0,game.getFramescore(7));//0 Assert.assertEquals(0+0+0,game.getFramescore(8));//0 Assert.assertEquals(0+0+0,game.getFramescore(9));//0 Assert.assertEquals(0+0+0,game.getFramescore(10));//0 Assert.assertEquals((0+0+0) + (0+0+0) + (0+0+0) + (0+0+0) + (0+0+0) + (0+0+0) + (0+0+0) + (0+0+0) + (0+0+0) + (0+0+0),game.getTotalscore()); } }
Game.java
package com.bijian.study.bowling; /** * 保龄球比赛,计算每局分数及总分 * 实现方法: * 采用rollscore数组记录比赛每次投球的分数,如果在一局当中,第一个球为满分的话,第二个球无需投,但在此数组中将其设置为0 * 采用rollscoreState数组记录rollscore对应的下标是真实的分数还是免投设置的值 * * @author BIJIAN */ public class Game { //满分值 public static int MAX_score = 10; //记录比赛每次投球的分数,如果在一局当中,第一个球为满分的话,第二个球无需投,但在此数组中将其设置为0 private int[] rollscore; //rollscoreState记录rollscore对应的下标是真实的分数还是免投设置的值 private boolean[] rollscoreState; //num为2*实际比赛的局数 private int num; //投球的下标记数器 private int currentRoll; /* * 构造方法 */ public Game(int num) { this.num = num; rollscore = new int[num+4]; rollscoreState = new boolean[num+2]; this.currentRoll = 0; } /* * 投球 */ public void roll(int pin) { if(currentRoll >= num + 2) { return; } if(currentRoll > num && rollscore[currentRoll-1] == MAX_score) { return; } rollscore[currentRoll++] = pin; if(pin == MAX_score && currentRoll < num) { rollscore[currentRoll] = 0; rollscoreState[currentRoll++] = true; } } /* * 获取指定局次的分数 */ public int getFramescore(int frame) { if(frame > num /2) { return 0; } int res = rollscore[(frame-1)*2] + rollscore[(frame-1)*2 + 1]; if(rollscore[(frame-1)*2] == MAX_score) { res += rollscore[frame*2] + rollscore[frame*2 + 1]; if(rollscore[frame*2] == MAX_score && rollscoreState[(frame-1)*2 + 1]) { res += rollscore[(frame+1)*2]; } }else if(res == MAX_score) { res += rollscore[frame*2]; } return res; } /* * 获取比赛总分 */ public int getTotalscore() { int totalscore = 0; for(int i=1;i<=currentRoll/2;i++) { if(i <= this.num/2) { totalscore += getFramescore(i); } } return totalscore; } }