코딩도장

코딩도장

변경이력

돌아가기
2 8개 문자 추가 55개 문자 삭제

2025年04月08日 04:49

rk

** Ruby ** 값을 보관하는 `Data`, 주사위를 굴리고 규칙에 따라 점수를 계산하는 `Role`, 입출력을 처리하는 `Presenter`, 이들을 사용해 게임을 진행(랜덤 주사위 or 데이터 입력)하는 `Context`를 작성. ## Data ```{.ruby} # Data class DiceGameModel attr_accessor :inputs, :scores, :turn_data, :target_score def initialize clear end def total_score @scores.sum end def clear @inputs, @scores = [], [] @turn_data = nil @target_score = target_score end def over @scores.empty? || total_score >= @target_score end end ```## Role ```{.ruby} module DiceRollable def roll @inputs << (@turn_data&.shift || Array.new(6) { rand(1..6) })# data or random @scores << score(@inputs.last) @scores.clear if @scores.last.zero? # bomb end private def score(dice) frequencies = dice.tally # hash { num => occur, ... } score_sequence(frequencies).nonzero? || frequencies.sum { score_spots(*_1) } end def score_spots(num, occur) base, bonus = { 1 => 100, 5 => 50 }, { 1 => 1000, 5 => 500 } # 15 rule base.default, bonus.default = 0, 100 # 2346 rule occur < 3 ? base[num] * occur : num * bonus[num] * (2**(occur - 3)) end def score_sequence(frequencies, seq_len = frequencies.size) rest_score = ->(hash) { score_spots(hash.key(2), 1) } case when seq_len == 5 && !frequencies.key?(6) then 750 + rest_score[frequencies] when seq_len == 5 && !frequencies.key?(1) then 1250 + rest_score[frequencies] when seq_len == 6 then 2000 else 0 end end end ```## Presenter ```{.ruby} class Presenter def input_target_score print "Input target score: " gets.to_i end def continue_turn(target_score, total_score) print "[target: #{target_score}, now: #{total_score}]. continue the turn? (y/n): " gets.strip == 'y' end def display_result(inputs, scores, total_score) formatted_scores = scores.size > 1 ? "#{scores.join(' + ')} = " : "" puts "#{inputs.map(&:to_s).join(', ')} -> " + formatted_scores + "#{total_score} pts" end end ```## Context ```{.ruby} class DiceGamePlayContext def initialize(game, presenter) @game = game @presenter = presenter @game.extend DiceRollable end def execute(turn_data = nil, target_score = nil) setup(turn_data, target_score) begin @game.roll end while continue_playing display_result end private def setup(turn_data, target_score) @game.turn_data = turn_data @game.target_score = target_score || @presenter.input_target_score # data or stdin end def continue_playing return false if @game.over @game.turn_data ? @game.turn_data.any? : @presenter.continue_turn(@game.target_score, @game.total_score) end def display_result @presenter.display_result(@game.inputs, @game.scores, @game.total_score) @game.clear end end ``` ## 실행 테스트 데이터로 주사위 굴리기 ```{.ruby} target_score = 2000 play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute([[3, 6, 6, 3, 4, 2]], target_score) # spots : base score(2346) play_context.execute([[2, 6, 1, 1, 6, 3]], target_score) # spots : base score(1) play_context.execute([[1, 5, 2, 3, 6, 4]], target_score) # sequence : 123456 play_context.execute([[3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4]], target_score) # spots : bomb play_context.execute([[5, 2, 1, 2, 5, 2]], target_score) # spots : base score(15) + bonus score(2) # spots : target score exceeded. play_context.execute([[1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4]], target_score) [3, 6, 6, 3, 4, 2] -> 0 pts [2, 6, 1, 1, 6, 3] -> 200 pts [1, 5, 2, 3, 6, 4] -> 2000 pts [3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4] -> 0 pts [5, 2, 1, 2, 5, 2] -> 400 pts [1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4] -> 800 +たす 450 +たす 900 = 2150 pts ``` 랜덤하게 주사위 굴리기 ```{.ruby} play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute Input target score: 1000 [target: 1000, now: 200]. continue the turn? (y/n): y [target: 1000, now: 400]. continue the turn? (y/n): y [1, 3, 4, 3, 6, 1], [5, 4, 5, 1, 4, 3], [3, 3, 3, 4, 1, 3] -> 200 +たす 200 +たす 700 = 1100 pts ```
** Ruby ** 값을 보관하는 `Data`, 주사위를 굴리고 규칙에 따라 점수를 계산하는 `Role`, 입출력을 처리하는 `Presenter`, 이들을 사용해 게임을 진행(랜덤 주사위 or 데이터 입력)하는 `Context`를 작성. ## Data ```{.ruby} # Data class DiceGameModel attr_accessor :inputs, :scores, :turn_data, :target_score def initialize clear end def total_score @scores.sum end def clear @inputs, @scores = [], [] @turn_data = nil @target_score = target_score end def over @scores.empty? || total_score >= @target_score end end ```## Role ```{.ruby} module DiceRollable def roll @inputs << (@turn_data&.shift || Array.new(6) { rand(1..6) })# data or random @scores << score(@inputs.last) @scores.clear if @scores.last.zero? # bomb end private def score(dice) frequencies = dice.tally # hash { num => occur, ... } score_sequence(frequencies).nonzero? || frequencies.sum { score_spots(*_1) } end def score_spots(num, occur) base, bonus = { 1 => 100, 5 => 50 }, { 1 => 1000, 5 => 500 } # 15 rule base.default, bonus.default = 0, 100 # 2346 rule occur < 3 ? base[num] * occur : num * bonus[num] * (2**(occur - 3)) end def score_sequence(frequencies, seq_len = frequencies.size) rest_score = ->(hash) { score_spots(hash.key(2), 1) } case when seq_len == 5 && !frequencies.key?(6) then 750 + rest_score[frequencies] when seq_len == 5 && !frequencies.key?(1) then 1250 + rest_score[frequencies] when seq_len == 6 then 2000 else 0 end end end ```## Presenter ```{.ruby} class Presenter def input_target_score print "Input target score: " gets.to_i end def continue_turn(target_score, total_score) print "[target: #{target_score}, now: #{total_score}]. continue the turn? (y/n): " gets.strip == 'y' end def display_result(inputs, scores, total_score) formatted_scores = scores.size > 1 ? "#{scores.join(' + ')} = " : "" puts "#{inputs.map(&:to_s).join(', ')} -> " + formatted_scores + "#{total_score} pts" end end ```## Context ```{.ruby} class DiceGamePlayContext def initialize(game, presenter) @game = game @presenter = presenter @game.extend DiceRollable end def execute(turn_data = nil, target_score = nil) setup(turn_data, target_score) begin @game.roll end while continue_playing display_result end private def setup(turn_data, target_score) @game.turn_data = turn_data @game.target_score = target_score || @presenter.input_target_score # data or stdin end def continue_playing return false if @game.over @game.turn_data ? @game.turn_data.any? : @presenter.continue_turn(@game.target_score, @game.total_score) end def display_result @presenter.display_result(@game.inputs, @game.scores, @game.total_score) @game.clear end end ``` ## 실행 테스트 데이터로 주사위 굴리기 ```{.ruby} target_score = 2000 play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute([[3, 6, 6, 3, 4, 2]], target_score) # spots : base score(2346) play_context.execute([[2, 6, 1, 1, 6, 3]], target_score) # spots : base score(1) play_context.execute([[1, 5, 2, 3, 6, 4]], target_score) # sequence : 123456 play_context.execute([[3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4]], target_score) # spots : bomb play_context.execute([[5, 2, 1, 2, 5, 2]], target_score) # spots : base score(15) + bonus score(2) # spots : target score exceeded. play_context.execute([[1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4]], target_score) [3, 6, 6, 3, 4, 2] -> 0 pts [2, 6, 1, 1, 6, 3] -> 200 pts [1, 5, 2, 3, 6, 4] -> 2000 pts [3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4] -> 0 pts [5, 2, 1, 2, 5, 2] -> 400 pts [1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4] -> 800 +たす 450 +たす 900 = 2150 pts ``` 랜덤하게 주사위 굴리기 ```{.ruby} play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute Input target score: 1000 [target: 1000, now: 200]. continue the turn? (y/n): y [target: 1000, now: 400]. continue the turn? (y/n): y [1, 3, 4, 3, 6, 1], [5, 4, 5, 1, 4, 3], [3, 3, 3, 4, 1, 3] -> 200 +たす 200 +たす 700 = 1100 pts ```
** Ruby ** 값을 보관하는 `Data`, 주사위를 굴리고 규칙에 따라 점수를 계산하는 `Role`, 입출력을 처리하는 `Presenter`, 이들을 사용해 게임을 진행(랜덤 주사위 or 데이터 입력)하는 `Context`를 작성. ## Data ```{.ruby} # Data class DiceGameModel attr_accessor :inputs, :scores, :turn_data, :target_score def initialize clear end def total_score @scores.sum end def clear @inputs, @scores = [], [] @turn_data = nil @target_score = target_score end def over @scores.empty? || total_score >= @target_score end end ```## Role ```{.ruby} module DiceRollable def roll @inputs << (@turn_data&.shift || Array.new(6) { rand(1..6) })# data or random @scores << score(@inputs.last) @scores.clear if @scores.last.zero? # bomb end private def score(dice) frequencies = dice.tally # hash { num => occur, ... } score_sequence(frequencies).nonzero? || frequencies.sum { score_spots(*_1) } end def score_spots(num, occur) base, bonus = { 1 => 100, 5 => 50 }, { 1 => 1000, 5 => 500 } # 15 rule base.default, bonus.default = 0, 100 # 2346 rule occur < 3 ? base[num] * occur : num * bonus[num] * (2**(occur - 3)) end def score_sequence(frequencies, seq_len = frequencies.size) rest_score = ->(hash) { score_spots(hash.key(2), 1) } case when seq_len == 5 && !frequencies.key?(6) then 750 + rest_score[frequencies] when seq_len == 5 && !frequencies.key?(1) then 1250 + rest_score[frequencies] when seq_len == 6 then 2000 else 0 end end end ```## Presenter ```{.ruby} class Presenter def input_target_score print "Input target score: " gets.to_i end def continue_turn(target_score, total_score) print "[target: #{target_score}, now: #{total_score}]. continue the turn? (y/n): " gets.strip == 'y' end def display_result(inputs, scores, total_score) formatted_scores = scores.size > 1 ? "#{scores.join(' + ')} = " : "" puts "#{inputs.map(&:to_s).join(', ')} -> " + formatted_scores + "#{total_score} pts" end end ```## Context ```{.ruby} class DiceGamePlayContext def initialize(game, presenter) @game = game @presenter = presenter @game.extend DiceRollable end def execute(turn_data = nil, target_score = nil) setup(turn_data, target_score) begin @game.roll end while continue_playing display_result end private def setup(turn_data, target_score) @game.turn_data = turn_data @game.target_score = target_score || @presenter.input_target_score # data or stdin end def continue_playing return false if @game.over @game.turn_data ? @game.turn_data.any? : @presenter.continue_turn(@game.target_score, @game.total_score) end def display_result @presenter.display_result(@game.inputs, @game.scores, @game.total_score) @game.clear end end ``` ## 실행 테스트 데이터로 주사위 굴리기 ```{.ruby} target_score = 2000 play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute([[3, 6, 6, 3, 4, 2]], target_score) # spots : base score(2346) play_context.execute([[2, 6, 1, 1, 6, 3]], target_score) # spots : base score(1) play_context.execute([[1, 5, 2, 3, 6, 4]], target_score) # sequence : 123456 play_context.execute([[3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4]], target_score) # spots : bomb play_context.execute([[5, 2, 1, 2, 5, 2]], target_score) # spots : base score(15) + bonus score(2) # spots : target score exceeded. play_context.execute([[1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4]], target_score) [3, 6, 6, 3, 4, 2] -> 0 pts [2, 6, 1, 1, 6, 3] -> 200 pts [1, 5, 2, 3, 6, 4] -> 2000 pts [3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4] -> 0 pts [5, 2, 1, 2, 5, 2] -> 400 pts [1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4] -> 800 +たす 450 +たす 900 = 2150 pts ``` 랜덤하게 주사위 굴리기 ```{.ruby} play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute Input target score: 1000 [target: 1000, now: 200]. continue the turn? (y/n): y [target: 1000, now: 400]. continue the turn? (y/n): y [1, 3, 4, 3, 6, 1], [5, 4, 5, 1, 4, 3], [3, 3, 3, 4, 1, 3] -> 200 +たす 200 +たす 700 = 1100 pts ```
1 Original

2025年04月07日 16:30

rk

** Ruby ** 값을 보관하는 `Data`, 주사위를 굴리고 규칙에 따라 점수를 계산하는 `Role`, 입출력을 처리하는 `Presenter`, 이들을 사용해 게임을 진행(랜덤 주사위 or 데이터 입력)하는 `Context`를 작성. ## Data ```{.ruby} class DiceGameModel attr_accessor :inputs, :scores, :turn_data, :target_score def initialize clear end def total_score @scores.sum end def clear @inputs, @scores = [], [] @turn_data = nil @target_score = target_score end def over @scores.empty? || total_score >= @target_score end end ``` ## Role ```{.ruby} module DiceRollable def roll @inputs << (@turn_data&.shift || Array.new(6) { rand(1..6) })# data or random @scores << score(@inputs.last) @scores.clear if @scores.last.zero? # bomb end private def score(dice) frequencies = dice.tally # hash { num => occur, ... } score_sequence(frequencies).nonzero? || frequencies.sum { score_spots(*_1) } end def score_spots(num, occur) base, bonus = { 1 => 100, 5 => 50 }, { 1 => 1000, 5 => 500 } # 15 rule base.default, bonus.default = 0, 100 # 2346 rule occur < 3 ? base[num] * occur : num * bonus[num] * (2**(occur - 3)) end def score_sequence(frequencies, seq_len = frequencies.size) rest_score = ->(hash) { score_spots(hash.key(2), 1) } case when seq_len == 5 && !frequencies.key?(6) then 750 + rest_score[frequencies] when seq_len == 5 && !frequencies.key?(1) then 1250 + rest_score[frequencies] when seq_len == 6 then 2000 else 0 end end end ``` ## Presenter ```{.ruby} class Presenter def input_target_score print "Input target score: " gets.to_i end def continue_turn(target_score, total_score) print "[target: #{target_score}, now: #{total_score}]. continue the turn? (y/n): " gets.strip == 'y' end def display_result(inputs, scores, total_score) formatted_scores = scores.size > 1 ? "#{scores.join(' + ')} = " : "" puts "#{inputs.map(&:to_s).join(', ')} -> " + formatted_scores + "#{total_score} pts" end end ``` ## Context ```{.ruby} class DiceGamePlayContext def initialize(game, presenter) @game = game @presenter = presenter @game.extend DiceRollable end def execute(turn_data = nil, target_score = nil) setup(turn_data, target_score) begin @game.roll end while continue_playing display_result end private def setup(turn_data, target_score) @game.turn_data = turn_data @game.target_score = target_score || @presenter.input_target_score # data or stdin end def continue_playing return false if @game.over @game.turn_data ? @game.turn_data.any? : @presenter.continue_turn(@game.target_score, @game.total_score) end def display_result @presenter.display_result(@game.inputs, @game.scores, @game.total_score) @game.clear end end ``` ## 실행 테스트 데이터로 주사위 굴리기 ```{.ruby} target_score = 2000 play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute([[3, 6, 6, 3, 4, 2]], target_score) # spots : base score(2346) play_context.execute([[2, 6, 1, 1, 6, 3]], target_score) # spots : base score(1) play_context.execute([[1, 5, 2, 3, 6, 4]], target_score) # sequence : 123456 play_context.execute([[3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4]], target_score) # spots : bomb play_context.execute([[5, 2, 1, 2, 5, 2]], target_score) # spots : base score(15) + bonus score(2) # spots : target score exceeded. play_context.execute([[1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4]], target_score) [3, 6, 6, 3, 4, 2] -> 0 pts [2, 6, 1, 1, 6, 3] -> 200 pts [1, 5, 2, 3, 6, 4] -> 2000 pts [3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4] -> 0 pts [5, 2, 1, 2, 5, 2] -> 400 pts [1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4] -> 800 +たす 450 +たす 900 = 2150 pts ``` 랜덤하게 주사위 굴리기 ```{.ruby} play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute Input target score: 1000 [target: 1000, now: 200]. continue the turn? (y/n): y [target: 1000, now: 400]. continue the turn? (y/n): y [1, 3, 4, 3, 6, 1], [5, 4, 5, 1, 4, 3], [3, 3, 3, 4, 1, 3] -> 200 +たす 200 +たす 700 = 1100 pts ```
** Ruby ** 값을 보관하는 `Data`, 주사위를 굴리고 규칙에 따라 점수를 계산하는 `Role`, 입출력을 처리하는 `Presenter`, 이들을 사용해 게임을 진행(랜덤 주사위 or 데이터 입력)하는 `Context`를 작성. ## Data ```{.ruby} class DiceGameModel attr_accessor :inputs, :scores, :turn_data, :target_score def initialize clear end def total_score @scores.sum end def clear @inputs, @scores = [], [] @turn_data = nil @target_score = target_score end def over @scores.empty? || total_score >= @target_score end end ``` ## Role ```{.ruby} module DiceRollable def roll @inputs << (@turn_data&.shift || Array.new(6) { rand(1..6) })# data or random @scores << score(@inputs.last) @scores.clear if @scores.last.zero? # bomb end private def score(dice) frequencies = dice.tally # hash { num => occur, ... } score_sequence(frequencies).nonzero? || frequencies.sum { score_spots(*_1) } end def score_spots(num, occur) base, bonus = { 1 => 100, 5 => 50 }, { 1 => 1000, 5 => 500 } # 15 rule base.default, bonus.default = 0, 100 # 2346 rule occur < 3 ? base[num] * occur : num * bonus[num] * (2**(occur - 3)) end def score_sequence(frequencies, seq_len = frequencies.size) rest_score = ->(hash) { score_spots(hash.key(2), 1) } case when seq_len == 5 && !frequencies.key?(6) then 750 + rest_score[frequencies] when seq_len == 5 && !frequencies.key?(1) then 1250 + rest_score[frequencies] when seq_len == 6 then 2000 else 0 end end end ``` ## Presenter ```{.ruby} class Presenter def input_target_score print "Input target score: " gets.to_i end def continue_turn(target_score, total_score) print "[target: #{target_score}, now: #{total_score}]. continue the turn? (y/n): " gets.strip == 'y' end def display_result(inputs, scores, total_score) formatted_scores = scores.size > 1 ? "#{scores.join(' + ')} = " : "" puts "#{inputs.map(&:to_s).join(', ')} -> " + formatted_scores + "#{total_score} pts" end end ``` ## Context ```{.ruby} class DiceGamePlayContext def initialize(game, presenter) @game = game @presenter = presenter @game.extend DiceRollable end def execute(turn_data = nil, target_score = nil) setup(turn_data, target_score) begin @game.roll end while continue_playing display_result end private def setup(turn_data, target_score) @game.turn_data = turn_data @game.target_score = target_score || @presenter.input_target_score # data or stdin end def continue_playing return false if @game.over @game.turn_data ? @game.turn_data.any? : @presenter.continue_turn(@game.target_score, @game.total_score) end def display_result @presenter.display_result(@game.inputs, @game.scores, @game.total_score) @game.clear end end ``` ## 실행 테스트 데이터로 주사위 굴리기 ```{.ruby} target_score = 2000 play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute([[3, 6, 6, 3, 4, 2]], target_score) # spots : base score(2346) play_context.execute([[2, 6, 1, 1, 6, 3]], target_score) # spots : base score(1) play_context.execute([[1, 5, 2, 3, 6, 4]], target_score) # sequence : 123456 play_context.execute([[3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4]], target_score) # spots : bomb play_context.execute([[5, 2, 1, 2, 5, 2]], target_score) # spots : base score(15) + bonus score(2) # spots : target score exceeded. play_context.execute([[1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4]], target_score) [3, 6, 6, 3, 4, 2] -> 0 pts [2, 6, 1, 1, 6, 3] -> 200 pts [1, 5, 2, 3, 6, 4] -> 2000 pts [3, 5, 1, 5, 3, 3], [2, 4, 6, 3, 3, 4] -> 0 pts [5, 2, 1, 2, 5, 2] -> 400 pts [1, 2, 3, 4, 5, 5], [5, 2, 1, 2, 1, 2], [4, 6, 4, 1, 4, 4] -> 800 +たす 450 +たす 900 = 2150 pts ``` 랜덤하게 주사위 굴리기 ```{.ruby} play_context = DiceGamePlayContext.new(DiceGameModel.new, Presenter.new) play_context.execute Input target score: 1000 [target: 1000, now: 200]. continue the turn? (y/n): y [target: 1000, now: 400]. continue the turn? (y/n): y [1, 3, 4, 3, 6, 1], [5, 4, 5, 1, 4, 3], [3, 3, 3, 4, 1, 3] -> 200 +たす 200 +たす 700 = 1100 pts ```
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.

코딩도장 © 2014 · 문의 [email protected]
피드백 · 개인정보취급방침 · RSS

AltStyle によって変換されたページ (->オリジナル) /