保龄球计分算法

Posted by hcy on October 27, 2020

保龄球计分算法

题目描述:

​ 保龄球前面个会摆放10个球瓶,计分规则如下:

​ 如果第一球就把全部的球瓶击倒,所得的分数是10分再加下两球的倒瓶数;如果第一球没有全部击倒,就要再打一次,如果两次能把全部球瓶击倒,则分数是10分再加下一球的倒瓶数;如果两次加一块没有击倒全部球数,则分值为两次的倒瓶数和。

​ 请你写一个记分牌程序,统计每次的得分。

​ 可以参考下保龄球-百度百科介绍的计分规则部分,题目和真实场景下是相同的。

保龄球项目是根据运动员投球所击倒的球瓶数量来计算得分,按运动员在规定局数中所得分数的多少决定胜负。记分规则如下:每局比赛由10格组成,前9格中运动员每格有两次投球机会:(1)如该格第一次投球击倒全部10个球瓶,则不需第二次投球,该格计为全中,该格全中所击倒的瓶数(10分)加随后两次投球所击倒的瓶数为该格所得的分数;(2)若该格第一次投球未能击倒全部10个球瓶,则可投第二次,若第二次投球将剩余的球瓶全部击倒,则该格计为补中,该格两次投球所击到的瓶数(10分)加下一次投球所击倒的瓶数为该格所得的分数;(3)若该格两次投球未能将10个球瓶全部击倒,则称为失误,该格得分为两次投球所击倒的全部瓶数。在第10格中,如果在第一或第二次投球中出现了全中或补中,则运动员可进行第三次投球,该格所得分数为该格实际击倒的球瓶数量。按上述规定将运动员10格所得分数进行累计,即为该局得分

分析:

​ 分析此问题,首先一次击球后是无法判断出成绩的,因为一次击球如果全部击倒,则会奖励下两球的倒瓶数,如果两次能全部击倒,则会奖励下一次的倒瓶数,如果两次加一起都没有全部击倒,则直接计算分值。

所以有如下规则:

  • 如果第一球 = 10,则分数等于 第一球 + 第二球 + 第三球

  • 如果第一球 + 第二球 = 10,则分数等于 第一球 + 第二球 + 第三球

  • 如果第一球 + 第二球 < 10,则分数等于 第一球 + 第二球

​ 所以将每次的分值记录下来,等数据满足条件能够计算时再开始计算,并移除已经计算的部分。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    public static class BLQ {
        /*
         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 0 0 0  第二局得分
         0 0 0 0 0 0 0 0 0 0 0  第一局得分
         */
        int[][] scores = new int[11][4];
        int x = 0;
        int y = 0;
        boolean finish = false;

        public void addScore(int score) {
            if (finish) {
                return;
            }
            scores[x][y] = score;
            //查询前两局,是否需要附加分
            for (int i = 1; i <= 2; i++) {
                if (x - i > 0 && scores[x - i][3] > 0) {
                    scores[x - i][2] += score;
                    scores[x - i][3]--;
                }
            }

            //全中或本次对局完成,调整到下一局
            if (score == 10) {
                scores[x][3] = 2;
                x++;
                y = 0;
            } else if (y == 1) {
                if (scores[x][0] + scores[x][1] == 10) {
                    scores[x][3] = 1;
                }
                x++;
                y = 0;
            } else {
                y++;
            }
            //判断是否终止,如果第十局没有中,或者第十局已经投过一次,则终止计分
            if (x == 10) {
                if (scores[9][0] != 10 && scores[9][0] + scores[9][1] != 10) {
                    finish = true;
                }
                if (y > 0) {
                    finish = true;
                }
            }
        }

        public List<Integer> getScore() {
            List<Integer> result = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                result.add(scores[i][0] + scores[i][1] + scores[i][2]);
            }
            return result;
        }
    }



转载请注明出处:https://www.huangchaoyu.com/2020/10/27/保龄球计分算法/