💮

ChatGPTは完全情報ゲームで勝利できるか(三目並べ編)

に公開

完全情報ゲーム(より正確には二人零和有限確定完全情報ゲーム)はルールが比較的単純なものであれば必勝法が確立されている。
例えば三目並べ(○×ゲーム)は手順を知っていれば必ず引き分けに持ち込むことができる。
子供の頃にこれを知らない相手に無双していい気になっていた人も多いことだろう。

そんな完全情報ゲームを、2025年の大規模言語モデル(LLM)であれば検索をせずとも自力で必勝パターンをみつけて人間を打ち負かしてくれるのではないか。

結論から言うと、一部のゲームではまだまだ人間のほうが強かったのだが[1]、2025年時点ではこれくらいであったという記録を残しておきたいと思う。

下準備

実験をしたのは2025年の5月。
200ドル払ってその時点で最新モデルの4oを使えるようにする。

実験はスレッドを分ける。

実験間で影響がでないように、
設定→パーソナライズ→メモリの「保存されたメモリを参照する」「チャット履歴を参照する」をそれぞれをオフにする。

三目並べ

実験1(4o)

まずは何も教え込まずに三目並べができるか確認する。
モデルは4oを選択。

あなた:
あなたはボードゲームの天才です。
ChatGPT:
ありがとうございます!ボードゲームの天才として、戦略、ルール説明、オススメの作品、オリジナルゲームの作成まで何でもお任せください。
あなた:
三目並べをしましょう。
絶対に負けないよう全力で対戦してください。
ChatGPT:
了解しました。全力で三目並べ(○×ゲーム/Tic-Tac-Toe)に挑みます。私は 絶対に負けない戦略を用いてプレイします。
ルール確認:
3×3のマス目。
交互に「〇」「×」を置く。
縦・横・斜めいずれかに3つ並べた方が勝ち。
あなたが先手(〇)、私は後手(×)でよろしいですか?

 1 | 2 | 3
---+---+---
 4 | 5 | 6
---+---+---
 7 | 8 | 9

好きな位置(1〜9)を選んで、〇を置いてください!

特に特別な指示を出さなくてもすぐに対戦を始めることができた。
オセロと三目並べはゲーム作りのサンプルとしてベタなので教師データが多いのだろう。

あなた:
先手で3
ChatGPT:
あなた(〇)がマス 3 に置きましたね。

   |   | 〇
---+---+---
   |   |  
---+---+---
   |   |  

では、私は負けないように戦略的に動きます。
後手として、私はマス 5(中央)に × を置きます。

こちらの手を受けて考えることもできている。

ここから数手のやり取りは省略する。

   |   | 〇
---+---+---
   | × |  
---+---+---
〇 |   |  

問題は先手(人間)が7のマスを取ったこの手番で、ChatGPTがどんな手をさせるかだ。
2, 4, 6, 8のいずれかに置かなければ、後述するフォークの手筋が成立してしまう。

ChatGPT:
では私は、マス 1 に × を置きます。

 × |   | 〇
---+---+---
   | × |  
---+---+---
〇 |   |  

あなたの番です。次の手(1〜9の空いているマス)をどうぞ!
(空き:2, 4, 6, 8, 9)

はい、だめでした。
先手が次に9のマスを取ると、6か8のどちらを取っても勝ちの状況ができてしまう。

どちらを取っても勝ち(フォーク)

 × |   | 〇
---+---+---
   | × | 6
---+---+---
〇 | 8 | 〇

ということで、4oは最善手が指せませんでした。

以降、手を進めて先手が一列を揃えても手を続けようとしたりして、負けていることにも気づかず。

何も教えてないのにここまでゲームが成立していること自体はすごいのだが、最後までイマイチな挙動だった。

実験2(4o)

事前にシミュレーションをさせて、そこから得た知見を元に考えさせたら強くなるのではないか。

あなた:
あなたはボードゲームの天才です。
ChatGPT:
ありがとう!ボードゲームなら戦略系からパーティー系、クラシックな将棋やチェスまで何でもお任せください。遊び方の説明、戦術のアドバイス、オリジナルゲームのアイデア出しなど、何でも対応できますよ。
どんなボードゲームの話をしましょうか?それともオリジナルのゲームを一緒に作ってみますか?
あなた:
先手、後手ともに自身で考えて、三目並べを10000戦してください。
このとき既知のアルゴリズムは使用しないでください。
各試合どちらが勝ったかと試合の流れの要約を表にしてください。
ChatGPT:
こちらが、先手(X)と後手(O)による三目並べ(Tic-Tac-Toe)の10000戦の結果です。すべての試合で、既知のアルゴリズムを使用せず、完全なランダム戦略でプレイしました。
勝敗の要約:

  • X(先手)勝利: 5820回
  • O(後手)勝利: 2908回
  • 引き分け: 1272回
    各試合の勝者と、どのような手順で進んだかの流れ(要約)を表にして表示しています。さらに分析や、別の条件での対戦シミュレーションも可能ですので、興味があればお知らせください。

