challenge マルバツゲーム

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

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

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

Posted feedbacks - Smalltalk

Squeak Smalltalk で。

 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
| マス目群 勝敗カウンタ 勝ち判定 |
マス目群 := OrderedCollection new.
(1 to: 3) asDigitsToPower: 2 do: [:座標 | マス目群 add: 座標 copy].

勝敗カウンタ := Bag new.

1e4 timesRepeat: [
    | 残りのマス目群 先手 後手 打ち手順 手番 結果 |
    残りのマス目群 := マス目群 copy shuffled.
    先手 := OrderedCollection new. 後手 := 先手 copy.
    打ち手順 := {先手. 後手}.
    手番 := 0.
    結果 := nil.
    勝ち判定 := [:取得済み |
        (#(first second) anySatisfy: [:セレクタ |
            (取得済み
                groupBy: [:各々 | 各々 perform: セレクタ]
                having: [:括り | 括り size = 3]) notEmpty]) or: [
        {[:各々 | 各々 first = 各々 second]. [:各々 | 各々 sum = 4]}
            anySatisfy: [:条件 | (取得済み count: 条件) = 3]]].

    [残りのマス目群
        ifEmpty: [結果 := #引き分け]
        ifNotEmpty: [
            | 取得マス目群 |
            (取得マス目群 := 打ち手順 atWrap: (手番 := 手番 + 1))
                add: 残りのマス目群 removeFirst.
            (勝ち判定 value: 取得マス目群) ifTrue: [
                結果 := 手番 odd
                    ifTrue: [#先手勝ち]
                    ifFalse: [#後手勝ち]]].
    結果 isNil] whileTrue.

    勝敗カウンタ add: 結果].

^勝敗カウンタ sortedCounts asArray

"=> {5895->#先手勝ち. 2796->#後手勝ち. 1309->#引き分け} "

勝敗判定が分かりづらかったので変えてみました。

 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
| マス目群 ライン群 勝敗カウンタ |
マス目群 := OrderedCollection new.
(1 to: 3) asDigitsToPower: 2 do: [:座標 | マス目群 add: 座標 copy].

ライン群 := OrderedCollection new.
(1 to: 3) do: [:座標1 |
    ライン群 add: ((1 to: 3) collect: [:座標2 | {座標1. 座標2}]).
    ライン群 add: ((1 to: 3) collect: [:座標2 | {座標2. 座標1}])].
ライン群 add: #((1 1) (2 2) (3 3)); add: #((1 3) (2 2) (3 1)).

勝敗カウンタ := Bag new.

1e4 timesRepeat: [
    | 残りのマス目群 先手 後手 打ち手順 手番 結果 |
    残りのマス目群 := マス目群 copy shuffled.
    先手 := OrderedCollection new. 後手 := 先手 copy.
    打ち手順 := {先手. 後手}.
    手番 := 0.
    結果 := nil.

    [残りのマス目群
        ifEmpty: [結果 := #引き分け]
        ifNotEmpty: [
            | 取得マス目群 |
            (取得マス目群 := 打ち手順 atWrap: (手番 := 手番 + 1))
                add: 残りのマス目群 removeFirst.
            (ライン群 anySatisfy: [:必須マス群 |
                    取得マス目群 includesAllOf: 必須マス群])
                ifTrue: [結果 := 手番 odd
                    ifTrue: [#先手勝ち] ifFalse: [#後手勝ち]]].
    結果 isNil] whileTrue.

    勝敗カウンタ add: 結果].

^勝敗カウンタ sortedCounts asArray

Index

Feed

Other

Link

Pathtraq

loading...