Skip to content

Instantly share code, notes, and snippets.

@libkazz
Created January 31, 2017 15:59
Show Gist options
  • Save libkazz/704970b2665ceba888976cd0ba0b0770 to your computer and use it in GitHub Desktop.
Save libkazz/704970b2665ceba888976cd0ba0b0770 to your computer and use it in GitHub Desktop.
石取りゲーム
class StoneTori
class Stones
def initialize(count)
@count = count
end
def empty?
@count.zero?
end
def count
@count
end
def get(n)
@count -= n
end
end
class Players
def initialize(*player_types)
@players = player_types.map { |type| create_player(type) }
@current_player_index = 0
end
def shuffle
@players.shuffle!
end
def current_player
@players[@current_player_index]
end
def next!
@current_player_index = (@current_player_index + 1) % @players.size
end
private
def create_player(type)
case type
when :computer
Player::Computer.new
when :human
Player::Human.new
end
end
end
class Player
MAX_COUNT = 5
@@index = 0
def initialize
@player_index = @@index
@@index += 1
end
def name
"<Player##{@player_index}>"
end
alias to_s name
class Computer < Player
def deside(current_stone_count)
return 1 if current_stone_count == 1
# 10 回に 1 回はランダムな選択, 9 回は賢い選択をする
if rand(10) == 0
randome_deside(current_stone_count)
else
intelligent_deside(current_stone_count)
end
end
def randome_deside(current_stone_count)
(1..current_stone_count - 1).to_a.sample
end
def intelligent_deside(current_stone_count)
count = current_stone_count % (MAX_COUNT + 1) - 1
return count if count >= 1
randome_deside(current_stone_count)
end
end
class Human < Player
def deside(current_stone_count)
return 1 if current_stone_count == 1
loop do
max_count = current_stone_count > MAX_COUNT ? MAX_COUNT : current_stone_count
print "Hit get count [1..#{max_count}] > "
count = $stdin.gets.to_i
next puts("Over max count: #{max_count}") if count > max_count
next puts("Zero is invalid.") if count == 0
return count
end
end
end
end
def initialize(n = 50)
@stones = Stones.new(n)
@players = Players.new(:computer, :human)
end
def shuffle
@players.shuffle
end
def start
loop do
player = @players.current_player
get_count = player.deside(@stones.count)
next if @stones.count < get_count
@stones.get(get_count)
puts "#{player.name} get #{get_count}."
if @stones.empty?
puts "#{player.name} loose .."
return
else
@players.next!
puts "next! Rest #{@stones.count}."
end
end
end
end
if __FILE__ == $0
game = StoneTori.new(20)
game.shuffle
game.start
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment