-
Notifications
You must be signed in to change notification settings - Fork 0
ボウリングのスコア計算プログラムの演習問題 #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Gemfile
Outdated
|
|
||
| source "https://rubygems.org" # rubocop:disable Style/StringLiterals | ||
|
|
||
| # gem "rails" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bundle init した時に自動生成されたコードだと思いますが、このプログラムにおいては今後 rails を使うことはないのでこの行は削除しておきましょう。
03.bowling/bowling_score.rb
Outdated
|
|
||
| score_list = ARGV[0].split(',') | ||
|
|
||
| total = 0 # 合計得点を入力する変数 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
各変数の説明コメントですが必要でしょうか?
変数名から用途が想像できるコメントについては削除した方がコードの見通しが良くなります。少なくとも total は削除して問題ないかと。
03.bowling/bowling_score.rb
Outdated
| # ストライク・スペアの時の加算得点を計算するプログラム | ||
| def cal_addscore(score, flag, running_strike) | ||
| if flag > 0 # rubocop:disable Style/NumericPredicate | ||
| add_score = score # 得点を加算 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add_score がメソッド外のスコープのものと名前が被っていますね。メソッド外の処理もメソッド化してスコープを分けられないでしょうか?
03.bowling/bowling_score.rb
Outdated
| # ストライクだった時の処理 | ||
| if score_s == 'X' | ||
| flame[0] += 1 # フレームを更新 | ||
| strike_spare_flag = 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_flag という名前からは true または false という値が類推されますが、実際には 1 2 が格納されていますね。
別の名前を検討しましょう。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
また、 1 2 がマジックナンバーになっているので定数を定義するようにしましょう。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strike_spare_flag と pre_strike の役割が被ってそうな点も気になりました 👀
03.bowling/bowling_score.rb
Outdated
| if flag > 0 # rubocop:disable Style/NumericPredicate | ||
| add_score = score # 得点を加算 | ||
| flag -= 1 # フラグの数を減らす | ||
| add_score += score if running_strike == true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
== true は省略可能ですね。
03.bowling/bowling_score.rb
Outdated
| else | ||
| add_score = 0 | ||
| end | ||
| return add_score, flag, false # rubocop:disable Style/RedundantReturn |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rubocop:disable を許容してしまうと、 Rubocopのルールセットを定義している意味が薄れるので、使わない方向で修正をお願いします 🙏
03.bowling/bowling_score.rb
Outdated
| end | ||
|
|
||
| # 得点加算部分の実装 | ||
| score_list.each do |score_s| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
score_s と score_i のスコープが被っているので、こういった型に依存した変数名にせざるを得なくなっていますが、あらかじめすべて convert_str2int に変換し終えてからスコア計算の処理に移ることで、スコープが被ることを防げないでしょうか?
03.bowling/bowling_score.rb
Outdated
| # 得点を合計得点に加算 | ||
| total += add_score + score_i | ||
|
|
||
| # 10フレーム目の処理を別で実装 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
10フレーム目の処理 が別途あるかのようなコメントですが、実際には存在しないので、コメントの修正をお願いします。
.rubocop.yml
Outdated
| inherit_gem: | ||
| rubocop-fjord: | ||
| - "config/rubocop.yml" | ||
| - "config/rubocop.yml" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
細かいですが行末の改行が消えているので元に戻しておきましょう 🙏
03.bowling/bowling_score.rb
Outdated
| @@ -0,0 +1,39 @@ | |||
| #!/usr/bin/env ruby # rubocop:disable Style/FrozenStringLiteralComment | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここも rubocop:disable しない方向で修正をお願いします。
03.bowling/bowling_score.rb
Outdated
| # ストライク・スペアの時の加算得点を計算するプログラム | ||
| def calculate_add_score(flame, score, score_list, ball_number) | ||
| add_score = 0 | ||
| return add_score if flame[0] == 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここはストライク・スペアの加算得点を計算しているわけではないですね。呼び元で「最終フレームでは calculate_add_score を呼ばないように」修正するのはどうでしょうか?
03.bowling/bowling_score.rb
Outdated
| #!/usr/bin/env ruby # rubocop:disable Style/FrozenStringLiteralComment | ||
|
|
||
| total = 0 | ||
| flame = [1, 1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
変数名が flame ですが中に入っている値はフレームではありませんね。また、flame[0] と flame[1] が全く関係のない値を保持しているので、なぜここだけ配列変数にしているのかが読み取れませんでした。
別々の変数にして適した名前を付けるようにしましょう。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
あと、ボウリングにおけるフレームのスペルは frame ですね。
flame だと炎という意味になってしまいます。
03.bowling/bowling_score.rb
Outdated
| score_list = score_list.map { |score| score == 'X' ? 10 : score.to_i } | ||
|
|
||
| # ストライク・スペアの時の加算得点を計算するプログラム | ||
| def calculate_add_score(flame, score, score_list, ball_number) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
score_list にはすべての投球が含まれていますが、このメソッドの処理にすべての投球は不要なはずです。判定に必要な直近3投球のみを渡すようにしてはどうでしょうか?
それができると ball_number も不要になるはずです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この方法であれば score も渡す必要がないように見えました。
03.bowling/bowling_score.rb
Outdated
| end | ||
|
|
||
| # 得点加算部分の実装 | ||
| score_list.each_with_index do |score, ball_number| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
以下のように Enumerable#sum を使うと total の宣言や加算が不要になりますね。
score_list.each_with_index do |score, ball_number|
# 戻り値を `total` に加算する値にする
endThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
記載がないので憶測ですが、
total = score_list.each_with_index.sum do |score, ball_number|
# 省略
score + add_score
endという認識でよろしいですか?
03.bowling/bowling_score.rb
Outdated
| # ストライク・スペアの時の加算得点を計算 | ||
| def calculate_add_score(throw, score_group) | ||
| add_score = 0 | ||
| add_score += score_group[1] + score_group[2] if throw == 1 && score_group[0] == 10 # ストライク判定 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここは add_score += score_group[1..2].sum とも書けます。参考まで。
03.bowling/bowling_score.rb
Outdated
| def calculate_add_score(throw, score_group) | ||
| add_score = 0 | ||
| add_score += score_group[1] + score_group[2] if throw == 1 && score_group[0] == 10 # ストライク判定 | ||
| add_score += score_group[2] if throw == 1 && score_group[0] + score_group[1] == 10 # スペア判定 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここの条件部分も score_group[0..1].sum と書けますね 👍
03.bowling/bowling_score.rb
Outdated
|
|
||
| total = score_list.each_with_index.sum do |score, index| | ||
| score_group = score_list[index, 3] | ||
| add_score = if frame == 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
frame == 10 がこのブロックの中で2回登場しています。1箇所にまとめられないでしょうか?
最終フレームの場合はボーナススコアの計算も不要なので、ここでアーリーリターンならぬアーリーnextをすると、以降の行では最終フレームのケースを考慮しなくてよくなりコードの見通しが良くなりそうです 👍
03.bowling/bowling_score.rb
Outdated
| # 投球数、フレーム数の更新 | ||
| if frame == 10 # 10フレーム目はそれ以上フレーム数が更新されないので、個別に投球数を進める | ||
| throw += 1 | ||
| elsif throw == 1 && score == 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
この判定は calculate_add_score の中でも同じ判定をしています。1箇所にまとめられないでしょうか?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
こちらは修正後のコードを見てもまだ重複している状況なので、1箇所にまとめられないか検討をお願いします 🙏
03.bowling/bowling_score.rb
Outdated
| elsif throw == 1 && score == 10 | ||
| frame += 1 # ストライク処理 | ||
| elsif throw == 1 | ||
| throw = 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここは frame += 1 とすると都合が悪いでしょうか? frame += 1 でいいなら他の条件分岐とまとめられそうに見えます。
03.bowling/bowling_score.rb
Outdated
| add_score += score_group[2] | ||
| throw = 2 | ||
| else | ||
| frame += 1 if throw == 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw == 2 が2回登場するので1回にまとめたいです 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
指摘箇所の中にはthrow == 2は2回出てきていないと思います。
恐らく一行下のthrow = (throw == 2 ? 1 : 2)を指しているのだと思うのですが合っていますか?
03.bowling/bowling_score.rb
Outdated
| score_list = ARGV[0].split(',') | ||
| score_list = score_list.map { |score| score == 'X' ? 10 : score.to_i } | ||
|
|
||
| def update_game_state(frame, throw, score_group) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3つの引数を渡して、3つの戻り値を得るのであれば、おそらくそれはメソッドの切り出し方があまりよくないです。「結合度が高く、凝集度が低い」という言い方をします。一旦、ここはメソッドに切り出さずに呼び出し元と統合してはどうでしょう?
その上で、「ストライク判定」や「スペア判定」といった単位で新しいメソッドを切り出してはどうでしょうか?
1mori
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確認お願いします。
03.bowling/bowling_score.rb
Outdated
| add_score += score_group[2] | ||
| throw = 2 | ||
| else | ||
| frame += 1 if throw == 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
指摘箇所の中にはthrow == 2は2回出てきていないと思います。
恐らく一行下のthrow = (throw == 2 ? 1 : 2)を指しているのだと思うのですが合っていますか?
No description provided.