Codingame「Spring Challenge 2021」に参加しました。
前回はGold Leagueまで行けたので、今回はLegend League入りを目標にしました。
結果は、195位/ 6867人で、なんとかLegend Leagueに入れました!
目標達成できたので嬉しいのですが、今回はLegendの人数が多かったこともあり、やや微妙な気持ちもあります。
(ツイートした通りですが)私がやったことは、適当に評価値を作って、「Possible moveの中で評価値が一番高いのを選ぶ」というだけです。
本当は、
・評価値を作る→探索する(たとえば二手後の評価値を調べる、など)→やっぱり時間制限が厳しいから他の言語に書き換え
のようにする予定だったのが、最初のステップで終わってしまった感じです。それはちょっと悲しいですね。
ただ、元々今回は、「評価値を頑張りたい」という気持ちが強かったです。
前回のCodingameに参加した経験で、終了後に他の方の参加記を読むと、探索以前に、ゲームへの考察が不足しており、評価関数にまだまだ改善すべき点があったことが分かりました。今回はその点では後悔したくない、と思っていました。
それに、良い評価関数を作ることは、後で探索を行う場合でも枝狩りに役立ったり、無駄にはならないはず、と。
その点に関して言うと、他の方の参加記を読んでもそこまで考察不足だった、と感じる点はなかったので良かった。
あと、
koyumeishiさんの記事を参考にローカルでの実行環境を作れたのは良かったです。前回はローカルでの実行環境を作れなかったので……。100回とか300回実行して、勝率が高い方を選ぶ、というのができ、このおかげで評価関数を調整できました。
この、ローカルで実行しながら色々パラメーターを調整している間に暇な時間があったんですよね。その間に探索を実装したら良かったのですが……。サボってしまった。
次回は考察した上で、探索も実装したいですね!(NNを勉強するのは無理そうですが、普通の探索は)
評価値について
ツイートしたことをもう少し詳しく書きます。
・最初の五日は(どこにseedするか以外)他の人の真似をしています。
・250*score、100*sun
最終的に1 point = 3 sunになるので3:1を目安にしました。ただ、sunが多いことが(特に序盤は)重要なのでこの値に。
なお、score pointが重要になるのは後半なので、9日目までは0、10~19日目は上記の値、20日目以降はこの二倍にしています。
・木のsize別値を[5,115,245,420]として、(23-day)*本数*size別の値
後者の式は、日が経つほどにscore(COMPLETE)の重要性が増すことからこうしました(日に関する一次関数で良いのかには議論があるだろうけど)。
その後、ローカル対戦により調整したのが、この木の評価値です。たくさん自己対戦を行い、一番勝率が高そうなものを選んだというだけで、あまり根拠はありません。
・翌日~六日後に影がかかってsunがもらえない場合に-(7-day)*10*size
六日後まで見て、(現状のままだと)陰に入ってsun pointが得られない場合にマイナスポイントをしました。
・自分の木同士が長さ3の線分範囲にある場合10*そういう木の本数分マイナス
上位陣の対戦を見て、桂馬に木を配置しているのを見て、評価値に組み込みました。自分の木同士で陰になるのは避けた方が良いので。
・Richnessを補正(+Richness*1)
木を植える場所はRichnessが高いところになるようにしました。ただ、陰に入るか、という方が重要なようだったので、気持ち程度の補正です。