tsukammoの収穫記

上下左右の更地にアルゴリズムを

codingame:SUMMER CHALLENGE 2025 ルール要約

これはなに?

お題のゲームを解くプログラムを各自が作成、サイト上に提出して順位を競い合うゲームAIコンテストCodinGame「SUMMER CHALLENGE 2025」について、ルール要約を紹介します。
※記載内容の保証はし兼ねるので、自己責任で読んでください。
コンテストページ:https://www.codingame.com/contests/summer-challenge-2025-coderpad-play
コンテスト期間:7月17日~7月28日

ルール説明

※以下はBronzeリーグのルールです。wood4~1は下記のアクションが順次開放されるチュートリアルとなっています。

勝敗

グリッド上であるエージェントに指示を出し制圧する2人対戦ゲームです。各プレイヤーが同時に指示を出し、相手より600ポイント多く獲得するか敵エージェントを全て排除したプレイヤーの勝利です。

行動

指示するエージェント
各プレイヤーは自身のエージェント毎に指示を出すことができ、最大で1つの移動アクションと1つの戦闘アクションが可能です。出力順序は自由ですが、処理順は後述する順序で固定です。

MOVE x y
移動アクションです。エージェントは場所 (x, y) に移動しようとします。エージェントは1ターンに1マス移動可能であり、2マス以上離れた場所の場合、最短の有効なパスを自動的に求め1マス分移動します。移動先がカバーブロックがある、または別のエージェントがいる場合、移動はキャンセルされます。また、エージェント同士が MOVE しようとして衝突した場合、それらの移動はキャンセルされます。
HUNKER_DOWN
戦闘アクションです。身をかがめて、このターンの敵からの射撃に対するダメージを25%軽減します。これは後述するカバーブロックと重ねがけできます。
SHOOT id
戦闘アクションです。指定したidの敵エージェントを射撃しようとします。与えられるダメージは後述する射撃するエージェントの optimal range と soaking power、ターゲットのエージェントが得るダメージ軽減(HUNKER_DOWNアクションや射線上のカバーブロック)によって決定されます。
THROW x y
戦闘アクションです。指定したタイル (x, y) の位置に爆弾を投げようとします。爆弾はエージェントから最大4タイル離れた場所まで投げられます。着弾したタイルと斜めを含めた隣接する9つのタイルにいる全エージェントに30のダメージを与えます。このアクションはカバーブロックとHUNKER_DOWNによるダメージ軽減を無視します。

入力情報の説明

初期入力

各ゲームの最初に、以下の情報が与えられます。
1行目:あなたのプレイヤーID
2行目:グリッド上のエージェントの数
各エージェントについて6つの入力:

  • agentId: このエージェントの一意のID
  • player: このエージェントを所有するプレイヤーのID
  • shootCooldown: このエージェントが次の射撃を行うまでに待機する必要がある最小ターン数
  • optimalRange: このエージェントの最適な射撃範囲
  • soakingPower: このエージェントの最大ウェットネスダメージ出力
  • splashBombs: このエージェントが利用できるスプラッシュボムの初期量

次の行:グリッドのサイズである2つの整数widthとheight。 グリッドのサイズ幅 (width 12~20マス) と高さ (height 6~10マス) ※左上を (x, y) = (0, 0) とし、visualizer上の横方向を x、縦方向 y で表します。 各タイルについて3つの入力 x: X座標(0が最も左)、y: Y座標(0が最も上)、tile_type

  • 0 空のタイル
  • 1 低いカバー
  • 2 高いカバー

ターン毎の入力

各ターン毎に以下の入力が与えられます。
1行目:グリッド上に残っているエージェントの数 各エージェントについて6つの入力:

  • agentId: このエージェントの一意のID
  • x: X座標(0が最も左)
  • y: Y座標(0が最も上)
  • cooldown: このエージェントが再び射撃できるまでの残りターン数
  • splashBombs: このエージェントが利用できる現在のスプラッシュボムの量
  • wetness: エージェントの現在のウェットネス

