challenge マルバツゲーム

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

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

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

Posted feedbacks - PostScript

あんまり綺麗なコードじゃないですが、 PostScript で。

O win : 5892
draw  : 1247
X win : 2861
  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
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
%!PS

/ShowMap { % [Map Vector]  ShowMap  -
    aload length sqrt cvi
    dup { % v0 v1 ... vn N
        dup { % v0 v1 ... vn N
            exch dup
            0 gt { pop (O) } { 0 lt { (X) } { ( ) } ifelse } ifelse
            print
        } repeat
        () =
    } repeat
    pop
    () =
} bind def

/DotProduct { % [Vector1] [Vector2]  DotProduct scaler
    [ 3 1 roll
    dup length 1 sub 0 1 3 -1 roll {
        3 copy get 3 1 roll exch get mul 3 1 roll
    } for
    pop pop
    ]

    0 exch
    { add } forall
} bind def

/CheckerVector [
        [ 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 ]
    ] def

/KachiMake { % [Map Vector]  KachiMake   integer
    dup length sqrt cvi 0 exch
    CheckerVector
    {
        % [Map] 0 N [V]
        3 index DotProduct
        dup
        % [Map] 0 N V V
        2 index eq {
            pop pop 1 exch exit
        } {
            % [Map] 0 N V
            1 index neg eq {
                pop -1 exch exit
            } if
        } ifelse
    } forall
    pop exch pop
} bind def


/Okeru { % [Map] Okeru [Okeru]
    [ exch dup length 1 sub
    0 1  3 -1 roll
    {
        2 copy get 0 eq {
            exch
        } {
            pop
        } ifelse
    } for
    pop
    ]
} bind def

/RandomPlayer { % [Map] player RandomPlayer [Map'] bool
    % player: -1 or 1
    exch dup dup 4 2 roll Okeru
    dup length dup
    0 gt {
        rand 1024 idiv exch mod
        get
        exch put true
    } {
        pop pop pop pop false
    } ifelse
} bind def

/Marubatsu { % [Map] int /Proc1 /Proc2 Marubatsu  int
    % Result: 0 : draw, 1: O win, -1: X win

    % Initial Table
    4 copy 2 index 1 lt {
        exch
    } if
    pop
    cvx exec
    {
        KachiMake dup 0 eq
        {
            pop
            3 -1 roll neg 3 1 roll
            Marubatsu
        } if
    } {
        pop 0
    } ifelse
} bind def

% Randmize
realtime srand

% Counter
[0 0 0]

10000 {
    [0 0 0 0 0 0 0 0 0] 1 /RandomPlayer /RandomPlayer Marubatsu
    5 1 roll pop pop pop
%    ShowMap
    pop
    1 add 2 copy 2 copy get 1 add put pop
} repeat

aload pop
(O win : ) print =
(draw  : ) print =
(X win : ) print =

Index

Feed

Other

Link

Pathtraq

loading...