「1-4. reversi を動かしてみる」が正常に動いたなら、いよいよAIプレーヤーを自作してみましょう!
大丈夫、そんなに難しくありませんよ。
AIプレーヤーのアルゴリズムを考える
AIプレーヤーの実装に先立ち、まず、どのようなアルゴリズムで思考させるのかをしっかりと考える必要があります。
ここでは、次のようなアルゴリズムで思考するAIプレーヤーを作成することにしましょう。
- 角に打てる場合は角に打つ。
- 角に打てない場合は、角から2つ隣のマスに打つ。
- 上記のいずれにも打てない場合は、角から対角線上の内側に2つ入ったマスに打つ。
- 上記のいずれにも打てない場合は、・・・(以下略)
- どこにも打てない場合は、パスを宣言する。
つまり、リバーシ盤のマス目に優先順位を付け、その優先順位に沿って順番に打てるかを確認し、最初に見つかった打てる位置を選択することにします。
上図の優先順位は適当に設定したものですので、変更しても構いません。もっと良い順番があるかもしれません。
さて、どれだけ強いAIプレーヤーになるかは分かりませんが、とりあえずアルゴリズムは明確になりました。
なんだ、簡単すぎる、物足りないなとお感じの方は「3-1. AIプレーヤーの思考アルゴリズム」でいくつかのアルゴリズムを紹介していますので、より高度な思考アルゴリズムを考えてみてください!
AIプレーヤーを実装する
ここからは、上で考えたアルゴリズムを実際の Java ソースコードに実装していきます。
A) AIプレーヤークラスの作成
xyz.hotchpotch.reversi.core.Player インタフェースを実装することにより、AIプレーヤーを作成することができます。
(1) パッケージ・エクスプローラー・ビューの [myFirstJava] を右クリックし、[新規] – [パッケージ] を選択します。
(2) パッケージ名を入力して [完了] ボタンを押します。
パッケージ名は、とりあえず “mypackage” とでもしておけば良いでしょう。
[src] の配下に [mypackage] パッケージが作成されればOKです。
パッケージ名について
パッケージは似た役割のクラス群をまとめるためのものです。自作したプログラムを外部に配布しない限り、好きな名前を付けて構いません。
外部に配布する場合は、誰かが作った他のパッケージと決して名前が被らないようにしなければなりません。そのため、インターネット上の自分が所有するドメイン名をひっくり返したものをパッケージ名とするルールになっています。
reversi ライブラリの場合は、私が所有するドメイン名「hotchpotch.xyz」をひっくり返した「xyz.hotchpotch」から始まるパッケージ名を利用しています。
ドメイン名の取得にはそのドメイン名の人気に応じてお金がかかりますが、比較的簡単に取得できます。将来的にプログラムの配布やWebサイトの公開などを行おうと考えている方は、取得にチャレンジすると良いかもしれません。
(3) 作成したパッケージを選択して右クリックし、[新規] – [クラス] を選択します。
(4) 適当なクラス名を入力します。ここでは「MyFirstAIPlayer」としてみました。
クラス名を入力したら、インターフェースの [追加…] ボタンを押します。
(5) 上段のテキストボックスに「Player」と入力してください。
下段の [一致する項目] に「Player – xyz.hotchpotch.reversi.core」と出てきたら、それを選択して [OK] ボタンを押します。
もし [一致する項目] に「Player – xyz.hotchpotch.reversi.core」が表示されない場合は reversi ライブラリの取り込みが出来ていませんので、「1-4. reversi を動かしてみる」をもう一度やり直してみてください。
(6) [インターフェース] 部分に「xyz.hotchpotch.reversi.core.Player」が追加されていることを確認し、[完了] ボタンを押します。
次のように [MyFirstAIPlayer] クラスが表示されれば、クラス作成の完了です。
B) 思考ロジックの実装
(1) まず、ビューの配置を使いやすいように調整しましょう。
以下のビューは当面なくても困らないので閉じてしまいましょう。
- 「プロジェクト・エクスプローラー」ビュー
- 「アウトライン」ビュー
- 「ランナー」ビュー
- 「Gradle タスク」ビュー
- 「サーバー」ビュー
↓
だいぶスッキリしましたね。
閉じたビューは、メニューの [ウィンドウ] – [ビューの表示] から再表示することができます。
(2) 自動生成されたソースコード [MyFirstAIPlayer.java] の中身を確認してみましょう。
次のように自動生成されているはずです。
package mypackage;
import xyz.hotchpotch.reversi.core.Board;
import xyz.hotchpotch.reversi.core.Color;
import xyz.hotchpotch.reversi.core.Player;
import xyz.hotchpotch.reversi.core.Point;
public class MyFirstAIPlayer implements Player {
@Override
public Point decide(Board board, Color color, long remainingMillis) {
// TODO 自動生成されたメソッド・スタブ
return null;
}
}
(3) 思考ロジックを実装します。次のようにソースコードを書き換えてください。
package mypackage;
import xyz.hotchpotch.reversi.core.Board;
import xyz.hotchpotch.reversi.core.Color;
import xyz.hotchpotch.reversi.core.Player;
import xyz.hotchpotch.reversi.core.Point;
import xyz.hotchpotch.reversi.core.Rule;
public class MyFirstAIPlayer implements Player {
private static final String[] positions = {
"a1", "h1", "h8", "a8",
"c1", "f1", "h3", "h6", "f8", "c8", "a6", "a3",
"c3", "f3", "f6", "c6",
"d3", "e3", "f4", "f5", "e6", "d6", "c5", "c4",
"d1", "e1", "h4", "h5", "e8", "d8", "a5", "a4",
"c2", "f2", "g3", "g6", "f7", "c7", "b6", "b3",
"d2", "e2", "g4", "g5", "e7", "d7", "b5", "b4",
"b1", "g1", "h2", "h7", "g8", "b8", "a7", "a2",
"b2", "g2", "g7", "b7"
};
@Override
public Point decide(Board board, Color color, long remainingMillis) {
for (String pos : positions) {
if (Rule.canPutAt(board, color, Point.of(pos))) {
return Point.of(pos);
}
}
return null;
}
}
ソースコードを記述したら、[Ctrl + S] キーでソースファイル(MyFirstAIPlayer.java)を上書き保存します。ソースファイルを編集するとタブの先頭にアスタリスク(*)が付きますが、保存することにより消えます。
(4) プログラムをビルドします。
といっても、Pleiades All in One ではソースファイル保存時に自動的にビルドするように設定されているはずです。
[プロジェクト] – [自動的にビルド] にチェックが付いていることを確認してください。
チェックが付いていない場合はチェックを付けてください。
プログラムに文法ミスがあるとビルドは行われません。
「マーカー」ビューにエラー内容が表示されますので、よく見直してソースコードを修正しましょう。
ソースファイルを上書き保存すると自動的にビルドされます。
作成したAIプレーヤーを動かしてみる
それでは早速、作成したAIプレーヤーを動かしてみましょう。
A) 他のAIプレーヤーと対戦させてみる
(1) 「パッケージ・エクスプローラー」ビューの [MyFirstJava] プロジェクトを選択した状態で、メニューの [実行] – [実行] – [Java アプリケーション] を選択します。
(2) 下記のような画面が表示された場合は「Menu – xyz.hotchpotch.reversi.cui」を選択します。
(3) 「コンソール」ビューで reversi が動き出したでしょうか。もしも動かない場合は、「1-4. reversi を動かしてみる」をもう一度確認してみてください。
画面の表示に従って、対話的に入力を行います。
プレーヤー選択時に「0 : その他(自作クラス)」を指定し、作成したAIプレーヤークラスを完全修飾クラス名(パッケージ名.クラス名)で指定することにより、自作クラスを動かすことができます。「mypackage.MyFirstAIPlayer」と入力しましょう。
対戦相手には、手をランダムに選ぶ「2 : xyz.hotchpotch.reversi.players.RandomAIPlayer」を指定してみました。
制限時間(ゲーム全体の持ち時間)は 1 秒(1,000 ミリ秒)もあれば十分でしょう。
ゲームが始まると思いますので、しばらく動かしてみてください。
・
・
・
お、勝ちました! やったね!!
しばらく色々と動かしてみてください。
プレーヤー選択時に「7 : 手動(自分で手を指定する)」を選択すると、自分自身(人間)がAIプレーヤーと対戦することもできます。
B) 総当たり戦をさせてみた!
reversi のメニューで「3 : 総当たり戦」を選ぶと、複数のAIプレーヤーで総当たり戦をさせることができます。
次の条件で総当たり戦を実施してみました。
- 参加AIプレーヤー : 7 プレーヤー
- 1ゲームあたりの各プレーヤーの持ち時間 : 3 秒(3,000 ミリ秒)
- 1ペアごとの対戦回数 : 10 回
結果は、ナ・ナ・ナント・・・
勝率 55%。うーん、微妙・・・
まぁ初めてのAIプレーヤーですし、こんなものですかね 😕
最強のAIプレーヤーを目指して
ここまで、AIプレーヤーを作成してみましたが、いかがでしたか? 意外と簡単だったのではないでしょうか。今後は是非、自分自身で思考アルゴリズムを考え、色々なAIプレーヤーを作成してみてください。
そのためには、まず Java の文法を知る必要があります。Java 標準ライブラリが提供する様々な機能を利用することで、より高度な処理を簡単に行うこともできます。
その一方で、アルゴリズムに対する理解も深める必要があります。実際のAIプレーヤーの強さを決めるのは、Java プログラミングの巧拙ではなくアルゴリズムであると言っても過言ではありません。
本サイトの題材である reversi プログラムには、いくつかの基本的な思考アルゴリズムを実装したAIプレーヤーが同梱されています。これらのアルゴリズムは、リバーシのみならず、チェスや将棋、囲碁にも通ずるものです。「3-1. AI プレーヤーの思考アルゴリズム」で解説していますので、参考にしてみてください。
また、Java やその他に関する書籍やサイトを「1-6. 書籍&サイトの紹介」で紹介しています。
最強のAIプレーヤーが出来ましたら、ぜひコチラまでお知らせください。
みなさんの挑戦をお待ちしています!