次の行:プレイヤーが操作するエージェントの数

エージェントの持つパラメータ

wetness(ウェットネス)
各エージェントはウェットネスを持っており、敵エージェントから攻撃されると上昇します。エージェントのウェットネスが100に達するとゲームから除外されます。
soaking_power(パワー)とoptimal_range(レンジ)
次にsoaking_powerとoptimal_rangeについて、パワーは通常与えるウェットネスの量を示し、レンジはターゲットが遠すぎる場合にペナルティを適用するために使用されます。
マンハッタン距離でoptimal_range以内の位置の敵は、射撃によって soaking_power の100%のダメージを与えます。 次に optimal_range の2倍以内までは、射撃によて soaking_power の50%のダメージを与えます。 それを超えると射撃は失敗と判定されます。
shoot_cooldown(クールダウン)
shoot_cooldownは、射撃後に再度SHOOTできるまでの待機ターン数です。この間も他のアクションを使用できます。
splashBombs(爆弾数)
最初に設定された数の爆弾を投げることができます。数は増えません。

バーブロックについて

グリッドの tileType が1(低いカバー) or 2(高いカバー)の場合、カバーのあるタイルとみなします。カバータイルは通行不能です。
カバーの上下左右に隣接するエージェントは、敵の射撃がカバータイルの反対側から来る場合にダメージを軽減します。低いカバーは50%、高いカバーは75%のダメージを軽減します。 例えば、エージェントのレンジ内で、パワーが24のエージェントでも、高いカバーの背後にいる敵には6のダメージしか与えられません。 ただし、両方のエージェントがカバーに隣接している場合、この軽減は無効となります。複数のカバーが考慮される場合、最も高いカバーのみがカウントされます。

ポイントの獲得について

敵のエージェントよりも、あなたのエージェントのいずれかにより近いタイルは、あなたの支配下にあると見なされます。ただし、エージェントのウェットネスが50以上の場合、そのエージェントまでの距離は2倍に換算されます。相手よりも広いエリアを支配している場合、そのタイル数の差分をポイントとして獲得します。

各ターンの実行順序

  1. MOVEアクション
  2. HUNKER_DOWNアクション
  3. SHOOTとTHROW
  4. ウィットネスが100以上のエージェントをゲームから除外

その他ジャッジコードから読み取れる内容

ジャッジコードは以下です。
https://github.com/CodinGame/SummerChallenge2025-SoakOverflow

グリッドサイズの生成ロジック
グリッドの高さ (height) を 6~10 から一様ランダムで決めた後、その2倍の値が幅 (width) となります。
グリッド上のタイルは10% が高いカバー、もう10% が低いカバー、残りが空のタイルとなります。

エージェントの生成ロジック
エージェントは3~5体が一様ランダムで決定された後、5体の時に1/2で-1体にされ、さらに4体の時に1/2に-1体されます。
エージェントの初期位置は全て左側の壁に隣接するマスからランダムに決定されます。
エージェントの能力はパターンが決まっており、以下となっています。
GUNNER:クールダウン 1、パワー 16、レンジ 4、爆弾数 1
SNIPER:クールダウン 5、パワー 24、レンジ 6、爆弾数 0
BOMBER:クールダウン 2、パワー 8、レンジ 2、爆弾数 3
ASSAULT:クールダウン 2、パワー 16、レンジ 4、爆弾数 2
BERSERKER:クールダウン 5、パワー 32、レンジ 2、爆弾数 1

ゲーム攻略『ユニコーンオーバーロード』のストーリー中の編成紹介

前回記事に続いて、任天堂SWITCHなどでプレイ可能なシミュレーションRPGユニコーンオーバーロード』(公式ページ)をプレイした際の編成紹介記事です。ゲーム内容や感想、プレイ方針については前回記事を参照ください。
ゲーム中の基本的な用語は、既知のものとして説明を割愛させていただきます。ストーリーには触れませんが、それ以外の要素は大体触れてしまうのでネタバレOKな方のみ続きをご覧ください。

