マルバツゲーム
Posted feedbacks - Erlang
以下実行結果です。
1> c(tic_tac_toe).
{ok,tic_tac_toe}
2> tic_tac_toe:start().
first:5835,second:2957,draw:1208
ok
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 | -module(tic_tac_toe).
-import(io).
-import(lists).
-import(random).
-export([start/0]).
create_board() -> lists:map(fun(_) -> 0 end,lists:seq(1,9,1)).
move(B,1,{C,_}) -> move(B,1,C);
move(B,2,{_,C}) -> move(B,2,C);
move(B,P,C) ->
PS = C(B,P),
lists:sublist(B,PS - 1) ++ [P|lists:sublist(B,PS + 1,length(B) - PS)].
check_pattern() ->
lists:map(fun(X) -> lists:seq(X,X+6,3) end, lists:seq(1,3,1)) ++
lists:map(fun(X) -> lists:seq(X,X+2,1) end, lists:seq(1,7,3)) ++
[lists:seq(1,9,4),lists:seq(3,7,2)].
check(B,P) ->
lists:any(
fun(PT) ->
lists:all(
fun(ST) -> ST == P end,
lists:map(fun(X) -> lists:nth(X,B) end, PT)
)
end,
check_pattern()
).
process(B,P,C) ->
BN = move(B,P,C),
R = check(BN,P),
D = lists:all(fun(ST) -> ST /= 0 end, BN),
if
R -> P;
D -> 0;
true -> process(BN, P rem 2 + 1, C)
end.
process(C) -> process(create_board(),1,C).
random_choice(B,_) ->
S = lists:map(fun({PS,_}) -> PS end, lists:filter(fun({_,X}) -> X == 0 end, lists:zip(lists:seq(1,length(B),1),B))),
lists:nth(random:uniform(length(S)),S).
start() ->
R = lists:map(fun(_) -> process({fun random_choice/2,fun random_choice/2}) end,lists:seq(1,10000,1)),
io:format("first:~w,second:~w,draw:~w~n",lists:map(fun(P) -> length(lists:filter(fun(X) -> X == P end, R)) end,[1,2,0])).
|

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