ランダム・マルバツ

Doukaku?から

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

以下が勝ちのパターンになるようにマス目に番号を振っておく

wins={{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}};

マルがある場所(あるいはバツがある場所)をリストで表現すると、次のように勝ちを判定できる

isWinner[player_]:=MemberQ[Length[Intersection[player,#]]&/@wins,3]

ゲームの結果は、マルの勝ちなら1、バツの勝ちなら-1、引き分けなら0とする

judge[{p1_,p2_}]:=
  If[isWinner@p1,1,
    If[isWinner@p2,-1,
      If[Length@p1==5,0,Null]]]

盤面の状態を{マルのリスト, バツのリスト}で表すことにする。状態を与えると、可能な場所のリストを返す関数は以下のとおり

operators[state_]:=Complement[Range@9,Flatten@state]

手を決める関数を2つ(マル用とバツ用)与えると、ゲームが行われる

game[decision1_,decision2_]:=Module[{state={{},{}},result=Null},
    While[result===Null,
      If[Length@state[[1]]==Length@state[[2]],
        AppendTo[state[[1]],decision1[Sort/@state]],
        AppendTo[state[[2]],decision2[Sort/@state]]];
      result=judge@state];
    result]

ランダム・プレーヤーが用いる関数は次のとおり

randomDecision[state_]:=With[{x=operators@state},
    x[[Random[Integer,{1,Length@x}]]]]

対戦させると、マルの5877勝2835敗1288分

Timing[
  result=Table[game[randomDecision,randomDecision],{10000}];
  Count[result,#]&/@{1,-1,0}
  ]

{7.688 Second, {5877, 2835, 1288}}

負けないマルバツに続く

Related posts:

  1. アレイのuniq、どう書く?(Mathematica)
  2. プレゼント交換の手伝い
  3. 油売り算(Prolog)
  4. 油売り算(Mathematica)
  5. Puzzles for Hackers
カテゴリー: ゲーム, コード   タグ:   この投稿のパーマリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>