続きを読む

ゲーム感想『ユニコーンオーバーロード』をプレイして

任天堂SWITCHなどでプレイ可能なシミュレーションRPGユニコーンオーバーロード』(公式ページ)をプレイした感想記です。

書こうと思った動機

本ゲームの特徴として、シミュレーションの面倒なコマンド選択を省略するオート戦闘と、その作戦を組むガンビット(後述)が挙げられます。非常に良いシステムなのですが、仕様が複雑かつ正確な挙動が説明だけでは読み取れず、各攻略サイト等にも載っていなかったため、やりたい事ができるのかどうかの検証に苦労しました。面白いコンボ等もできるので、備忘も兼ねて文字に起こそうと思いました。
なお、具体的な仕様説明や編成例は次の記事とし、本記事はその導入のためのゲーム紹介とプレイ感想です。

続きを読む

一緒に働きま賞。(AtCoder 第二回マスターズ選手権 -決勝- で九位入賞しました。)

下記の日時に開かれた競技プログラミングコンテスト、AtCoder「第二回マスターズ選手権」の備忘録です。

  • 予選:2025/03/02(日) 13:00 ~ 19:00 (360分)
  • 本戦:2025/04/19(土) 11:10 ~ 17:10 (360分)

第二回マスターズ選手権 名札

結果

予選:61/145位、本戦:9/50位でした。※有効回答者のみカウント。
昨年のに引続きオンサイト出場 & 入賞ができ、たくさんの方と出会えた記念に参加記を書きます。
※昨年の第一回マスターズ選手権の参加記はこちら

続きを読む

AHC のジャッジコードを流用して作る visualzer作成(AtCoder 第二回マスターズ選手権 -予選- )

はじめに

AtCoder Heuristic Contest (AHC) において、結果を素早く確認したり、途中経過を可視化することは、より良い成績を取るために重要です。
通常の AHC では、web版の visualizer が提供されていますが、欲しい機能を拡張したい思いに駆られる事があります。また、昨年より実施されている「マスターズ選手権」では、visualizer の提供がされないため自作する必要があります。

visualizer の自作の際は、なるべく時間をかけずミス無く作成したいものです。 それを叶えてくれるのが、偉大なる先人の yunixさんの方法です。この方法は公式のジャッジコード + React を用いることによって、生成される入力データとスコアの正しさが保証されている visualizer を楽に作成することができます。
yunix-kyopro.hatenablog.com

しかし、この手法だとローカルサーバを都度起動する必要があり、ひと手間かかります。必要なのはジャッジコードの Rust を wasm化して、それを表示する html と JS があれば良いはずです。
そこで、本記事では AtCoder 第二回マスターズ選手権 -予選- のコンテスト中に実際に行った内容をベースに、ローカルファイルとして visualizer を作成する方法を紹介します。
* 第二回マスターズ選手権-予選-:2025/02/02(日) 13:00 ~ 19:00 (360分)

実際に作成した visualizer

前提

  • 公式からRustのテスターや入力ジェネレーターは提供されるものとします。
  • visualizer を表示するブラウザは chrome を用います。
  • windows環境での説明です。
  • メインとなる状態の可視化部分は、問題固有の実装が必要です。
  • なるべく再現できるようハンズオン形式で説明しますが、環境の違い等で異なる事象が発生する可能性は高いです。都度自身で調べられる方を対象としています。※LLM(AI)に聞くとかなり精度高く対処方法を教えてもらえます。

この手法で作成する visualizer の特徴

メリット

  • 普段の AHC の web版ツールに近い感触のものができます。
  • 変更時にF5でページ更新するだけで反映されます。
  • ローカルファイルを扱えるため、ファイルアップロード不要で出力内容を自動ロード可能です。

デメリット

  • 後述するCORS回避が必要です。
  • yunixさんの方法と同じく、Rust の wasm化に関してある程度の理解が必要です。※LLM(AI)に聞きながらで十分可能です。
