いちごくん

競技プログラミングの話をしたり

CodinGame Spring Challenge 2022 参加記

CodinGame Spring Challenge 2022 参加記

 

CodinGame というサイトの Spring Challenge 2022 というゲームAIコンテストに参加した結果、7695(参加登録のみでは18288)人中199位になることができました。

いえーーーい

 

というわけでこの記事では今回の僕のコンテストの様子を追体験してもらいながら「コドゲって面白そうだなぁ」と思ってくれれば幸いです

 

目次

 

 

そもそもコドゲって何?

簡単に行ってしまえばCodinGame(以下コドゲ)は自分が作ったゲームAIを他の人が作ったゲームAIと戦わせて誰が最強か決めようぜ!といった大会です。

ゲームAIを書いて提出すると下の画像のように自動的に他の人のゲームAIと対決してくれ、その結果からよくある対戦ゲームのレート戦のように自分のゲームAIにレートが付けられ、順位付けされます。

 

 

また、コドゲには「リーグ」と呼ばれるものがあり、最初はWood2リーグから始まり各リーグのBOSSより上のレートになる(要はそのリーグで1位になる)と上のリーグに昇格できます

今回参加したSpring Challenge 2022は10日間開催されており、この期間内に自分のAIを強化して上のリーグを目指すなり上位入賞を目指すなり頑張るといったコンテストとなっております。

ちなみに今回一番上のLegend Leagueまでたどり着いたのは390人だったようです。

 

ゲームルール

というわけでコドゲのコンセプトを理解したところで、「じゃあ具体的にどんなゲームするんだよ」って気になると思うので今回のゲームルールを確認していきましょう。

と言っても百聞は一見に如かず、対戦動画を見たら何となくわかると思います。

 

対戦動画

 

簡単に言葉で説明すると1対1の対戦ゲームで、3人の人間を動かしてモンスター(虫みたいなやつ)を相手陣地に入れた方が勝ちってゲームです

人間は一ターンにつき以下の4つの行動ができます

MOVE : 800マス以下の範囲で動く。

WIND : 1280マスの範囲に居るモンスターと敵を指定した向きに2200マス飛ばす

SHIELD : 指定した相手にシールドを張る。12ターンWINDとCONTROLを受けなくなる。

CONTROL : 指定した相手の次のターンの行動を操作する。モンスターを操作した場合、モンスターはその時指定された向きに以降も歩き続ける。

 

人間がモンスターの800マス以内に居る時、人間はモンスターにダメージを与え、"マナ"を獲得できます。

WIND,SHIELD,CONTROLを使うには10マナ消費する必要があります

 

というのが大雑把なルールです

細かいルールが知りたい人はツカモ様がルールの日本語訳記事を書いてくれているのでそちらを見ると良いです。

ツカモ様の記事

 

Bronze Leagueまで

Wood2,Wood1リーグはチュートリアル的なポジションで、メッチャ簡単なプログラムさえ書ければBronze Leagueまで行けます

今回はWIND,SHIELD,CONTROLは使う必要なく、ただ自陣の近くに来たモンスターのとこまで歩いていけば問題ないです

こんな感じ

めっちゃ単純でかわいいね

 

Silver Leagueまで

まだ簡単。

ちょっとだけWINDを使って防衛できるようになればBronze Leagueは突破できた

イメージ的には毎回Silverまではちょっと実装能力があればたどり着けるので、ちょっとでもプログラミングできる人は次回のコドゲに挑戦してみて欲しいかも(?)

こんな感じ

 

ここまで到達した時点ではTOEICがあったため本腰を入れて取り組むことができず、ここまででコンテスト終了まで残り3日となっていた。

「このままじゃ上位いけないな、頑張らないとなぁ」と思い、以下の計画を実行する

このツイートの通り、金曜(土曜とも言う)夜3AMからコンテスト終了日の昼12時までほぼ研究室に引きこもりコドゲ以外何もしないという暴挙に出た。

いちごちゃんの戦いはここから始まる!!!

Gold Leagueまで

流石にまともにプログラムする必要がある。

具体的にはいままでは守ってるだけで良かったけど攻撃役を用意しWIND,SHIELD,CONTROLを駆使して敵陣にモンスターを押し込む必要が出てくる。

研究室に引きこもってからなんやかんや3時間ほどプログラミングをして、以下の戦略でSilver Leagueは突破できた。

こんな感じ

まだまだかなり単純で、序盤はマナをためてある程度溜まったらCONTROLをモンスターに打ちまくって相手にモンスターを押す付けるというもの

まだまだ拙い部分もたくさんあるがとりあえずこれでSilver Leagueは突破できた

 

Legend Leagueまで

鬼門。

ここまではお遊びに過ぎない。

ぶっちゃけGold Leagueまではまともに動くアルゴリズムを実装さえできればたどり着けるんですが、Goldを突破してLegendにたどり着くにはいよいよ一戦一戦のゲーム内容や環境を研究して強い戦略を練る必要がある。

 

僕もいろいろな戦略を立ててみた

・CONTROLとWINDを使って適切にシュートを試みるコード

・適切なモンスターにSHIELDを使って敵のWINDを無効化し対応不可にするコード

・WINDを使いモンスターを相手と押し付け合い、敵のマナを枯渇させるコード

・敵にコントロールを打ち対応不可にするコード

その他にも効率の良いマナ稼ぎ、強くマナ効率が良い防衛方法、敵にWINDやCONTROLを使われたときの対処法など細かい修正を加えた結果、日曜夜12時頃、ようやくボスに9割くらい勝てるコードが完成した。

こんな感じ

 

が、このコードではGold League 50位前後が関の山で、Legend Leagueに到達できない

なぜか

それは次の動画を見て欲しい

この動画

なにこれ(笑)

これは通称「ロマン砲」と呼ばれる戦略で、複数人でWINDを打つと飛距離が加算されることをいいことに序盤にマナを溜めるや否や、圧倒的パワーでモンスターを押し付けてくる戦略である。

コンテスト終盤、このロマン砲がGold League上位で跋扈しており、性能の良いロマン砲が性能の悪いロマン砲を駆逐するという地獄絵図となっていた。

Legend Leagueに行くにはこのロマン砲を対策するか、自身もロマン砲に魂を売るかのどちらかをしないといけない環境だったのだ。

 

さて、このロマン砲、最強の戦術かと言われると実はそんなことはない。複数人で攻撃するには当然防衛が手薄となる。すなわちロマン砲を打ってる間にこちらが攻め込んでしまえばこの戦術は崩壊するのである。

ということでロマン砲対策を埋め込み提出してみた

こんな感じ

こうして晴れてLegend Leagueに到達できました!よかったね

 

感想

今回のゲームは正直かなりジャンケンの要素が強かった

具体的には

ロマン砲

・マナファーミング(僕はこれに当たる)

・1攻撃2守り型

これらが上からグー、チョキ、パーの関係にあり、明確に戦術同士の相性が存在した。

しかし、順位を上げるのに大切なことは「自分がチョキの時にどれだけパーへの勝率を気づ付けることなくグーにワンちゃん勝てるようになるか」と感じる。実際僕のコードはロマン砲と戦ってもある程度の勝率を確保できるようになったときにLegendへ上がることができた。

どうやったら自分に不利な相手を倒せるか、どうやったらより有効な攻撃ができるかを考察し、実装し、対戦するのは非常に楽しく、研究室に籠っていた三日間熱中して取り組むことができました。

CodinGame様、楽しいコンテンツをありがとう、次回も頑張ります!!

 

おまけ

最終コードの戦術

【防衛】

モンスターの数と自陣付近の敵の数に合わせて0~2人で防衛し、防衛していないときはマナ集め。尚敵が攻めてきたときは基本的には2人防衛。

モンスターは自陣に着くギリギリまでは攻撃してHPを減らし、WIND以外で対応できなくなったらWINDを打つ。

敵が来ている時は必ず1人が敵をマークし、敵のWIND圏内にモンスターが入った時はWINDを打ちシュートを決められないようにする。

【マナ集め】

防衛役は自陣付近、攻撃役は敵陣付近でマナ集めを行う。

可能な限り複数のモンスターを同時攻撃できた方が良いためモンスターが重なる場所を探索し、そこを目指してマナ集めするように動く。

序盤は敵陣に向かうモンスターを優先的に狩り、中盤以降は自陣に向かうモンスターを優先に狩る

【攻撃】

45ターン目、または相手がロマン砲を作っていると判明すると1人敵陣へ突っ込みWINDを使って攻撃する。敵が1人の時はCONTROLを使ってこの1人を拘束する。敵が2人見えたらロマン砲ではないためマナ集めへ戻る。

十分マナアドバンテージが取れると1人敵陣へ向かう。

敵陣付近でうろうろし、敵陣に入りそうなモンスターにCONTROLを打つ。そして敵陣4700マス地点にモンスターが到達した時、人がその前方1100マスに立ち、二連続WIND(WIND射程が1280マス、WINDで飛ぶ距離が2200マスのため適切な位置に人がいると2回WINDを当てて4400マス飛ばすことができる)を打てるようにする。

十分なHPを持ち敵陣近くに居るモンスターにSHIELDを打つ。

モンスターが3体以上溜まり、敵防衛が2人居る時、敵2人に交互にWINDを打つことによって敵2人を拘束する。