重力操作可能なコネクト4のゲームAI作成
要約
コネクト4に重力操作を加えた自作ゲームと、そのゲーム用のAIを作成しました。
これです
ゲーム画面
ゲームの概要
コネクト4に重力操作を加えると面白いのでは?と思い、作ってみました。
ルール
基本的なルールは通常のコネクト4と同じですが、1ターンで以下のいずれか1つを選択できます:
- コマを配置: 空いている列にコマを入れる
- 重力の向きを変更: 重力の向きを変更する(今の重力方向以外の3方向)
重力の仕組み
例えば重力を右向きに変更すると:
- 盤上のすべてのコマが右向きに落下
- 新しくコマを配置する際は、盤面の左端から入れる
- コマは右向きの重力に従って右端に落ちる
これが
こうなる
重力を変更すると、盤上のすべてのコマがその重力方向に落下します。また、新しくコマを配置する際は、盤面の左端から入れることになります。
コマはその重力方向に従って落下します。
このルールだと自分のコマと相手のコマが同時に4つ揃うことがありますが、その場合は引き分けとします。
ルールの簡単な説明は以上です。
こちらからプレイできるので、是非遊んでみてください。
ゲームAIの作成
ここからが本題です。
始めに作ったのは人間vs人間のモードでしたが、せっかくなので人間vsCPUのモードも作ることにしました。
CPUのレベルは"Weak"、"Normal"、"Strong"の3段階として、それぞれ別の方法で実装しています。
尚、NormalとStrongの実装は下記の書籍を参考にしました。
参考文献
- 青木栄太 (2023). 『ゲームで学ぶ探索アルゴリズム実践入門~木探索とメタヒューリスティクス』. 技術評論社. Amazon
🐇Weak の実装
合法手からランダムに1つ選ぶだけです。
// Weak CPU
export const chooseCpuActionWeak = (ctx: CpuContext): CpuAction | null => {
// actions配列に現在の盤面で取りうる全ての合法手(コマを入れる or 重力を変える)を追加する処理
// (具体的な実装は省略)
// 合法手の中からランダムで選んで返す
const choice = actions[Math.floor(Math.random() * actions.length)];
return choice;
};
Weakは自滅するほど弱いですが、このゲームのルールに慣れてもらうための練習用CPUなのでこれで十分です。
🐑Normal の実装
原始モンテカルロ法を使います。
// Normal CPU
export const chooseCpuActionNormal = (ctx: CpuContext): CpuAction | null => {
// actions配列に現在の盤面で取りうる全ての合法手(コマを入れる or 重力を変える)を追加する処理
// (具体的な実装は省略)
const rolloutsPerAction = 50;
let best: CpuAction | null = null;
let bestScore = -Infinity;
for (const action of mcCandidates) {
let total = 0;
//各合法手に対してrolloutsPerAction回のシミュレーションを行う
//勝つなら1,負けるなら0,引き分けなら0.5をtotalに加算する
//(具体的な実装は省略)
const score = total / rolloutsPerAction;
if (score > bestScore) {
bestScore = score;
best = action;
}
}
return best;
};
rolloutsPerAction
はシミュレーション回数で、50
に設定しています。もう少し大きくすることもできますが、強くなりすぎても面白くないのでこの値にしています。
🦁Strong の実装
モンテカルロ木探索を使っています。実装はここでは省略します。
快適にプレイできる範囲でシミュレーション回数をできるだけ大きくしているので、かなり強いです。
🐇Weak vs 🐑Normal vs 🦁Strong
3つのAIの強さを検証するため、リーグ戦形式で各組み合わせ100回ずつ対戦させました。
対戦結果
対戦組み合わせ | 勝者 |
---|---|
🐇Weak vs 🐑Normal | 🐑Normal(100勝0敗0分) |
🐇Weak vs 🦁Strong | 🦁Strong(100勝0敗0分) |
🐑Normal vs 🦁Strong | 🦁Strong(80勝11敗9分) |
良い塩梅で調整できていそうです。
感想
Strongが強すぎて私は全然勝てません。重力操作は人類には早すぎるのかもしれない。
また、今回始めてReactを使ってみました。結構面白かったです(実装はほぼ全て Cursor Pro に任せましたが)。
Discussion