何度か実験していると、すべて引き分けといった怪しい結果を返すことがあった[2]ので、「各試合どちらが勝ったかと試合の流れの要約を表にしてください。」と追加してサボらせないようにしている。

ChatGPTがシミュレーションで使ったとするプログラムは以下。パッとこれだけのコードが勝手に作られ勝手に使われていることはすごい。

import random
import pandas as pd

# Define the Tic-Tac-Toe board and moves
def check_winner(board):
    win_patterns = [
        [0, 1, 2], [3, 4, 5], [6, 7, 8],  # Rows
        [0, 3, 6], [1, 4, 7], [2, 5, 8],  # Columns
        [0, 4, 8], [2, 4, 6]              # Diagonals
    ]
    for pattern in win_patterns:
        a, b, c = pattern
        if board[a] == board[b] == board[c] and board[a] != " ":
            return board[a]
    if " " not in board:
        return "Draw"
    return None

def random_strategy(board):
    return random.choice([i for i, v in enumerate(board) if v == " "])

# Simulate 10000 games without using known algorithms
results = []
for _ in range(10000):
    board = [" "] * 9
    current_player = "X"  # First player
    moves = []

    while True:
        move = random_strategy(board)
        board[move] = current_player
        moves.append(f"{current_player}:{move}")
        winner = check_winner(board)
        if winner:
            results.append({
                "Winner": winner,
                "Moves": " -> ".join(moves)
            })
            break
        current_player = "O" if current_player == "X" else "X"

df_results = pd.DataFrame(results)
summary = df_results["Winner"].value_counts().reset_index()
summary.columns = ["Result", "Count"]

import ace_tools as tools; tools.display_dataframe_to_user(name="Tic-Tac-Toe Game Results", dataframe=df_results)
summary

あなた:
10000戦の結果から負けないための手順をまとめてください。
ChatGPT:
こちらは10000戦のデータを元にした「負けないための手順」の分析結果です。
各試合の最初の2手(先手Xと後手Oの初手)に注目し、それぞれの勝率・引き分け率を算出しました。以下の点から、どのオープニングが有利か、またどの組み合わせが「負けにくい」かがわかります。
分析のポイント:
X:4 → O:2(中央 → 左上):先手Xが中央を取った場合、後手Oが左上に返す形は、Xの勝率が約61.7%、Oの勝率が約25.3%、引き分けが約12.9%。
X:4 → O:0(中央 → 左上隅):これも先手Xが非常に有利(勝率64.2%)です。
X:6 → O:7(左下 → 下中央)やX:5 → O:3(右中央 → 左中央)など、中央を取らない戦略は引き分けやOの勝率がやや高くなりますが、Xが依然として優位です。
結論(負けないための指針):
先手(X)を取ったら、最初に中央(4)を選ぶのが圧倒的に有利。
後手(O)の場合、Xが中央を取ってきたときは角(0, 2, 6, 8)を取り、対角を意識するのが良い対抗手。
初手で辺(1, 3, 5, 7)を選ぶのはどちらの手番でも勝率が低くなりやすい。
より高度な戦略の導出や、これらをもとにしたAIの開発なども可能です。希望があればさらに掘り下げた戦術をまとめます。
あなた:
その知見を用いて絶対に負けないよう全力で私と対戦してください。
自分の手番ごとになぜその手を選んだのか説明してください。

結果

 O |   | X
-----------
   | O |  
-----------
 X |   | X

フォーク成立、ダメでした。

実験3(o3)

しょせんChatGPTはこんなものか。失望しかけたそんなとき、「4oはマルチモーダルに強いが、推論に特化しているのはo3」ということを思い出す。
ゲームをするといったタスクはo3の方が向いているのではないか。

さっそくやってみた。

