技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

マジで駄文。ボウリングのスコア計算

ボウリングのスコア計算ってどういうルールなんだろう?
と思って調べてみた。

スコアの付け方

なるほどそういうルールだったのか…興味ないから今まで知らんかった(汗

  • ストライク = 10 点+次の 2 投分
  • スペア = 10 点 + 次の 1 投分

ストライクは次の 2 投分 + 10 するということは、「ストライク → 1, 3」となったとき、10+1+3, 1, 3 という計算になるのだろう。
仮に9 フレーム目まで All Strikeで、10フレーム目で「1, 0」だったと仮定すると

9 フレーム目にフィードバックで 11, 8 フレーム目= 10 + 10(9フレーム目) + 1(10フレーム目) みたいな計算になるはず。
てことは、実質最後から計算した方が計算しやすいのかもしれない。

全フレームストライクと仮定すると、最初の 2 投まで1投目のスコアはつかず、3投目決まった時点で 30 点になる。
で、その後もストライクが続くと 1 フレームあたりマックススコア 30 が 10 フレーム続くので、 300 点マックスと。

やっぱりこれは後ろから計算した方が楽そうだ。

python にゃ配列の処理が豊富なので、色々楽にできる。

# 各フレームのスコアを列挙してみた
score = [
    [9, 1],
    [8, 2],
    [10],
    [5, 0],
    [3, 6],
    [4, 2],
    [7, 3],
    [6, 3],
    [10],
    [9, 1, 9]
]
score.reverse()
score

[[9, 1, 9], [10], [6, 3], [7, 3], [4, 2], [3, 6], [5, 0], [10], [8, 2], [9, 1]]

逆順ソートできるのでイイネ
そしたら 10 フレーム目だけ単純 sum して残りをスライスでループしたらいい

total=0
next1, next2 = 0, 0

# 最終フレームは特別扱い
total += sum(score[0])
if len(score[0]) == 3:
    next1, next2, _ = score[0]
else:
    next1, next2 = score[0]
print(f'Total: {total}')

# 他のフレームを計算
for frame in score[1:]:
    print(f'frame {frame}')
    frame_sum = sum(frame)
    if len(frame) == 1:
        print(f'strike! 10 + {next1} + {next2}')
        total += 10 + next1 + next2
        next1, next2 = 10, next1
    elif frame_sum == 10:
        print(f'spere! 10 + {next1}')
        total += 10 + next1
        next1, next2 = frame
    else:
        print(f'append {frame_sum}')
        total += frame_sum
        next1, next2 = frame
    print(f'Total: {total}')

total

結果: イインジャネ?

Total: 19
frame [10]
strike! 10 + 9 + 1
Total: 39
frame [6, 3]
append 9
Total: 48
frame [7, 3]
spere! 10 + 6
Total: 64
frame [4, 2]
append 6
Total: 70
frame [3, 6]
append 9
Total: 79
frame [5, 0]
append 5
Total: 84
frame [10]
strike! 10 + 5 + 0
Total: 99
frame [8, 2]
spere! 10 + 10
Total: 119
frame [9, 1]
spere! 10 + 8
Total: 137
137