当プログラミングコンテストのミッションは相手のスタート位置にたどり着いた後、 自分のスタート位置に戻ってくることです。 しかもそれを相手ロボットより早く成し遂げなければ勝てません。 ただ対戦相手が存在した状態だと動作確認がやりにくいので、 ここまでは対戦相手を使ってませんでした。
対戦させてみるには、まずシミュレータの「対戦ロボットを動かす」にチェックをいれます。
チェックを入れるとロボット選択ボタンが有効になります。
ロボット候補が出てくるので、どれかを選んで対戦させます。
ロボット選択ボタンを押した時に、自分で作ったロボットも一覧に出るようにしてみましょう。 やり方はここに書きましたが、念のためおさらいです。
まずはソリューションの構成を Release にします。
そして実行もしくはビルドメニューからソリューションのビルドを行います。
すると x64\Release\EsagonaleFlag.dll が新しくなります。
適当に名前を変えておきます (この例では サンプル.dll という名前にしてます)。
そして bin\dll にコピーします。
対戦ロボット B にサンプル.dll が現れるので読み込んで対戦してみることができます。 マップ a25x70_level01.txt〜a25x70_level08.txt で戦わせてみてください。 同じ頭脳なのに先行が勝ったり後攻が勝ったり様々です。 どちらの陣地を取るか地形が非常に重要なことが分かるでしょう。
次にマップ a25x70_level09.txt を動かしてみてください。 正面衝突してお互いに動けなくなります。
実は相手が 5 ターン以内に通ったタイルは通れないというルールが存在してます。 ルール的に通れないのです。 もちろんそのタイルが通れるか通れないかロボットは gSurTiles を通して 知ることができます。 WAKEBLOCK とのアンドを取るのです。 とりあえず、目の前が通れなかったら右を向くようにしてみましょう。
if (AvoidMode==1) { 〜〜〜コード 9.8 参照〜〜〜 } else if (AvoidMode==2) { 〜〜〜コード 9.6〜〜〜 } else { if (gSurTiles[0] & OBSTACLE_TILE){ NaviCmd(0,2); AvoidMode=1; } else if (gSurTiles[0] & WAKEBLOCK) NaviCmd(0,1); else if ((gSurTiles[1] & NEXTFLAG_TILE) || (gSurTiles[8] & NEXTFLAG_TILE)) NaviCmd(0,1); else if (isTgtAhead()) NaviCmd(1,0); else NaviCmd(0,1); } |
前が通れないと分かったので右旋回するようになりました。
ところで相手側は旋回していません。 これは相手側の制御プログラムはコピーした時点でのアルゴリズムだからです。 自分のプログラムはコード 10.1、相手のプログラムはコード 9.8 のままです。 だから自分のロボットは旋回し、相手は直進しようとして失敗しているのです。 次のターンでは自分は前進し相手は動けていません。
これは 5 ターン以内に相手が通ったタイルは通れないというルールからです。 今この状態で自分の足跡は次の通りになってます。
相手ロボットにとって、目の前のタイルは対戦相手が 1 ターン前 (2 ターン前でもある) に通った所です。 そのため進行できないのです。 この状態は後 4 ターン続きます
そして次のターンで初めて進行できるようになります。
よく観察するとそういったことはあちこちで起こっていることが分かります。 次の図はマップ a25x70_level06.txt での 1 シーンですが、相手の動きを見事ブロックしています。
上手い戦略を立てると相手の動きを邪魔して試合を有利に運べます。 どういう動きをさせれば良いかいろいろ考えてみてください。
コード 10.1 ですが、めったに起こらないかもしれませんが 障害物回避モード中に正面衝突したら動けなくなります。 障害物回避モードの処理はコード 9.8 のまま手を加えてないので 前進できるかどうか調べてないからです。 手を加えれば対処できます。
あまりどのように書き加えればいいか詳しく書くと、 コンテストの意味が無くなってしまうので書きませんが多分正面が通れないなら右旋回 だけだとダメでしょう。 右旋回して前進すると障害物から離れてしまうからです。 いろいろ工夫してみてください。