ボウリングのスコア計算プログラムを書いた
最近会社にジョインしたパートナーが研修課題で「ボウリングのスコア計算プログラム」にチャレンジしているらしい。聞くところによるとスコア計算方法には新旧があって、旧ルールが結構複雑らしい。たしかに実際ボウリングしてても投げた後に前のフレームの点数が確定したりして、なにがなんだかよくわからんもんなあ。でもたぶんその要素があるからよりゲームが盛り上がるんだとは思うけど。ぱっと見でどっちが優勢かわからない感じとかワンチャン逆転あるかもと思わせる感じとか。
とにかく自分も計算方法をよく知らなかったし当然プログラムを書いたことはなかったので、いい機会だからRubyで書いてみた。
旧ルールのミソはこのあたり。
- スペアだったら次の1投の点を加算する
- ストライクだったら次の2投の点を加算する
- 10フレーム目は、1投目がストライクか2投目がスペアなら、3投目が投げられる
確かにこれはむずいなあ〜〜〜。参考回答とかよくありそうな感じにしてもしょうがないので、ニュアンスを込めて書いた。
https://gist.github.com/akht/693f0cbde58e9a754f641a341c125edf
scores = ARGV[0].strip.split(',').flat_map { |p| p == 'X' ? [10, nil] : p.to_i }
frames = scores.each_slice(6).flat_map { |n| n.size.even? ? n.each_slice(2).to_a : [n] }
total = (0..9).inject(0) do |acc, i|
current_frame, next_frame, after_next_frame = frames.slice(i, 3)
bonus = [current_frame.first == 10, current_frame.compact.sum == 10].sum { |i| i ? 1 : 0 } # strikeは2投分,spareは1投分
acc + current_frame.compact.sum + [next_frame, after_next_frame].flatten.compact.take(bonus).sum
end
puts total
❯ ruby bowling.rb 6,3,9,0,0,3,8,2,7,3,X,9,1,8,0,X,6,4,5
139
❯ ruby bowling.rb 0,10,1,5,0,0,0,0,X,X,X,5,1,8,1,0,4
107
❯ ruby bowling.rb X,X,X,X,X,X,X,X,X,X,X,X
300
ほんとにこのプログラムが正しいかわからんので週末ラウンドワンでテストしてきます。