daruma3940の日記

理解や文章に間違い等あればどんなことでもご指摘お願いします

Codingame_Amadeusチャレンジにっき

Codingame Amadeusチャレンジ

ルール

目的:ゲーム終了時に相手よりも多くの惑星をコントロールする。
ーーーーーーーーーーーーゲーム

このゲームは、惑星を頂点としたグラフ上で行われます。
両方のプレイヤーはできるだけ多くの惑星を支配しようとします。
プレイヤーが相手よりも惑星に多くのユニットを送っている場合、惑星はそのプレイヤーの色の星に変換され、
その支配下にあるとみなされます。
各プレイヤーは、グラフの反対側にあるそれぞれの支配下にある惑星にから出発します。

ーーーーーーーーーーーーユニット
毎ターン:
あなたは5人のユニットに命令をする必要があります
すでに少なくとも一人のユニットのいる惑星とあなたがコントロールしている惑星の隣にユニットを送れます
あなたは隣接の惑星の数に関係なく、任意の惑星にいる5人のユニットを選んで犠牲にし1人のユニットをその惑星の隣に生成することが出来ますユニットスプレッドと呼ばれます(良く分からん)

ーーーーーーーーーーーー
一つの惑星には各プレイヤー5回だけしかユニットを送る操作が出来ません.
許容値はユニットスプレッドの影響を受けません。

ーーーーーーーーーーーー
近隣の惑星に自分がコントロールしている惑星よりも相手がコントロールしている惑星のほうが多い場合
その惑星のユニットは一人失われます

ーーーーーーーーーーーー制約
16<= planetCount <=90
10<= edgeCount <=200
最初のターンの応答時間<= 1000ms
1ターンあたりの応答時間<=50ms
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
研究室の後輩がプログラムのコンテストに興味を持ったらしく
とりあえずCodingameを勧めた。
人にこういうの勧めるのあんまり良くないなと思っていて。
自分が他人に何か勧められても「はいはいそれでマウント取りたいだけでしょ。絶対やんねー」ぐらいにしか思わないので。
その後輩に今回のコンテストを教えた結果、「出ます!」とのこと。他人に勧めておいて自分が出ないのはゴミなのでとりあえず出る

~~~~1日目

とりあえずサンプルを動かしてみてゲームの性質を眺める。
こんな感じのボードになっていた。
f:id:daruma3940:20180723222204p:plain

なるほど
緑のノードを取られてしまうとそこから下は相手のものになってしまうのか。
重要なノードがあるんでそこを死守しなければならないって感じのゲームですか。

とりあえず惑星に重要度をつける。
重要度はその惑星を取り除いたときにどれだけ到達できる惑星の数が変化するか+alphaでつけた。(alphaが何だったのかもう覚えていない...)
ページランクアルゴリズムはどうだったんでしょうね。

これで重要な惑星は絶対死守するプログラムを書いたが、
盤面には次のような盤面も含まれていた。
重要なノードをとってる間にもっと大きな空間で優勢を取られるケース。
f:id:daruma3940:20180723222710p:plain
直線的になっていて重要なノードだと認識してしまうノードばかりになってしまうケース。
f:id:daruma3940:20180723222720p:plain
なるほど。

こういうのと前線を守ったりするのを適当なifelseで処理(どんな処理だったのかもう思い出せない..)したらsilverランクに上がれた。

とりあえず探索をしたいんですよね。したいんだけど愚直な探索では50msという制約ではTLEするだろう
できないところはあきらめながらでもなんとか50msで探索できる効率的な方法はないか???

そこで思いついたのが指し手GA Softmax

ーーーーーーーーーーーー
最初の指し手生成
貪欲手法を3つ用意する

自分の領土を出来る限り広げようとする

自分の領土を出来る限り守ろうとする

重要な惑星を出来る限り確保しようとする



これら3つの貪欲手法にしたがって複数の自分の指し手を作成しそれらの指し手を評価する

ーーーーーーーーーーーー指し手の評価方法

それぞれの自分の指し手に対して
相手の指し手を3つの貪欲手法にしたがって複数用意する。

それらの動きで盤を更新してそれぞれに対して自分が支配している惑星の数を数える。

自分の支配している惑星の数の最小をこの自分の手の評価にする
しかしこれで重要なノードをちゃんとまもろうとするのか怪しいので評価関数はその辺考慮していじくる必要はありそう


ーーーーーーーーーーーー新しい指し手の生成

次にこのleafに訪れた場合
一番スコアの良い指し手を突然変異させる、または交配させることによって新しい指し手を作ってその指し手を評価し、
最善スコアを超えるかどうかをする。

もし指し手の数が一定に達した場合は最善だった指し手と相手の応手を用いて盤面を更新してツリーを深化させる。


ーーーーーーーーーーーーnodeの選び方

ノードの選び方は末端の評価値に末端までの遠さの割引項をかけて確率的に選択する(ボルツマン分布的)


なんかかっこよく聞こえるしうまくいきそうじゃない?

最初の貪欲指し手生成で強い指し手を生成できたほうがもちろん良いのでifelseベースの行動で強いのを作れないといけないし、まだユニットスプレッドを理解していないのでそれもちゃんと把握しないといけない
大変だなぁ。
まあ明日からやっていこうかなと思ったところで1日目終わり

~~~~2日目
後輩氏は進捗発表と院試の勉強で忙しいらしく参加は厳しいらしい。
まあそうですよね。私も研究あるしゲーム作る機運が高まっていたので終了(は?)。


ーーーーー感想戦(初日しか参加してないが)



にゃるほど

コドゲは相手の戦略が見えるので対策を立てられてしまうため強い人は潜伏する傾向が強いみたいですね




にゃるほど

ykawano.hatenablog.com


にゃるほどしか感想がでないのかよ