forked from fjordllc/ruby-practices
-
Notifications
You must be signed in to change notification settings - Fork 0
ボウリングプログラムをオブジェクト指向で作成しました。 #11
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
Open
s-tone-gs
wants to merge
11
commits into
main
Choose a base branch
from
bowling_object
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+167
−0
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
bd99e02
オブジェクト指向でボウリングプログラムを作成
s-tone-gs e4d0de2
テストコードを作成
s-tone-gs dcee9cb
shotクラスをより簡潔にするために修正
s-tone-gs 5d98392
ボウリングの仕様を正確に表現するために修正&クラスの責務の見直し
s-tone-gs 4fed4da
書式の修正
s-tone-gs 74bec73
必要以上に変数のスコープが広かったため修正
s-tone-gs 9285ada
一投目と二投目のスコアを合算する処理が複数個所で重複していたので共通化
s-tone-gs f659eef
記述の重複があったため修正
s-tone-gs 59b1350
共用の数値を定数に修正
s-tone-gs ef49cc1
冗長な記述を修正
s-tone-gs 8603fb8
必要のない条件分岐であったため修正
s-tone-gs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative 'game' | ||
| require_relative 'frame' | ||
| require_relative 'shot' | ||
|
|
||
| game = Game.new(ARGV[0]) | ||
| puts game.total_score |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative 'shot' | ||
|
|
||
| class Frame | ||
| attr_reader :first_shot, :second_shot, :third_shot | ||
|
|
||
| def initialize(first_score, second_score, third_score = nil) | ||
| @first_shot = Shot.new(first_score) | ||
| @second_shot = Shot.new(second_score) | ||
| @third_shot = third_score.nil? ? nil : Shot.new(third_score) | ||
| end | ||
|
|
||
| def total_score(next_frame, after_the_next_frame) | ||
| return [@first_shot, @second_shot, @third_shot].map(&:score).sum unless @third_shot.nil? | ||
|
|
||
| total_score = total_score_first_and_second | ||
| total_score += strike_bounus(next_frame, after_the_next_frame) if strike? | ||
| total_score += spare_bounus(next_frame) if spare? | ||
| total_score | ||
| end | ||
|
|
||
| def total_score_first_and_second | ||
| [@first_shot, @second_shot].map(&:score).sum | ||
| end | ||
|
|
||
| def strike_bounus(next_frame, after_the_next_frame) | ||
| if next_frame.strike? | ||
| # 9フレーム目の場合 | ||
| return next_frame.total_score_first_and_second if after_the_next_frame.nil? | ||
|
|
||
| [next_frame.first_shot, after_the_next_frame.first_shot].map(&:score).sum | ||
| else | ||
| next_frame.total_score_first_and_second | ||
| end | ||
| end | ||
|
|
||
| def spare_bounus(next_frame) | ||
| next_frame.first_shot.score | ||
| end | ||
|
|
||
| def spare? | ||
| @first_shot.score + @second_shot.score == 10 && @first_shot.score != 10 | ||
| end | ||
|
|
||
| def strike? | ||
| @first_shot.score == 10 | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative 'frame' | ||
|
|
||
| class Game | ||
| ONE_TO_NICE_FRAMES_SHOTS_COUNT = 2 * 9 | ||
| def initialize(row_scores) | ||
| framed_scores = parse_scores(row_scores) | ||
| # Frameクラス内のfirst_shot, second_shotとは命名の法則が異なっており統一感は無いが、 | ||
| # ここでfirst_frame, second_frame・・・と宣言したら全体の記述が長くなり、 | ||
| # むしろ可読性が落ちると判断したので配列で宣言 | ||
| @frames = framed_scores.map do |score| | ||
| Frame.new(*score) | ||
| end | ||
| end | ||
|
|
||
| def total_score | ||
| total_score = 0 | ||
| @frames.each_with_index do |frame, index| | ||
| next_frame, after_the_next_frame = @frames[index + 1, 2] | ||
| total_score += frame.total_score(next_frame, after_the_next_frame) | ||
| end | ||
| total_score | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def parse_scores(row_scores) | ||
| scores = [] | ||
| row_scores.split(',').each do |score| | ||
| scores.length < ONE_TO_NICE_FRAMES_SHOTS_COUNT && score == 'X' ? scores.push('X', '0') : scores << score | ||
| end | ||
| tenth_frame_scores = scores[ONE_TO_NICE_FRAMES_SHOTS_COUNT...scores.count] | ||
| framed_scores = scores.take(ONE_TO_NICE_FRAMES_SHOTS_COUNT).each_slice(2).to_a | ||
| framed_scores << tenth_frame_scores | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| class Shot | ||
| attr_reader :score | ||
|
|
||
| def initialize(string_score) | ||
| @score = string_score == 'X' ? 10 : string_score.to_i | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative 'game' | ||
|
|
||
| def main | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自動テストが書かれているので安心してリファクタリングできますね 👍 |
||
| test_bowling_return_139 | ||
| test_bowling_return_164 | ||
| test_bowling_return_107 | ||
| test_bowling_return_134 | ||
| test_bowling_return_144 | ||
| test_bowling_return_300 | ||
| test_bowling_return_292 | ||
| test_bowling_return_50 | ||
| end | ||
|
|
||
| def test_bowling_return_139 | ||
| template_test_bowling('6,3,9,0,0,3,8,2,7,3,X,9,1,8,0,X,6,4,5', 139) | ||
| end | ||
|
|
||
| def test_bowling_return_164 | ||
| template_test_bowling('6,3,9,0,0,3,8,2,7,3,X,9,1,8,0,X,X,X,X', 164) | ||
| end | ||
|
|
||
| def test_bowling_return_107 | ||
| template_test_bowling('0,10,1,5,0,0,0,0,X,X,X,5,1,8,1,0,4', 107) | ||
| end | ||
|
|
||
| def test_bowling_return_134 | ||
| template_test_bowling('6,3,9,0,0,3,8,2,7,3,X,9,1,8,0,X,X,0,0', 134) | ||
| end | ||
|
|
||
| def test_bowling_return_144 | ||
| template_test_bowling('6,3,9,0,0,3,8,2,7,3,X,9,1,8,0,X,X,1,8', 144) | ||
| end | ||
|
|
||
| def test_bowling_return_300 | ||
| template_test_bowling('X,X,X,X,X,X,X,X,X,X,X,X', 300) | ||
| end | ||
|
|
||
| def test_bowling_return_292 | ||
| template_test_bowling('X,X,X,X,X,X,X,X,X,X,X,2', 292) | ||
| end | ||
|
|
||
| def test_bowling_return_50 | ||
| template_test_bowling('X,0,0,X,0,0,X,0,0,X,0,0,X,0,0', 50) | ||
| end | ||
|
|
||
| def template_test_bowling(input, expected) | ||
| game = Game.new(input) | ||
| puts "入力したスコア:#{input}" | ||
| puts "expected: #{expected}" | ||
|
|
||
| total_score = game.total_score | ||
| puts "actual: #{total_score}" | ||
|
|
||
| if total_score == expected | ||
| puts '正常' | ||
| else | ||
| puts '異常' | ||
| end | ||
| puts '' | ||
| end | ||
|
|
||
| main | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
ここを
row_scores.split(',').take(18).eachとすると、このブロックの内側のscores.length < 18の判定や、framed_scores = scores[0..17].each_slice(2).to_aの[0..17]をなくせそうですね。Uh oh!
There was an error while loading. Please reload this page.
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.
今回、
row_scores.split(',')の結果返される配列の要素数に揺れがある(ストライク=Xと表現されていることが要因)ため、takeメソッドでの処理は難しいと判断しました。現状の処理をより分かりやすく記述する方法が見つけられなかったため、この修正を保留しています。
もし何か良い方法があればご教授願いたいです🙇♂️
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.
なるほど、確かにこの時点ではxが未処理でしたね💦失礼いたしました。現状のままとしましょう。