続きを読む

codingame:WINTER CHALLENGE 2024 ルール要約

これはなに?

お題のゲームを解くプログラムを各自が作成、サイト上に提出して順位を競い合うゲームAIコンテストCodinGame「WINTER CHALLENGE 2024」について、ルール要約を紹介します。
※記載内容の保証はし兼ねるので、自己責任で読んでください。
コンテストページ:https://www.codingame.com/contests/winter-challenge-2024
コンテスト期間:12月20日~1月7日

ルール説明

※Bronzeリーグのルールです。wood4~1は下記のルールが順次開放され、その効果のチュートリアルとなっています。

勝敗

グリッド上である生物の器官の生成を指示する2人対戦ゲームです。各プレイヤーが同時に指示を出し、100ターン経過した時点でよりたくさんの生物器官を保持しているプレイヤーの勝利です。

行動

各プレイヤーは生物の ROOT (根)タイプの器官毎に指示を出すことができ、以下のコマンドで既存の器官から、隣接する空きマスに新しい器官を生成することができます。
GROW id x y type direction
※指定した id の器官から、x, y の位置に新しい器官 type を生成します。目標位置が id の隣接マスでない場合、器官は x, y への最短経路上に生成されます。向きの指定が必要な場合、方向 direction (上=N、右=E、下=S、左=W)を指定します。

器官を生成するためには、器官毎に指定のタンパク質が必要です。グリッド上のマスにはタンパク質源(ABCD)が配置されており、そのマスに器官を生成させることでそのタンパク質を3つ得ることができます。新たに生成された器官は、生成元の器官と親子関係となります。

入力情報の説明

各ゲームの最初に、グリッドのサイズ幅 (width 16~24マス) と高さ (height 8~12マス) が与えられます。左上を (x, y) = (0, 0) とし、visualizer上の横方向を x、縦方向 y で表します。
次に毎ターン以下の情報が与えられます

各グリッド上の物体

各マスに存在する物体情報が与えられます。大きく3種類の物体が存在します。

  • 壁:侵入不可なマスです。破壊手段もありません。
  • 器官:自身か相手の器官です。器官があるマスには侵入不可となります。
  • タンパク質:器官を生成するための栄養です。ABCDの4種類が存在し、侵入可能なマスです。

各器官の説明

生成可能な器官は全部で5種類存在します。それぞれの生成コストは下図の通りです。

ROOT(根)

  • ゲーム開始時に1つの ROOT (根) 器官が与えられます。
  • 後述する器官を用いることで、新たな ROOT (根) を産み出すことができます。

BASIC (基本器官)

  • 基本的な器官です。特別な効果はありませんが、生成に必要なタンパク質が少ないです。

HARVESTER (収穫器)

  • タンパク質に隣接して生成することで、毎ターン対象のタンパク質を1つずつ得ることができます。
  • 1つのタンパク質に複数の HARVESTER を設置しても、得られるタンパク質はプレイヤー毎に1つです。

    TENTACLE (触手)

  • 対峙する相手の器官を攻撃し、死滅させることができます。

  • 攻撃は同時に行われるため、TENTACLE 同士が向き合うと共に死滅します。
  • 親の器官が死滅した場合、その子供の器官も連鎖的に死滅します。
  • 相手の TENTACLE の攻撃範囲に新たに器官を生成することはできません。

SPORER (胞子嚢)

  • 新しい ROOT (根)を産むことができる唯一の器官です。
  • 向いている方向に一直線に胞子を発射し、指定のマスに新しい ROOT (根)を産み出すことができます。
  • 発射された胞子は壁か器官にぶつかるまで飛ばすことができ、タンパク質があるマスは通過可能です。
  • 産み出された ROOT (根)は独立した器官であり、親子関係を持ちません。

