Created
August 8, 2024 20:55
-
-
Save Kallin/518b39d57c6bb4021bb199680b781c83 to your computer and use it in GitHub Desktop.
bowling.rb
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
| FRAME_COUNT = 5 | |
| class Frame | |
| PIN_COUNT = 10 | |
| def initialize(final_frame = false) | |
| @rolls = RollList.new | |
| @final_frame = final_frame | |
| reset_pins | |
| end | |
| def reset_pins | |
| @pins_remaining = PIN_COUNT | |
| end | |
| def add_roll(roll) | |
| @rolls.add_roll(roll) | |
| @pins_remaining -= roll.pins_hit | |
| if @final_frame && @pins_remaining == 0 && @rolls.count < 3 | |
| reset_pins | |
| end | |
| end | |
| # Both these methods assume a non-final frame. | |
| def strike? | |
| @pins_remaining == 0 && @rolls.count == 1 | |
| end | |
| def spare? | |
| @pins_remaining == 0 && @rolls.count == 2 | |
| end | |
| def pins_remaining | |
| @pins_remaining | |
| end | |
| def options | |
| # 10,10,10 | |
| # 10,10,4 | |
| # 10,5,5 | |
| # 4,2 | |
| end | |
| def complete? | |
| if @final_frame | |
| (@pins_remaining > 0 && @rolls.count == 2) || @rolls.count == 3 | |
| else # This goes against object calisthenics | |
| @pins_remaining == 0 || @rolls.count == 2 | |
| end | |
| end | |
| end | |
| class FrameList | |
| def initialize | |
| @frames = [] | |
| end | |
| def add_frame | |
| @frames << Frame.new(count == FRAME_COUNT - 1) | |
| end | |
| def last | |
| @frames.last | |
| end | |
| def count | |
| @frames.count | |
| end | |
| def frames | |
| # this isn't allowed I guess, but doing for now to make progress on scoring | |
| @frames | |
| end | |
| end | |
| class BowlingGame | |
| def initialize() | |
| @scoring_strategy = DefaultScoringStrategy.new | |
| @frame_list = FrameList.new | |
| @frame_list.add_frame | |
| @current_score = 0 | |
| @last_two_rolls = [nil, nil] | |
| end | |
| # list of frames | |
| def roll(roll) | |
| current_frame.add_roll(roll) | |
| puts "we're in frame #{@frame_list.count}" | |
| puts "we hit #{roll.pins_hit} pins!" | |
| @last_two_rolls.unshift | |
| if current_frame.strike? | |
| puts "Strike" | |
| @last_two_rolls << 'X' | |
| elsif current_frame.spare? | |
| puts "Spare!" | |
| @last_two_rolls << '/' | |
| else | |
| @last_two_rolls << roll.pins_hit | |
| end | |
| if @last_two_rolls.include? 'X' | |
| @current_score = @current_score + (roll.pins_hit * 2) | |
| elsif @last_two_rolls.last == '/' | |
| @current_score = @current_score + (roll.pins_hit * 2) | |
| else | |
| @current_score = @current_score + roll.pins_hit | |
| end | |
| puts "current score is #{@current_score}" | |
| @frame_list.add_frame if current_frame.complete? && @frame_list.count < FRAME_COUNT | |
| # puts "we're in frame #{count}" | |
| # puts "we rolled a 5, X, or /" | |
| # puts "current score is 123" | |
| end | |
| def current_frame | |
| @frame_list.last | |
| end | |
| def is_finished | |
| @frame_list.count == FRAME_COUNT && current_frame.complete? | |
| end | |
| def pins_remaining | |
| current_frame.pins_remaining | |
| end | |
| def scores | |
| # return an array with what happened in each frame, as well as total score at end of that frame | |
| scores = [] | |
| end | |
| end | |
| class DefaultScoringStrategy | |
| end | |
| class GameRenderer | |
| def initialize(game) | |
| @game = game | |
| end | |
| def draw | |
| # numbers = (1..10).to_a | |
| # puts numbers.join("\t") | |
| # array_of_pipes = Array.new(10, '|') | |
| # puts array_of_pipes.join("\t") | |
| end | |
| end | |
| class RollList | |
| def initialize | |
| @rolls = [] | |
| end | |
| def sum | |
| @rolls.sum { |roll| roll.pins_hit } | |
| end | |
| def count | |
| @rolls.count | |
| end | |
| def add_roll(roll) | |
| @rolls << roll | |
| end | |
| end | |
| class Roll | |
| def initialize(pins_hit) | |
| @pins_hit = pins_hit | |
| end | |
| def pins_hit | |
| @pins_hit | |
| end | |
| end | |
| class RandomPlayer | |
| def initialize(game) | |
| @game = game | |
| end | |
| def play_until_complete | |
| until @game.is_finished | |
| roll | |
| end | |
| end | |
| def roll | |
| puts "Pins remaining: #{@game.pins_remaining}" | |
| pins_hit = (0..@game.pins_remaining).to_a.sample | |
| roll = Roll.new(pins_hit) | |
| @game.roll(roll) | |
| end | |
| end | |
| game = BowlingGame.new | |
| player = RandomPlayer.new(game) | |
| player.play_until_complete | |
| renderer = GameRenderer.new(game) | |
| renderer.draw | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment