CODE4LIFE
CodinGameの10日間コンテスト。↓こんな感じで薬を作って得点を稼ぐゲームです。
https://www.codingame.com/replay/228356470
世界21位/国内5位でした。日本つよい。
ルール
↑のエリアではサンプル(薬の素)を取得できます。取得する際にはrank1~3を選べて、高ランクであるほど作るのが大変だけど高得点です。
←のエリアではサンプルを解析してレシピにします。不要なレシピはクラウドにアップロードするという形で捨てることが出来ます。なおアップロードしたレシピは敵・味方問わずいつでも再取得できます。
↓のエリアでは薬の材料を取得できます。材料は各種類5つづつ用意されてあり、それを敵味方で奪い合います。
→のエリアにレシピ+レシピに合った材料を投入すると得点になります。薬を作るとA~Eどれかの経験値を得られて、経験値分だけレシピより少ない材料で薬を作れるようになります。
アルゴリズム
ルールベースで処理しました。αβも考えたんですが、ルールベースの強さを超える自信がなかったし、評価関数がどーせヒューリスティックっぽくなるだろうなと思ってやめました。
↑の戦略
シミュレータのソースを見るとどんな種類のサンプルが取得できるかが載ってあったので、とりあえずそれはテーブルとして持っておきました。
ランク毎に平均得点(A)と手持ちの材料+下の材料で何割作れるか(B)を算出して、A*Bが最大になるランクを拾うようにしました。
←の戦略
とりあえず全部解析します。
解析後、手持ちに作れないものがあって、クラウドに得点が高くてかつ作れるものがあったら交換します。
1個でも作れるものがあったら↓に行って、作れなかったら全部アップロードして↑に戻ります。
↓の戦略
まず嫌がらせを優先します。A~Eそれぞれに対して[場にある数-敵の薬を作るのに必要な数]を算出してそれが3~0だったらそれを奪います。(今思えば3はやりすぎだったかも)
嫌がらせが終わったら、得点の高いものから順に材料を集めていきます。作り易い順でもやってみたんですが、何か弱くなったので採用しなかったです。(ここちょっと考察不足)
場にあるものを拾っても作れるものが無くなったら→に行きます。ただし、ここで相手が→に投入する直前で、欲しい材料が戻ってきそうだったら待機します。
→の戦略
何も考えずに薬を作成します。(ちょっとは考えたほうが良かったかも)
全部作成し終わって、手持ちのレシピに作れそうなものがあったら↓に行って、なければ↑に行きます。
反省
終盤何が強いのか分からなくなってしまいました。これは、AgadeさんがGhost in the Cellでやってたことなんですが、シミュレータを作ってローカルで数万回自己対戦して強くなったかどうか判断すべきでした。
そろそろパラメータの自動調整を実装したい。今回もrankの選び方とか嫌がらせの閾値調整とかに無駄に時間取られたので何とかしたいし、常に最強のパラメータを選んでるという安心感が欲しいです。
最後までゲームの肝がよく分かってなかった(考察不足)。後半思考を放棄していたのがダメダメでした。考えることを諦めては勝てるものも勝てません。
CODERS OF THE CARIBBEAN
CodinGameの10日間コンテスト。↓こんな感じで船を操舵して樽を拾ってHPを回復しつつ砲弾・機雷で相手を潰すゲーム。
https://www.codingame.com/replay/212959177
世界11位 / 国内1位 でした。
アルゴリズム概要
3手読みのchokudaiサーチでした。ホントは全探索したかったんですが3隻+3手だと時間的に無理だったので時間管理が楽なchokudaiサーチを採用しました。
1手につき味方全隻のTurnLeft・TurnRight・Faster・Slower・Waitの組み合わせを探索してます。(つまり3隻なら1手が53=125パターン)
探索の結果TurnLeft・TurnRight・Faster・Slowerが選ばれた場合は普通にその通り行動するんですが、Waitが選ばれた場合は、機雷を置いて効果のある場面なら機雷を置いて、それ以外だったら砲撃するみたいな行動をとります。
探索の最中、敵のターンは基本的に流すだけですが、最低限砲撃を避ける・機雷を避けるという行動は取らせるようにしてました。
機雷の置き方
敵の進行方向上に置けるなら置くって感じでした。また、劣勢時に敵が近くに居ない場合は、砲撃しても無駄なので機雷をばらまいてました。
砲撃地点の選び方
基本的には敵の未来位置に対して砲撃するだけです。未来位置付近に機雷が置いてあった場合は爆発巻き込み狙いで機雷を砲撃します。 敵が近くに居なくて自分が優勢のときは機雷の除去に走ります。また、自分より敵に近い樽を見つけたら容赦なく樽を砲撃しました。
評価関数
- ラム量がベース
- 速度が0ならペナルティ
- 味方同士が近づきすぎたらペナルティ
- マップの端に突っ込んだらペナルティ
- 敵のケツに突っ込んだらペナルティ(機雷警戒)
- 速度0の敵に砲弾を飛ばしてたらボーナス
- 樽に近いとボーナス
- 優勢時は敵から離れればボーナス
- 劣勢時は一番ラム持ってる敵に近づくとボーナス
シミュレータのデバッグ
これは前回のCodinGameでもやってたんですが、シミュレーションした盤面と実際の盤面を比較して差異があったらエラーログを飛ばすってことをやってました。これやると、完璧と思ってたシミュレータのバグがボロボロ見つかったので、これやるのは必須と言っていいんじゃないでしょうか?
反省
αβやっても良かったんじゃないか?
3手読む必要が本当に合ったのか?(でも3手読みたい場面があったのは確か)
自殺してラムを生み出す手法は軽く導入しただけだったけど、もっと注力しても良かったかも。