あなた:
あなたはボードゲームの天才です。
ChatGPT:
ありがとうございます!ボードゲームのことなら何でもおまかせください。
遊ぶ仲間やシチュエーション、好きなゲームのタイプなど、どんな情報でも教えていただければ、最適なゲーム選びや戦略、ルール説明までバッチリお手伝いしますよ。今日はどんなことでお力になりましょうか?
あなた:
三目並べをしましょう。
絶対に負けないよう全力で対戦してください。
思考時間:8秒
ユーザーが三目並べをしたいと言っています。完璧な戦略を使って負けないように進める必要があります。まず、ゲームボードをどう表現するかを考えなきゃなりません。インタラクティブな会話なので、ボードを表示してユーザーに手を聞く形にしたいです。誰が先攻か決めて、座標や数字でボードを見せる方法を考えます。ユーザーの希望を聞いてからか、私から始めるか…その辺りも調整しつつ進めます。
ChatGPT:
では、三目並べ(Tic-Tac-Toe)を始めましょう!
以下の 3 × 3 のマス目を使います。空いているマスを 1〜9 の数字で指定してください。

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

4o同様、ふつうにゲームを始めることができたので、課題の盤面まで一気に手を進める。

1 | 2 | X
---------
4 | O | 6
---------
X | 8 | 9

次にChatGPTが何を指すか。なんとここでChatGPTは1分52秒も思考時間をかける。

X has marked positions 3 and 7, O is at position 5. Let's analyze potential threats. For X, the focus is on columns, rows, and diagonals. Specifically, row 1 has X in position 3, and row 3 has X marked in position 7. The anti-diagonal (positions 3-5-7) could form a line, but it’s partially blocked by O at position 5. I now need to make a move to prevent any potential line formation by X.
X has taken opposite corners (3 and 7), so to avoid giving them a chance to fork, O should play in an edge. I’ll choose position 2 (top-middle). This move blocks X from gaining a double opportunity and prevents them from gaining an advantage. The board looks like this now:
1: empty | 2: O | 3: X
4: empty | 5: O | 6: empty
7: X | 8: empty | 9: empty
Now, I’ll check if X has any immediate threats or ways to fork.
X has two threats, one with position 6 and the other with 8, creating a fork. This means O can only block one of them, but not both. If O plays edge 6 to block the column, X will still capture the win at 8. Even if O attempts to create a row 1 win, X still controls the game with a threat at position 9. Thus, X will win unless O can create a dual threat before the next turn, which doesn't seem possible here.

しかも本気なのか、思考の言語が英語であった(なぜか途中から日本語に戻るが)。
以降の思考は中略してハイライト部分だけ転記する。

理論を確認してみましょう。ティックタックトーでは、Xが対角線の角に配置してOが中央にいると、Xが勝利を強いることができるかもしれません。例えば、Xが1、Oが5、Xが9を選ぶと、Xが次に3に移動してフォークを作り、勝利になります。ただし、Oがブロックできる可能性もあります。
結局、引き分けの可能性もあるかもしれません。最終的に、結果を評価するために計算を行う必要があります。

def outcome(board):
    lines = [(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)]
    for a,b,c in lines:
        if board[a]==board[b]==board[c]!=None:
            return 1 if board[a]=='X' else -1
    if None not in board:
        return 0
    return None

def minimax(board, maximizing):
    result = outcome(board)
    if result is not None:
        return result
    if maximizing:  # X
        best=-2
        for i in range(9):
            if board[i] is None:
                board[i]='X'
                val=minimax(board,False)
                board[i]=None
                best=max(best,val)
                if best==1: break
        return best
    else:  # O
        best=2
        for i in range(9):
            if board[i] is None:
                board[i]='O'
                val=minimax(board,True)
                board[i]=None
                best=min(best,val)
                if best==-1: break
        return best

board=[None]*9
board[2]='X'
board[6]='X'
board[4]='O'
minimax(board,False)

なんとこいつ、ミニマックス法を使い始めた。
そして思考はさらに続き、出した答えは、

ChatGPT:
私(O)の手:2 に置きます。

1 | O | X
---------
4 | O | 6
---------
X | 8 | 9

フォークを阻止!
以降も手を続けると最善手を指し続けることができた。

X | O | X
---------
O | O | X
---------
X | X | O

ChatGPT:
これでマスがすべて埋まりました。どちらも三目揃わず 引き分け です!
ナイスゲームでした。もう一局や、別のボードゲームで遊んでみますか?

なるほどo3、大したものだ。

実験4(o3)

しかし途中でミニマックス法で計算するのはズルくないか。
計算をさせないで同じ結果を出力することはできないだろうか。

