アリAIチャレンジ。 初心者向けガイド

スターターパックに実装されている戦略は、独自のボットを作成するための出発点にすぎません。実際、これらは最悪の戦略の一部です。 同時に、スターターパックには、より良い戦略の開発に役立つ便利な機能が含まれています。 この記事では、一連のパッケージの機能強化について説明します。 完了したステップごとに、ボットがよりスマートになり、評価が増加し始めます。



背景



この記事では、Javaスタートアップパッケージを使用します(翻訳者の注意:ツール(ボットテスターと便利なスクリプトセットが記述されているため、記事の最後にあるリンク)からPythonも必要です)。 ツールも必要です。



インストールする



スターターパッケージ(ボット)とツールを使用するディレクトリを作成します。 次のようなものが得られるはずです。



C:\aichallenge>tree Folder PATH listing C:. +----tools +---mapgen +---maps | +---maze | +---multi_hill_maze | +---symmetric_random_walk +---sample_bots | +---csharp | +---java | +---php | | +---tests | +---python +---submission_test +---visualizer +---data | +---img +---js C:\aichallenge>dir /b AbstractSystemInputParser.java AbstractSystemInputReader.java Aim.java Ants.java Bot.java Ilk.java make.cmd Makefile Manifest.txt MyBot.java Order.java Tile.java tools
      
      







確認する



テストゲームを実行して、すべてが正常に機能することを確認します(OSに応じてシェルスクリプトplay_one_game.cmdまたはplay_one_game.shを使用します)。 ツールの中には、ボットのテストに役立つ「playgame.py」ユーティリティがあります。 その使用は、シェルスクリプトplay_one_game.cmd(play_one_game.sh)に明確に示されています。



ボットをテストするためのシェルスクリプトを作成する



それでは、新しいマップとボットを使用するシェルスクリプトを作成しましょう。



Windowsの場合:tutorial.cmdを作成します

 C:\aichallenge>notepad tutorial.cmd
      
      







Linuxの場合:tutorial.shを作成します

 user@localhost:~$ gedit tutorial.sh
      
      





その後、権利を割り当てます

 user@localhost:~$ chmod u+x tutorial.sh
      
      







私たちはそれに処方します:

 python tools/playgame.py "java -jar MyBot.jar" "python tools/sample_bots/python/HunterBot.py" --map_file tools/maps/example/tutorial1.map --log_dir game_logs --turns 60 --scenario --food none --player_seed 7 --verbose -e
      
      







Javaボットをコンパイルする必要があることを忘れないでください。 両方のボット-およびHunterBotと教科書で再現されたボットが決定されます。 同じ入力で、同じ動きを生成します。 これは、指示に完全に従えば、教科書とまったく同じ結果が得られることを意味します。



シェルスクリプトを使用してボットを起動し、スターターパックのボットがどのように機能するかを見てみましょう。

同様の出力が表示されるはずです。

 running for 60 turns ant_count c_turns climb? cutoff food r_turn ranking_bots s_alive s_hills score w_turn winning turn 0 stats: [1,1,0] 0 [1,1] - 18 0 None [1,1] [1,1] [1,1] 0 None turn 1 stats: [1,1,0] 0 [1,1] - 16 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 2 stats: [2,1,0] 0 [1,1] - 16 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 3 stats: [2,2,0] 0 [1,1] - 15 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 4 stats: [2,3,0] 0 [1,1] - 14 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 5 stats: [2,4,0] 0 [1,1] - 14 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 6 stats: [2,4,0] 0 [1,1] - 14 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 7 stats: [2,4,0] 0 [1,1] - 14 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 8 bot 0 eliminated turn 8 stats: [0,4,0] 0 [0,1] - 14 1 [0,0] [0,1] [1,1] [1,1] 1 [0,1] score 1 3 status eliminated survived playerturns 8 8
      
      







ゲームはわずか8ステップでしたが、これは疑わしいほど高速です。 プレイヤー0(ボット)が破壊されたようです。 ゲームが終了すると、ブラウザはビジュアライザで何が起こったかを表示し始めます。





元のボットの戦略はひどいものであることがわかります。2つのアリを押して、それ自体を破壊しました。 まあ、これは私たちの最初の改善になります。



ステップ1.衝突を避ける



計画


衝突を防ぐには、次を実行します。



実装


