Conversation
|
|
||
| source "https://rubygems.org" # rubocop:disable Style/StringLiterals | ||
|
|
||
| # gem "rails" |
There was a problem hiding this comment.
bundle init した時に自動生成されたコードだと思いますが、このプログラムにおいては今後 rails を使うことはないのでこの行は削除しておきましょう。
|
|
||
| score_list = ARGV[0].split(',') | ||
|
|
||
| total = 0 # 合計得点を入力する変数 |
There was a problem hiding this comment.
各変数の説明コメントですが必要でしょうか?
変数名から用途が想像できるコメントについては削除した方がコードの見通しが良くなります。少なくとも total は削除して問題ないかと。
| # ストライク・スペアの時の加算得点を計算するプログラム | ||
| def cal_addscore(score, flag, running_strike) | ||
| if flag > 0 # rubocop:disable Style/NumericPredicate | ||
| add_score = score # 得点を加算 |
There was a problem hiding this comment.
add_score がメソッド外のスコープのものと名前が被っていますね。メソッド外の処理もメソッド化してスコープを分けられないでしょうか?
| # ストライクだった時の処理 | ||
| if score_s == 'X' | ||
| flame[0] += 1 # フレームを更新 | ||
| strike_spare_flag = 2 |
There was a problem hiding this comment.
_flag という名前からは true または false という値が類推されますが、実際には 1 2 が格納されていますね。
別の名前を検討しましょう。
There was a problem hiding this comment.
また、 1 2 がマジックナンバーになっているので定数を定義するようにしましょう。
There was a problem hiding this comment.
strike_spare_flag と pre_strike の役割が被ってそうな点も気になりました 👀
| if flag > 0 # rubocop:disable Style/NumericPredicate | ||
| add_score = score # 得点を加算 | ||
| flag -= 1 # フラグの数を減らす | ||
| add_score += score if running_strike == true |
| else | ||
| add_score = 0 | ||
| end | ||
| return add_score, flag, false # rubocop:disable Style/RedundantReturn |
There was a problem hiding this comment.
rubocop:disable を許容してしまうと、 Rubocopのルールセットを定義している意味が薄れるので、使わない方向で修正をお願いします 🙏
| end | ||
|
|
||
| # 得点加算部分の実装 | ||
| score_list.each do |score_s| |
There was a problem hiding this comment.
score_s と score_i のスコープが被っているので、こういった型に依存した変数名にせざるを得なくなっていますが、あらかじめすべて convert_str2int に変換し終えてからスコア計算の処理に移ることで、スコープが被ることを防げないでしょうか?
| # 得点を合計得点に加算 | ||
| total += add_score + score_i | ||
|
|
||
| # 10フレーム目の処理を別で実装 |
There was a problem hiding this comment.
10フレーム目の処理 が別途あるかのようなコメントですが、実際には存在しないので、コメントの修正をお願いします。
| inherit_gem: | ||
| rubocop-fjord: | ||
| - "config/rubocop.yml" | ||
| - "config/rubocop.yml" No newline at end of file |
| @@ -0,0 +1,39 @@ | |||
| #!/usr/bin/env ruby # rubocop:disable Style/FrozenStringLiteralComment | |||
| # ストライク・スペアの時の加算得点を計算するプログラム | ||
| 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.
ここはストライク・スペアの加算得点を計算しているわけではないですね。呼び元で「最終フレームでは calculate_add_score を呼ばないように」修正するのはどうでしょうか?
| #!/usr/bin/env ruby # rubocop:disable Style/FrozenStringLiteralComment | ||
|
|
||
| total = 0 | ||
| flame = [1, 1] |
There was a problem hiding this comment.
変数名が flame ですが中に入っている値はフレームではありませんね。また、flame[0] と flame[1] が全く関係のない値を保持しているので、なぜここだけ配列変数にしているのかが読み取れませんでした。
別々の変数にして適した名前を付けるようにしましょう。
There was a problem hiding this comment.
あと、ボウリングにおけるフレームのスペルは frame ですね。
flame だと炎という意味になってしまいます。
| 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.
score_list にはすべての投球が含まれていますが、このメソッドの処理にすべての投球は不要なはずです。判定に必要な直近3投球のみを渡すようにしてはどうでしょうか?
それができると ball_number も不要になるはずです。
| end | ||
|
|
||
| # 得点加算部分の実装 | ||
| score_list.each_with_index do |score, ball_number| |
There was a problem hiding this comment.
以下のように Enumerable#sum を使うと total の宣言や加算が不要になりますね。
score_list.each_with_index do |score, ball_number|
# 戻り値を `total` に加算する値にする
endThere was a problem hiding this comment.
記載がないので憶測ですが、
total = score_list.each_with_index.sum do |score, ball_number|
# 省略
score + add_score
endという認識でよろしいですか?
| # ストライク・スペアの時の加算得点を計算 | ||
| 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.
ここは add_score += score_group[1..2].sum とも書けます。参考まで。
| 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 # スペア判定 |
|
|
||
| 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.
frame == 10 がこのブロックの中で2回登場しています。1箇所にまとめられないでしょうか?
最終フレームの場合はボーナススコアの計算も不要なので、ここでアーリーリターンならぬアーリーnextをすると、以降の行では最終フレームのケースを考慮しなくてよくなりコードの見通しが良くなりそうです 👍
| # 投球数、フレーム数の更新 | ||
| if frame == 10 # 10フレーム目はそれ以上フレーム数が更新されないので、個別に投球数を進める | ||
| throw += 1 | ||
| elsif throw == 1 && score == 10 |
There was a problem hiding this comment.
この判定は calculate_add_score の中でも同じ判定をしています。1箇所にまとめられないでしょうか?
There was a problem hiding this comment.
こちらは修正後のコードを見てもまだ重複している状況なので、1箇所にまとめられないか検討をお願いします 🙏
| elsif throw == 1 && score == 10 | ||
| frame += 1 # ストライク処理 | ||
| elsif throw == 1 | ||
| throw = 2 |
There was a problem hiding this comment.
ここは frame += 1 とすると都合が悪いでしょうか? frame += 1 でいいなら他の条件分岐とまとめられそうに見えます。
| add_score += score_group[2] | ||
| throw = 2 | ||
| else | ||
| frame += 1 if throw == 2 |
There was a problem hiding this comment.
指摘箇所の中にはthrow == 2は2回出てきていないと思います。
恐らく一行下のthrow = (throw == 2 ? 1 : 2)を指しているのだと思うのですが合っていますか?
| 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.
3つの引数を渡して、3つの戻り値を得るのであれば、おそらくそれはメソッドの切り出し方があまりよくないです。「結合度が高く、凝集度が低い」という言い方をします。一旦、ここはメソッドに切り出さずに呼び出し元と統合してはどうでしょう?
その上で、「ストライク判定」や「スペア判定」といった単位で新しいメソッドを切り出してはどうでしょうか?
| add_score += score_group[2] | ||
| throw = 2 | ||
| else | ||
| frame += 1 if throw == 2 |
There was a problem hiding this comment.
指摘箇所の中にはthrow == 2は2回出てきていないと思います。
恐らく一行下のthrow = (throw == 2 ? 1 : 2)を指しているのだと思うのですが合っていますか?
No description provided.