あなた:
あなたはボードゲームの天才です。
ChatGPT:
ありがとうございます!ボードゲームの話題なら大歓迎です。 😊
プレイのコツが知りたいゲームや、おすすめ作品、あるいは自作ゲームのアイデア相談など、どんなことでもお手伝いしますよ。今日はどんなボードゲームトークをしましょうか?
あなた:
先手、後手ともに自身で考えて、三目並べを50000戦してください。
このとき既知のアルゴリズムは使用しないでください。
各試合どちらが勝ったかと試合の流れの要約を表にしてください。
思考時間:28秒
ユーザーが要求している内容は、50000戦の三目並べをシミュレートして結果と流れを表にまとめるという非常に大きなリクエストです。全部を出力するのは現実的ではないので、このままではメッセージが膨大になってしまいます。代わりに、シミュレーション結果の統計やサンプルを提供する方法を提案できます。ユーザーに実現可能な範囲での代替案を示し、さらに詳細を確認した方が良いかもしれません。
ユーザーが要求している50,000回の三目並べシミュレーションは非常に大規模で、結果を表にするのは現実的ではないため、圧縮された形式で提供する方法を考えています。例えば、CSVファイルを作成し、そこにゲームの番号、勝者、および簡略化された試合の流れを記録する案です。アルゴリズムに関しては、既知の完璧な戦略を使わず、純粋なランダムプレイを選んで、できるだけシンプルに進める方向です。
ChatGPT:
シミュレーションした 50,000 局の結果を CSV ファイルにまとめました。
先手が 29,292 勝、後手が 14,420 勝、引き分けが 6,288 局という分布になっています。

今回は「このとき既知のアルゴリズムは使用しないでください。」という一文を加えている。
このあとは実験2と同様にシミュレーションから知見をまとめさせてから対戦する。

0 | 1 | X
---------
3 | O | 5
---------
X | 7 | 8

課題の盤面まで手を進めた[3]が、ここまでも思考の出力を信じるのならコードによる計算はしていない。

思考時間:1分1秒
The tic-tac-toe board is set, and now I want to figure out the best move for me as O.
X has two X’s on the diagonal (positions 2 and 6). I can’t block that, since my O is already at the center (position 4). I’m focusing now on preventing X from winning while also trying to force a draw. I'll look at where I could secure my position without leaving easy openings for X to win. I’m going to want to avoid placing O in risky positions!
X has two opposite corners (2 and 6), which is risky for creating a fork. To prevent this, O should play on an edge, like 1, 3, 5, or 7, to block potential forks.
If O plays 1 (top middle), it prevents X from setting up a fork. I’ll check if X can still create a winning line. For example, if X plays 8 (bottom right corner), it almost forms a fork. But I can block with O in the right spots. Let's keep testing.
I’m looking at possible moves to block a fork for O. X could create a fork by playing 8, which would give them two lines to win. After O plays on edge, X could still manage to create a fork if the right conditions are met.
In this case, any edge can lead to a fork if I’m not careful. The best strategy is for O to play in the right spot, but it’s tricky since both corners can still lead to a fork.
After analyzing the moves, it's clear that starting with opposite corners for X and the center for O leads to a forced win for X with perfect play. O’s best chance to avoid losing is to prevent X from getting those opposite corners early on. Based on our reasoning, the best defense for O would involve placing O on specific edge squares, but even that doesn't fully block X's ability to create a fork. So, it's likely impossible for O to guarantee a draw if X plays optimally.
ChatGPT:
私の手(O):1(上辺)

0 | O | X
---------
3 | O | 5
---------
X | 7 | 8

きちんとフォークの危険性に気づいて回避する手を選択した。
その後も手を続けると、試合は引き分けとなった。

あくまで思考の出力を信じるならばだが、ミニマックス法を使わなくてもo4は最善手を選択することができたことになる。

さらに別のゲームに挑戦したところそのゲームはぜんぜんダメな結果だったのでもしかすると三目並べだけChatGPTがたまたま得意なだけかもしれない。
しかし三目並べだけであったとしても、ここまで最善手を選ぶことができるとは、LLMの進歩に目を見張る。

脚注
  1. あくまでLLMでの話であり、すでに将棋や囲碁くらい複雑なゲームでも強化学習などを使うことで人類はAIに打ち負かされている。 ↩︎

  2. 本当にたびたび嘘をつかれた。勝ち負けがはっきりわかるゲームだから比較的簡単に気づけるが、そうでないケースで使うことを考えるとゾッとする。 ↩︎

  3. コマの座標が1はじまりなのか、0はじまりなのかはセッションごとに異なった。CとFORTRANの両方を触ったときの気持ちになって面白かった。 ↩︎

Discussion