アリのいる場所の情報を追跡するには、HashMap構造を効率的に使用します。 このデータ構造はアリの位置を保存し、この位置がすでに使用されているかどうかを確認できます。 各HashMapキー値にはTileオブジェクトが含まれます。 タイル-マップ上のオブジェクトの位置を持つオブジェクト。 キーは提案されたステップの位置であり、値は現在の位置です。 この方法で、2つのアリが同じポイントに行かないことを確認する手順を実行する前にHashMapをチェックできます。 移動するたびに、HashMapを更新します。

このチェックはチュートリアルの後半で役立つため、特定のステップが可能かどうかをチェックする関数を作成します。 ブール値(trueまたはfalse)を返します。



コード


元のボットのコメントを省略して、新しいコードを投稿します。

 public boolean doMoveDirection(Ants ants, HashMap<Tile, Tile> orders, Tile antLoc, Aim direction) { // Track all moves, prevent collisions Tile newLoc = ants.getTile(antLoc, direction); if (ants.getIlk(newLoc).isUnoccupied() && !orders.containsKey(newLoc)) { ants.issueOrder(antLoc, direction); orders.put(newLoc, antLoc); return true; } else { return false; } } @Override public void doTurn() { HashMap<Tile, Tile> orders = new HashMap<Tile, Tile>(); Ants ants = getAnts(); for (Tile myAnt : ants.getMyAnts()) { for (Aim direction : Aim.values()) { if (doMoveDirection(ants, orders, myAnt, direction)) { break; } } } }
      
      





doMoveDirection



関数は、蟻の位置(タイルオブジェクト)と方向(目的オブジェクト-N | E | S | W)を取得し、ステップの完了を試みます。 この関数はdoTurn



関数の外側にあるため、注文にAntsおよびHashMapオブジェクトを指定する必要があります。 ボットから事前定義されたいくつかの機能を使用します。

ants.getTile(Tile, Aim)



は、位置(Tileオブジェクト)と方向(Aimオブジェクト)を受け入れ、新しい位置(Tileオブジェクト)を返します。 彼女はカードのロックを引き受けてくれるので、心配する必要はありません。

ants.getIlk(Tile)



-位置(Tileオブジェクト)を取り、 ants.getIlk(Tile)



オブジェクト(指定された位置のマップポイントのタイプ)を返します。 次に、 isUnoccupied()



オブジェクトのisUnoccupied()



関数を呼び出して、移動できることを確認します。

Ilk.isUnoccupied



は位置を受け入れ、この移動が可能かどうかをIlk.isUnoccupied



ます。 これは、以前のIlk.isPassable



よりも優れています。これは、食物や他のアリをIlk.isPassable



ことができないためです。

-注文済みのHashMapは、計画されたステップを追跡するために使用されます。 if



式では、条件!orders.containsKey(newLoc)



は、指定されたキーの存在を確認し、衝突を回避するのに役立ちます。



結果


最後に、ボットを再度起動し、何が起こったのかを確認します。

 C:\aichallenge>tutorial.cmd running for 60 turns ant_count c_turns climb? cutoff food r_turn ranking_bots s_alive s_hills score w_turn winning turn 0 stats: [1,1,0] 0 [1,1] - 18 0 None [1,1] [1,1] [1,1] 0 None turn 1 stats: [1,1,0] 0 [1,1] - 16 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] turn 2 stats: [2,1,0] 0 [1,1] - 16 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] ... turn 60 stats: [1,5,0] 0 [1,1] - 12 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1] score 1 1 status survived survived playerturns 60 60
      
      











より良いが、それでも悪い。 1匹のアリだけが出てHunterBotと戦うが、自殺は避けた。これはすでに改善されている。 さらに、補助機能を作成しました。これは将来便利になります。



参照資料



スターターパックはこちらにあります

Linux / MacOS 用のWindows用ツール。

翻訳された記事: Antsチュートリアルステップ1:衝突の回避



PS Javaアプリケーションがサイトに表示されるようになりました(ステップ1で完了しました)ので、今のところ、最初のステップの最後まで翻訳し終えました。

PPS翻訳が気に入ったら、次のステップにJavaの例を追加しながら翻訳を続けます。

PPPS招待してくれた未知のHabr友人と、一般的な閲覧のために記事を提出する機会に感謝します。



All Articles