マルバツゲーム
Posted feedbacks - Ruby
Rubyらしくなくビット演算を使ってみました。○,×それぞれ9ビットのビット配列(実際にはただの整数)を用意し、ゲーム盤を表現しています。
0x1c0, 0x124, 0x111, 0x92, 0x54, 0x49, 0x38, 0x7
は3つ並んだかどうか判定するためのマスクです。例えば、0x111は2進数で100010001となりますが、これを3ビットずつ並べると
100
010
001
となり、斜めの判定パターンになってることが分かります。これと○・×のビット配列の論理和を取ることで、並んだかの判定を行うことが出来ます。
実行例です。
ruby marubatu.rb
{"PLAYER 0"=>5870, "PLAYER 1"=>2828, "DRAW"=>1302}
PLAYER 0が先手、 PLAYER 1が後手です。
0x1c0, 0x124, 0x111, 0x92, 0x54, 0x49, 0x38, 0x7
は3つ並んだかどうか判定するためのマスクです。例えば、0x111は2進数で100010001となりますが、これを3ビットずつ並べると
100
010
001
となり、斜めの判定パターンになってることが分かります。これと○・×のビット配列の論理和を取ることで、並んだかの判定を行うことが出来ます。
実行例です。
ruby marubatu.rb
{"PLAYER 0"=>5870, "PLAYER 1"=>2828, "DRAW"=>1302}
PLAYER 0が先手、 PLAYER 1が後手です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | class Judge
def initialize(player1, player2)
@players = []
@players[0] = player1
@players[1] = player2
end
def is_end?(ban)
[0x1c0, 0x124, 0x111, 0x92, 0x54, 0x49, 0x38, 0x7].each do |mask|
if ban & mask == mask then
return true
end
end
return false
end
KOMA = {0 => " ", 1 => "○", 2 => "×"}
def display(play1, play2)
print "---\n"
(0..2).each do |i|
(0..2).each do |j|
print KOMA[(play1 & 1) + ((play2 & 1) << 1)]
play1 >>= 1
play2 >>= 1
end
print "\n"
end
print "---\n"
print "\n"
end
def play(vervose = false)
bans = [0, 0]
curplayer = 0
(1..9).each do |no|
other = 1 - curplayer
bans[curplayer] = @players[curplayer].think(bans[curplayer], bans[other])
if vervose then
display(bans[0], bans[1])
end
if is_end?(bans[curplayer]) then
return "PLAYER #{curplayer}"
end
curplayer = other
end
"DRAW"
end
end
class Player
def think(myban, yourban)
r = 0
begin
r = rand(9)
end while ((myban | yourban) & (1 << r) != 0)
myban | (1 << r)
end
end
result = Hash.new(0)
jd = Judge.new(Player.new, Player.new)
(1..10000).each do |n|
result[jd.play] += 1
end
p result
|

syat
#6190()
Rating4/4=1.00
マルバツゲームは3×3の格子に交互に○と×を書き込み、先に縦・横・斜めに記号をそろえたほうが勝ちというおなじみのゲームです。
「毎ターン乱数を使って手を決めるランダムプレイヤー同士を対戦させる」というのが今回のお題です。 1万回対戦させ、勝ち・負け・引き分けの数を表示してください。 そして先手が有利であることを確かめてください。
良い手を思考するプレイヤーについては別のお題にしようと思っています。 プレイヤーを簡単に差し換えることができる設計を目指してください。
[ reply ]