三目並べで失う


18

Misèretic-tac-toeのゲームをプレイするプログラムを作成します。つまり、目標は、対戦相手に強制的に3連発させることです。

標準入力で「X」または「O」(ゼロではなく文字)を受け入れて、プログラムの再生側を決定します。次に、自分のターンでの動きに1桁を出力し、ゲームオーバーになるまで相手のターンで1桁を読み取ります(Xが常に最初になります)。勝者が決定したら、勝った人にはXまたはO、引き分けにはDを出力します。たとえば、Oが連続して3を獲得した場合、Xが勝ちます。

ボードには次のような番号が付けられていると仮定します。

0|1|2
-----
3|4|5
-----
6|7|8

理想的には、ソリューションは最適であり、決して失われないことです。三目並べのように、完璧なプレーは常に引き分けになるはずです。上記のプロトコルが順守されている場合、さまざまな可能な戦略に対して自動的に送信をテストできます。

勝者は最短のコードです。同様に良い動きからランダムに選んで、もう少し予測不能にする場合のボーナスポイント。

回答:


10

Python、383文字

M=[21,1344,86016,4161,16644,66576,65793,4368]
X=lambda B,k:any(m*k==B&m*3for m in M)
def S(B):
 if X(B,2):return 1,
 M=[i for i in range(0,18,2)if B>>i&3<2]
 return max((-S((B|3<<i)^87381)[0],i)for i in M)if M else(0,)
r='D'
c=ord(raw_input())&1
B=0
for i in range(9):
 if i&1==c:m=S(B^c*87381)[1];print m/2;B|=3-c<<m
 else:
  B|=2+c<<input()*2
  if X(B,2+c):r='XO'[c];break
print r

基板はB、平方当たり2ビットを使用して整数として表現される0001、空を表す、10Oを表し、11Xを表すこと Mとビットマスクのセットである01失うトリプル(のスポットに21= 0b010101など=上部列) Xを計算任意失う場合triple for kはボード上に存在します。SXの最適な動きをミニマックス検索し、スコア(1 =勝ち、-1 =負け、0 =引き分け)とスクエアインデックスのペアを返します。 ^87381(= ^0b010101010101010101)空の正方形を変更せずにXとOを反転します。

コンピューターが失われることはないので、そのチェックを含める必要はありませんでした:)。

おそらく、より簡単で短いルールベースのアルゴリズムがありますが、これは機能します。


卑劣な卑劣なビットごとの魔術+1
ローハンジュンジュンワラ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.