Created
January 31, 2017 15:59
-
-
Save libkazz/704970b2665ceba888976cd0ba0b0770 to your computer and use it in GitHub Desktop.
石取りゲーム
This file contains 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
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