Skip to content

Instantly share code, notes, and snippets.

@hanachin
Forked from webcrafts/gist:5948862
Last active December 19, 2015 11:39
Show Gist options
  • Save hanachin/5949091 to your computer and use it in GitHub Desktop.
Save hanachin/5949091 to your computer and use it in GitHub Desktop.
janken game. $ ruby main.rb
require './hand.rb'
class AskHandService
CHOICE_NUMBER_START = 1
def initialize
@hands = Hand.rock_paper_scissors
end
def choices
@hands.map.with_index(CHOICE_NUMBER_START) do |hand, n|
"#{n}: #{hand}"
end
end
def describe_choices
"どの手にする?\n#{choices.join('、')}"
end
def choice_number_max
@hands.size
end
def correct_choice_number?(choice_number)
choice_number.between?(CHOICE_NUMBER_START, choice_number_max)
end
def gets_choice_number
choice_number = gets.to_i
choice_number if correct_choice_number?(choice_number)
end
def wrong_choice_warning
"1から3の間で選んでね"
end
def hand(choice_number)
@hands[choice_number - CHOICE_NUMBER_START]
end
def choice_hand
choice_number = gets_choice_number
hand(choice_number) if choice_number
end
def ask_hand
loop do
puts describe_choices
choiced_hand = choice_hand
return choiced_hand if choiced_hand
puts wrong_choice_warning
end
end
end
require './player.rb'
require './hand.rb'
class Computer < Player
def prepare_hand
@hand = Hand.random
end
end
module Hand
class BasicHand
def rock?
false
end
def paper?
false
end
def scissors?
false
end
end
class Rock < BasicHand
def rock?
true
end
def to_s
'グー'
end
end
class Scissors < BasicHand
def scissors?
true
end
def to_s
'チョキ'
end
end
class Paper < BasicHand
def paper?
true
end
def to_s
'パー'
end
end
def self.random
rock_paper_scissors.sample
end
def self.rock_paper_scissors
ROCK_PAPER_SCISSORS.map(&:new)
end
ROCK_PAPER_SCISSORS = [Rock, Paper, Scissors].freeze
end
require './rules.rb'
module Janken
class Win
def initialize(winners)
@winners = winners
end
def winner_names
@winners.map(&:to_s)
end
def to_s
"#{winner_names.join('、')}の勝ち"
end
end
class Aiko
def to_s
"あいこ"
end
end
class OneToOneGame
def initialize(player, other)
@player = player
@other = other
end
def players
[@player, @other]
end
def players_hands
players.map(&:describe_hand)
end
def describe_hands
players_hands.join('、')
end
def rule
Rules::PlayerWinOtherPlayer.new(@player, @other)
end
def win(player)
Janken::Win.new([player])
end
def aiko
Janken::Aiko.new
end
def result
return win(@player) if rule.player_win?
return win(@other) if rule.other_player_win?
aiko
end
def describe_game
"勝敗結果は・・・「#{result}」です。"
end
def prepare_players_hand
players.each(&:prepare_hand)
end
end
end
require './janken.rb'
require './player.rb'
require './computer.rb'
require './round_game.rb'
human = Player.new('人間')
computer = Computer.new('コンピュータ')
janken_game = Janken::OneToOneGame.new(human, computer)
three_round_janken = RoundGame.new(3, janken_game)
three_round_janken.each_round do |game|
game.prepare_players_hand
puts game.describe_hands
puts game.describe_game
end
three_round_janken.start
puts three_round_janken.describe_result
require './ask_hand_service.rb'
class Player
attr_accessor :hand
def initialize(name)
@name = name
end
def ask_hand_service
AskHandService.new
end
def prepare_hand
@hand = ask_hand_service.ask_hand
# @hand = Hand.random
end
def describe_hand
"#{@name}の手は「#{@hand}」"
end
def to_s
@name
end
end
class RoundGame
ROUND_NUMBER_START = 1
def initialize(round_count, game)
@round_count = round_count
@game = game
end
def each_round(&round)
@round = round
end
def rounds
@round_count.times
end
def start
@results = rounds.map do
@round.call(@game) if @round
@game.result
end
end
def result_with_index
@results.map.with_index(ROUND_NUMBER_START) do |result, n|
"#{n}回戦の結果は・・・#{result}"
end.join("\n")
end
def decoration_line
"******************************************"
end
def describe_result
<<RESULT
#{decoration_line}
対戦結果は・・・
#{result_with_index}
RESULT
end
end
module Rules
class RockWinScissors
def initialize(hand, other)
@hand = hand
@other = other
end
def win?
@hand.rock? and @other.scissors?
end
end
class ScissorsWinPaper
def initialize(hand, other)
@hand = hand
@other = other
end
def win?
@hand.scissors? and @other.paper?
end
end
class PaperWinRock
def initialize(hand, other)
@hand = hand
@other = other
end
def win?
@hand.paper? and @other.rock?
end
end
def self.win_hand_rules
[
Rules::RockWinScissors,
Rules::ScissorsWinPaper,
Rules::PaperWinRock
]
end
class PlayerWinOtherPlayer
def initialize(player, other_player)
@player = player
@other_player = other_player
end
def player_win_rules
win_hand_rules(@player, @other_player)
end
def player_win?
player_win_rules.any?(&:win?)
end
def other_player_win_rules
win_hand_rules(@other_player, @player)
end
def other_player_win?
other_player_win_rules.any?(&:win?)
end
private
def win_hand_rules(player, other_player)
Rules::win_hand_rules.map do |rule|
rule.new(player.hand, other_player.hand)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment