CodinGame デバッグ補助手法
現在CodinGame(以下コドゲ)ではFall Challenge 2020が開催されていますが、
コドゲ独自の仕様で詰まっている人が多そうなので、取り急ぎ解説を書き殴ってみます。
目次
デバッグ表示
ゲーム中に内部情報を表示してデバッグしたいこと、ありませんか?
表示しましょう。
サンプルコードに何か書いてますね。(下のはC#です)
// To debug: Console.Error.WriteLine("Debug messages...");
エラー出力することでデバッグメッセージを出力できるようです。
ゲームの説明にも何か書いてますね(下のはFall Challenge 2020です)
Append text after any command and that text will appear next to your witch
コマンドの後に何か書くとゲーム画面にメッセージを表示できるようです。
最近のコンペ形式のゲームではほとんどこうなっていると思います。
下の画像は、実際に出力してみた例です。
できました。
ゲームの再現
既存のゲームをIDEで動かして誤動作の原因を探りたいこと、ありませんか?
再現しましょう。
自分のローカルIDE上(VisualStudioとか)で動作するプログラムに
ゲームの標準入力の内容を流すと、ゲームを再現できます。
標準入力の内容は対戦結果には含まれていないので、
標準入力を受け取った際にそのままエラー出力に流してやりましょう。
(少し上の、エラー出力によるデバッグ表示がその例です)
コピペには少し手間取るので、全コピーした後に上手く置換するか
ユーザースクリプト等で一括取得できるようにすると捗ります。
標準入力以外の自分のデバッグメッセージと混ざらないように注意。
私は自分のデバッグメッセージは"@ "で始めるルールにして識別しています。
再現性を確保するため、以下の事に気を付けましょう。
・乱数のseedを固定する
・時間いっぱい回すタイプであれば回した回数を記録しておき、それも再現する
・その他、実行する度に結果が変わるコードを書かない
時間の計測
制限時間いっぱい探索して最適手を探したいこと、ありませんか?
計測しましょう。
プログラミング言語毎の時間計測ライブラリについては省略しますが、
私はC#ではSystem.Diagnostics.Stopwatch()、
C++ではstd::chrono::system_clockとstd::chrono::millisecondsを利用しています。
AIのソースコードはなんとなく次のようになっているはずです。(例はC#)
while(true){
// 入力
string input = Console.ReadLine();
// ぼくの考えた最強の処理
string command = GetCommand();
// 出力
Console.WriteLine(command);
}
時間計測コードは何処に挟んでも良さそうな気がしますが、
ゲームサーバを介して複数のAIが動く関係上、空白の時間が存在します。
今回はゲームサーバから見た自分のプログラムの応答時間を知りたいので、
[入力を受け取った直後]~[出力を返す直前]の区間で処理時間を計測しましょう。
while(true){
// 入力
string input = Console.ReadLine();
// ※ここで時間計測開始
// ぼくの考えた最強の処理 ※時間を見て処理を打ち切る
string command = GetCommand();
// ※ここで時間計測終了
// 出力
Console.WriteLine(command);
}
こんな感じですね。
なお、出力してから次の入力までの間にゲームサーバや対戦相手が何らかの処理を回す空白時間があるのですが、この間はCPUを割り当ててもらえないため、この間に自分も裏で探索を進めるということは出来ないようです。
ソース:コドゲのフォーラムの何処か 思い出したら貼る
とりあえずは以上。
分からないことがあればコドゲのチャットやTwittterなどで聞いてみましょう。