codingameに初参加した話

 codingame参加記です。
 codingameというサイトで、10日間でAIの強さを競うコンテストに参加しました。今回のタイトルはbotters_of_the_galaxyで、LoLの一つのレーンを持ってきた感じです。codingameの特徴として、ある程度強くなるにつれてルールが解放されていろいろな要素が追加されていきます。が、今回はルールを全部解放するまでは手間取らなかったのでその辺の話はパスします。
 あまり詳しく覚えていないのでノリで流れを書きます。

最初の数日

 ルールがクソ複雑なのでしんどいなと思いながら読むと、実質LoLであることに気づき、読解が楽になる。チャンピオン5体から2体選んで戦うということで、そのあたりからめんどくささが漂っている。しかも、アイテムやスキル(各チャンピオン3つ)、ミニオンのラストヒットや中立モンスターなども用意されているので、いろいろと険しい気持ちになるが、とりあえず実装できるところから始める。
 まず、使うチャンピオンを選ぶ必要があるが、とりあえず長距離射程が強いのではという軽い気持ちで射程のながい二体を選ぶ。スキル的にはADCとheal supportという感じなのでbot laneぽくてよさそうと感じた。とりあえずまともにミニオンを攻撃するようにしたり、あまり突っ込まないようになどと初歩的なことを書いてから、ラストヒット書いてみたり、スキル適当に打ったりしてみる。割と上位のほうにいた気がする。

中盤

 とりあえず、ラストヒット精度がとても重要なのでシミュレーションを少し走らせつつ、ラストヒットを取りに行く。ミニオンよりもヒーローのほうがattackspeedが速くなるように設定されているので、射程内にいてかつ相手よりも近くてかつ一撃で倒せるミニオンのラストヒットは必ずとれる。また、そうじゃないときも移動しながら攻撃することで、時間を少しずらしてラストヒットをとるなどのテクニックがある。この後にバグが次々と見つかったので初期のはわりとひどかったっぽいけどまぁぱっと見た感じではいい感じに動いていた。この辺で他の人よりも時間を割いていたこともあり、一位争いに加わり、割と一位のあたりにいるようになる。
 順序は忘れてしまったけれど、この辺りでは暗殺系の敵への対策とか、スキルとかの処理もチョコチョコ書いていた気がする。暗殺系の敵に対するコツとしては、相手の自分を強化する系のクールダウンが増えていたら撤退することとか、タワーの下でできるだけ時間を稼ぐこととか、shieldを張れるヒーローを少し後ろに下げておいて、もう一方のヒーローを守るようにするとか。また、アイテムはdamageを優先して取るとラストヒットがとりやすくなって、manaとかmanaregenとかとるとfireballが強くなるのでfireball適当に投げてたら勝てる。fireballに当たるの割と痛いので、適当に左右にチョコマカ動く処理を付け加えたりする。暇なときに中立を刈る処理とかも書いた気がする。
 いろいろと処理があるので、優先順位が大切になってくるが、大まかなノリとしては、最初に安全確認して、突っ込めるときは突っ込んで、そのあとにスキルを打つべきかどうか判断して、ラストヒットできるか判断して、そのあとは適当に動くという感じ。
 立ち位置が本当に難しくて、ちょっとでも相手のスキルコンボとかに引っかかったり、相手のミニオンの中に引っ張られたりすると一気にHPが削れてしまうのでそこが最後まで難しかった。ミニオンとかタワーとかに重みを付けて、距離に応じて評価したりしてたけど、周りの人はもうちょっとうまくしていそうな感じだった。

終盤

 周りが本気でやり始める時期なので、徐々に後退を始めてしまう。暗殺系の人たちが、ミニオンもうまく刈るようになったのでただ安全にプレイしてるだけでは負けるようになったし、中立にスキルでダメージを与えてこっちにターゲットを向ける技とかでてきたし、そもそも普通にいろいろと精度が高くて勝てなくなった。
 bushを利用して暗殺系の攻撃をかわすようにしたり(相手がbushに突っ込むのを予測して逃げるのとか割と効果あった)、中立ミニオンをかわす処理を書いたり、逆にこっちも中立ミニオンを利用する処理を書いたり、バグをつぶしたり、ラストヒットのシミュレーションの精度をあげたりしていた。最も時間をかけたのは、相手のスキルに引っかかってHPを削られないためにはどのように立ち回ればいいのかだったが、これが本当に最後までよくわからないままになってしまった。当然、ラストヒットを積極的に狙うとスキルで引っ張られて一気にHP削られて終わるし、ラストヒットを消極的にして安全にしているとラストヒット数で負けるので難しい。最終順位は日本9位世界86位。いいんだか悪いんだかという感じだが、まぁLegendには到達したので及第点という感じがする。

感想

 途中は割と一位で独走していた時期もあったので楽しかったが、最後のほうに次々と抜かれていくのは割とhogeだったのでhugaになってしまった。割とシミュレーションをサボってしまっていたので、そのあたりをもっとしっかりと書いたりするべきだったが、ルールの実装を読むのを面倒くさがってしまったのでよくない(攻撃範囲内にいるときにどの対象を攻撃するかはシミュレーションしていたが、動く部分とかはすべて無視していた)。こういう系のコンテスト、大まかな作戦とかももちろん大事だけど、なんだかんだで最終的に強いのは細かい処理をちゃんと書いているほうなので(多分)、次に真面目に取り組むときはこういう処理をサボらないようにしようという気持ちになった。が、これ本当に時間が融ける上に終わった後の何やってた感が多少否めないので次回参加するときは慎重になりそう。

 この後オープンコンテストになるようなので、ソースコードは張らないほうがいいということで張りません。大体2000行ぐらいです。余談ですが、途中でリファクタリングという名の定数に名前つけたり短くできる処理を短くしたり、関数化を細かくしたりなどの作業をしたら、ものすごく作業効率が上がったので、偉大だなぁと思いました。しかし、まぁ目の前に書きたい処理があったら殴り書きしますよね…