このトピックは、Google AIチャレンジ用にボットを作成するためのガイドの最初の2つの部分の翻訳です。
すべてのコードはPythonで書かれています。
ステップ1:衝突を避ける
計画
アリが衝突しないようにするために必要です:
1)あるアリが別のアリに移動するのを防ぎます。
2)同じポイントで2つのアリの動きを防ぎます。
3)すべてのアリの居場所を追跡します。
実装
アリの位置に関する情報を追跡するために、辞書(別名HashMap、連想配列、JavaScriptオブジェクト)を使用します。 配列の各キーは位置になり、値はこのポイントに移動するアリです。 場所は、マップ上の行と列の2つの値のタプル(リスト、配列)になります。 次に、移動する前にリストを確認して、2つのアリが同じ場所に移動しないようにします。 アリを移動するたびに、リストを更新する必要があります。
このチェックはマニュアルの後半で役立ちますので、このステップが可能かどうかをチェックする関数を作成します。 論理値(trueまたはfalse)を返します。
コード
例のコードからコメントを切り取り、新しいコードを新しいコードに貼り付けます。
def do_turn(self, ants): # track all moves, prevent collisions orders = {} def do_move_direction(loc, direction): new_loc = ants.destination(loc, direction) if (ants.unoccupied(new_loc) and new_loc not in orders): ants.issue_order((loc, direction)) orders[new_loc] = loc return True else: return False # default move for ant_loc in ants.my_ants(): directions = ('n','e','s','w') for direction in directions: if do_move_direction(ant_loc, direction): break
(注:インデントが正しいことを確認してください。Pythonでは、インデントはコードとスコープのブロックを定義するため、インデントは正確でなければなりません)
Do_move_direction関数は、アリの位置(タプル(行、列))と方向( 'N'、 'e'、 'S'または 'W')を取り、移動を実行しようとします。 この関数は、クラスメソッド(関数でもあります)内にあり、これはPythonでは正常です。 (別の言語で記述する場合、関数を別の場所に配置する必要がある場合があります)最初のボットからいくつかの定義済み関数を使用します。
ants.destinationは場所と方向を取得し、目的地を返します。 この関数は、地図の端を越えるアリの動きを処理します。それについて考える必要はありません。
ants.unoccupiedは場所を受け入れ、アリをそこに移動できるかどうかを判断します。 これはants.passableよりも優れており、食物や他のアリに移動することはできません。
オーダーの連想配列は、現在の動きを追跡するために使用されます。 new_locの使用状況と、orders配列に存在しないことを確認すると、衝突を防ぐのに役立ちます。
結果
もう一度ボットを実行して見てみましょう。
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
繰り返します: http : //aichallenge.org/ants_tutorial_step_1.php
すでに優れていますが、それでもあまり良くありません。 一人のアリが出てきて、HunterBotと戦った。 これは自殺ではなく、改善です。 さらに、後で便利になるヘルパー関数を作成しました。
ステップ2:食料を集める
計画
勝つには2つ以上のアリが必要です。アリの開始位置の近くに食べ物があります。 組み立ててみましょう。 それを集めるためにアリを食物に移動させなければなりません。 また、これを効果的に行いたいです。 前回のゲームで、HunterBotがすべてのアリの半分を餌に送ったことに気づきましたか? これは非効率的なようです。
優先度キューに似たものを実装します。 すべてのアリのリストを作成し、各食事からどれくらい離れているかを確認します。 次に、リストを並べ替えて、各アリを最も近い食べ物に送りますが、1つの食べ物には1つのアリだけを送ります。 他のアリは自由になり、他の重要なことをします。 また、開始ボットから残っている愚かなデフォルトの動きを取り除きます。
実装
アリがすでにフォローしている食物情報を追跡するには、別の配列が必要です。 キーとしてターゲット食品の位置を格納し、値としてそれに続くアリの位置を格納します。 ターゲットキーをチェックして、同じ食べ物に2つのアリを送っていないことを確認できます。 別のヘルパー関数を作成して、わずかに異なるタイプの動きを作成します。 アリの位置と方向の代わりに、アリの位置とターゲットの位置を決定し、関数が方向を決定します。
コード
do_move_direction関数の後に次の関数を作成します。
targets = {} def do_move_location(loc, dest): directions = ants.direction(loc, dest) for direction in directions: if do_move_direction(loc, direction): targets[dest] = loc return True break else: return False
ターゲット配列はアリを追跡し、その目標は食物です。 別の標準ボット関数を使用して、次のことを支援します。
ants.directionは、現在の場所とターゲットを取得し、最も近い方向のリストを直線で返します。 ターゲットが左上にある場合、['N'、 'W']が返されるので、アリをこれらの2つの方向のいずれかに移動しようとする必要があります。 ターゲットが真下にある場合、['S']-1つの要素のリストを返します。
移動機能をこれに置き換えます:
# find close food ant_dist = [] for food_loc in ants.food(): for ant_loc in ants.my_ants(): dist = ants.distance(ant_loc, food_loc) ant_dist.append((dist, ant_loc, food_loc)) ant_dist.sort() for dist, ant_loc, food_loc in ant_dist: if food_loc not in targets and ant_loc not in targets.values(): do_move_location(ant_loc, food_loc)
ここにリストがあります-ant_dist-アリごとに食物と距離の組み合わせをタプル(distance、ant_loc、food_loc)として保存します。 リストはネストされたループで構築され、各組み合わせを提供します。 次に、リストをソートします。 Pythonリストには、便利なソート関数がいくつかあります。 タプルをソートするために、Pythonは各タプルの最初の値を比較し、それらが同じ場合は2番目の値に進みます。 そのため、最短距離がリストの最初になるように、距離を最初の値として保存しました。
次に、ソートされたリストのサイクルで、食物を収集できる無料のアリがあるかどうかを確認します。 Food_locがターゲットにない場合、食品に既に続いているアリがあるかどうかをチェックします。 targets.values()にないAnt_locは、アリにまだタスクが与えられていないことを確認します。 アリが見つかった場合、do_move_locationを呼び出します。
結果
もう一度ボットを実行して見てみましょう。
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: [1,1,0] 0 [1,1] - 16 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1]
...
turn 60 stats: [4,6,0] 0 [1,1] - 6 1 [0,0] [1,1] [1,1] [1,1] 1 [0,1]
score 1 1
status survived survived
playerturns 60 60
繰り返し: http : //aichallenge.org/ants_tutorial_step_2.php
私たちが見ることができるすべての食べ物は捕獲されました。 繰り返しを注意深く見ると、蟻塚にはまだ表示できない3匹のアリがいることがわかります。 将来的にはこれを処理する方が良いでしょう。 アリが出ない場合、彼らは私たちが勝つのを助けることができません。
オリジナル:
PSこの記事がサンドボックスを通過する間、 webkumoは同様の記事を公開しました。 彼の記事には、Antsチュートリアルとステップ1:衝突の回避が含まれています。これは、ステップ1:衝突の回避とステップ2:食料の収集です。