各ターンの実行順序

  1. GROW と SPORE のアクションが実行される。
  2. 同じマスに同時に器官を生成された場合そのマスは壁になる。
  3. タンパク質の収穫が計算される。
  4. 触手の攻撃が計算される。
  5. ゲームオーバー条件 (不正な出力 or 100ターン経過) がチェックされる。

出力

各プレイヤーは保有する ROOT (根) 毎に以下のいずれかの指示を1行で出力する必要があります。
ただし、各指示で「ROOT (根) またはその子供の器官」を指定した場合、再度その「ROOT (根) またはその子供の器官 」を指定することはできません。※ROOT (根) 毎に一度しか指示を出すことができません。

GROW id x y type direction
指定した id を持つ器官から、x, y の位置に type の新しい器官を作ろうとする。ターゲット位置がidの近傍でない場合、臓器はx, yへの最短パス上に作成される。
SPORE id x y
指定した id を持つ SPORER (胞子嚢) から、一直線上の x, y の位置に新しい ROOT (根) を産み出そうとする。
WAIT
何もしない。

その他ジャッジコードから読み取れる内容

ジャッジコードは以下です。
github.com

グリッドサイズの生成ロジック
グリッドの高さ (height) を 8~12 から一様ランダムで決めた後、その2倍の値が幅 (width) となります。
以下に続くグリッド上の生成物は 75% が点対称で生成され、25% が y 軸に対して線対称で生成されます。

壁の生成ロジック
グリッドのマスの数に対して生成する壁マスの数を 0~50% から一様ランダムで決めます。
全てのマスから一様ランダムでマスを決め、壁マスとし、対称のマスにも同じく壁マスを生成します。
最後に、到達不可能なマスが存在した場合、その周囲の壁は除外します。

タンパク質の生成ロジック
グリッドのマスの数に対して生成するタンパク質の数を 0~25% から一様ランダムで決めます。
全てのマスから一様ランダムでマスを決め、対称のマスにも同じタンパク質を生成します。
タンパク質は A→B→C→D の順序で生成されます。つまり、D のタンパク質だけ他より数が少ない等が起こり得ます。

初期 ROOT (根) の生成ロジック
グリッドの角 (0, 0) マスから、x 方向、y 方向共に 0~3 から一様ランダムで決めた数だけ進んだマスと、その対称マスに ROOT (根) を生成します。

初期に保有するタンパク質数の生成ロジック
4種類のタンパク質毎に3~10個から一様ランダムで決めた数だけタンパク質を保有します。両プレイヤーに差は生じません。

codingame:SUMMERF CHALLENGE 2024 ルール要約

これはなに?

お題のゲームを解くプログラムを各自が作成、サイト上に提出して順位を競い合うゲームAIコンテストCodinGame「SUMMER CHALLENGE 2024」について、ルール要約を紹介します。
※記載内容の保証はし兼ねるので、自己責任で読んでください。
コンテストページ:https://www.codingame.com/contests/summer-challenge-2024-olymbits
コンテスト期間:6月11日~6月25日

ルール説明

※Bronzeリーグのルールです。wood1、wood2は下記「ハードル競争」のみとなります。

勝敗

3人のプレイヤーが4つの競技を同時に競い、スコア(各競技の順位に応じてもらえる得点の乗算値)を競います。100ターン経過した時点のスコアの高さに応じて最終順位が決まります。
各競技の得点は、1回のゲーム毎に1位に3点、2位に1点、3位に0点が与えられ、その合計となります。同着の場合、高い方の点数が与えられます。(同率1位は3点)
なお、スコアは4競技の乗算のため、ひとつでも0点の競技がある場合は最終スコアは0点となります。

行動

ターン制で行われます。各ターンプレーヤーは UP、DOWN、LEFT、RIGHT の4つのアクションのいずれかひとつを出力します。 出力に応じて各競技毎に対応した行動を取ります。
※1ターン1つの出力が、同時に4つの競技に反映されるということです。

競技

競技は「ハードル競争」「アーチェリー」「スピードスケート」「飛び込み」の4つです。

