challenge マルバツゲーム

マルバツゲームは3×3の格子に交互に○と×を書き込み、先に縦・横・斜めに記号をそろえたほうが勝ちというおなじみのゲームです。

「毎ターン乱数を使って手を決めるランダムプレイヤー同士を対戦させる」というのが今回のお題です。 1万回対戦させ、勝ち・負け・引き分けの数を表示してください。 そして先手が有利であることを確かめてください。

良い手を思考するプレイヤーについては別のお題にしようと思っています。 プレイヤーを簡単に差し換えることができる設計を目指してください。

Posted feedbacks - OCaml

とりあえず愚直に。
player1:5803 player2:2916 draw:1281
 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
type board = int list;;
type player = P1 | P2;;
type result = Won of player | Draw | Next of board;;

let rec mark board n =
  let idx = Random.int 9 in
  if List.nth board idx != 0 then mark board n
  else
    let _, board' = List.fold_left (fun (idx', res) n' ->
      (idx' + 1, (if idx' == idx then res @ [n] else res @ [n']))
    ) (0, []) board in board'

let masks = [
  [1; 1; 1; 0; 0; 0; 0; 0; 0];
  [0; 0; 0; 1; 1; 1; 0; 0; 0];
  [0; 0; 0; 0; 0; 0; 1; 1; 1];
  [1; 0; 0; 1; 0; 0; 1; 0; 0];
  [0; 1; 0; 0; 1; 0; 0; 1; 0];
  [0; 0; 1; 0; 0; 1; 0; 0; 1];
  [1; 0; 0; 0; 1; 0; 0; 0; 1];
  [0; 0; 1; 0; 1; 0; 1; 0; 0];
];;

let judge board =
  let judge' board =
    List.exists (fun mask ->
      mask = List.map (fun (a, b) -> a * b) (List.combine mask board)
    ) masks
  in
  if judge' board then Won P1
  else if judge' (List.map (~-) board) then Won P2
  else if List.mem 0 board then Next board else Draw
;;

let rec player1 board =
  match judge (mark board 1) with
    | Next board' -> player2 board'
    | _ as x -> x
and player2 board =
  match judge (mark board ~-1) with
    | Next board' -> player1 board'
    | _ as x -> x
;;

let rec play (p1, p2, draw) = function
  | 0 -> (p1, p2, draw)
  | _ as n ->
      match player1 [0; 0; 0; 0; 0; 0; 0; 0; 0] with
    | Won P1 -> play (p1 + 1, p2, draw) (n-1)
    | Won P2 -> play (p1, p2 + 1, draw) (n-1)
    | Draw   -> play (p1, p2, draw + 1) (n-1)
    | _      -> raise (Failure "unknown")
;;

let main =
  Random.self_init ();
  let p1, p2, draw = play (0, 0, 0) 10000 in
  Printf.printf "player1:%d player2:%d draw:%d\n" p1 p2 draw

Index

Feed

Other

Link

Pathtraq

loading...