ハードル競争


この競技は30個のスペースで構成されたレーストラック上にランダムに生成されたハードルを飛び越えながらゴールを目指すものです。
ハードルを上手く飛び越えられなかったプレイヤーはハードルと同じスペースで停止した上に2ターン気絶し、気絶中は行動不能になります。

本競技では、4つのアクションは以下の行動となります。

  • UP:1つ先のスペースを飛び越えます。合計2スペース分前進します。
  • LEFT:1スペース分前進します。
  • DOWN:2スペース分前進します。
  • RIGHT:3スペース分前進します。

1人のプレイヤーがゴールに到達すると、その時点でそのレースは終了し、現在地点に応じて順位が決まり、次のレースが開始されます。

ハードルの生成について
最初のハードルはスタート地点から4~8スペース目に生成・ハードルの合計数は3~6台・ハードル間は3 or 4スペースの空きを設ける。以上が全てランダムに決まります。

アーチェリー


各プレイヤーはx座標とy座標を持つカーソルを操作します。毎ターン、 各プレイヤーは上下左右の方向を選び、その方向の現在の風の強さの数値分だけカーソルが移動します。
指定ターン経過後、プレイヤーは同時に矢を放ちユークリッド距離で座標(0,0)に近い順に順位が決まります。

初期座標の決定について
XY座標それぞれ±5~9が初期位置としてランダムに決定されます。※つまり中心から必ず(5,5)以上離れた状態です。

風の強さの決定について
まず、12~15ターンがランダムに決定されます。
その後、各ターンについて以下の確率で風の強さが決まります。

スピードスケート


長さ10スペース分の周期的なコースでレースを行い、15ターン経過後進んだスペース数に応じて順位が決定します。各プレイヤーは0から5までのリスク値を持ちます。
各ターンでは、4つのアクションの文字リストがランダムな順番で提供されます。(例:ULDR(UP,LEFT,DOWN,RIGHTの意)) これをリスクオーダーと呼び、出力したアクションがオーダーの何番目かに応じて、進むスペースとリスクが変化します。

  • 0番目:1スペース前進し、リスクは1減少します。
  • 1番目:2スペース前進し、リスクは変化しません。
  • 2番目:2スペース前進し、リスクは1増加します。
  • 3番目:3スペース前進し、リスクは2増加します。

アクションの後、プレイヤーが対戦相手と同じスペースにいる場合、両者のリスクは2ずつ増加します。また、プレイヤーのリスク値が5以上になった場合、そのプレイヤーは次の2ターンの間気絶し、リスクは0にリセットされます。
リスクオーダーは毎ターンランダムに決定されます。

飛び込み


プレイヤーは飛び込み開始時に与えられる一連のアクションの文字リスト(ダイビングゴールと呼ばれる)をなるべく一致させて下さい。
プレイヤーの出力したアクションが、このターンのダイビングゴールと一致したターン毎に、プレイヤーは現在のコンボ倍率に等しいポイントを獲得します。コンボ倍率は1から始まり、アクションが一致するターンが連続するごとに1ずつ増加します。また、プレイヤーのアクションがダイビングゴールと一致しなかった場合、コンボ倍率は1にリセットされます。

ダイビングゴールの決定について
まず、12~15ターンがランダムに決定されます。
その後、各ターン毎に4つのアクションから毎回ランダムに1つのアクションがゴールとして選ばれます。

入力情報サマリ

今回は競技毎に同じフォーマットで異なる意味合いの入力情報が与えられます。わかりにくいので一覧にまとめました。
変数名は元サイトの表記のままとしており、入力情報は対象競技の情報である「GPU」と、各プレイヤー毎の状況を示す「reg」に分かれます。



その他ジャッジコードから読み取れる内容

※今回はジャッジコードが未公開のため、現時点で情報はありません。
2024/06/12 1:00 時点、ジャッジコードが公開されました。
* 今後のリーグで、プレイヤー人数の増加やゲームの増加は想定されていません。