全国オンライン対応受付 平日 9:00-18:00
お問い合わせ

開発記録 / DX経営ゲーム制作記 / Vol.1 構想から立ち上げまで

記事 04

最初のプロトタイプが動いた瞬間

開発には必ず「最初に動く瞬間」がある。

2026-06-02 公開

開発には必ず「最初に動く瞬間」がある。

データベース設計が終わり、APIの骨格を作り、フロントエンドの画面を仮で組んだ。4社のプレイヤーが意思決定を入力すると、サーバーがターン計算を実行し、各社の結果が画面に返ってくる。その瞬間を、私は今でも覚えている。


最初に動かしたのは「計算エンジン」

ゲームの中核は計算エンジンだ。プレイヤーの意思決定を受け取り、市場競争をシミュレートし、各社の財務状態を更新する。この部分をPythonで実装した。ファイル名はturn_engine.py。最終的に3,000行を超えるコードになるが、最初のバージョンは数百行だった。

最初に実装したのは、もっとも単純な計算だ。「4社が同じ条件でプレイしたとき、市場シェアは均等になるか」——均等になった。当たり前だが、これが動いたとき手応えがあった。

次に試したのは「1社だけ価格を下げたとき、シェアが変わるか」——変わった。研修ツールとして機能する予感があった。


「計算」から「ゲーム」になる瞬間

計算が正しいことと、ゲームとして面白いことは別問題だ。最初のバランスは退屈だった。どの戦略を取っても結果が似たり寄ったりになる。

転換点は、DX変革成功時の効果を大きくしたことだ。最初は×1.5だったボーナスを×3.0にしたとき、ゲームの表情が変わった。DX変革に成功した企業が市場を一気に独占し始める。「これだ」と思った。


プロトタイプを家族に体験させた

最初のプロトタイプができた段階で、家族に体験してもらった。仕組みを全く説明せず、ただ「やってみて」と言った。

3ターン目、DXに全投資した会社が破産した。「えっ、もう終わり?」という反応があった。4ターン目、別の会社がDX変革に成功して一気にシェアを獲得し始めた。

「なんでこうなるの?」という問いが出た。このとき確信した。研修として機能する、と。


プロトタイプが教えてくれた課題

プロトタイプを動かすことで、設計では見えなかった課題が見えた。最大の課題は「ターン計算が遅い」ことだった。アルゴリズムの最適化とキャッシュ活用で解決し、最終的にどんな参加人数でも数百ミリ秒以内に完了するようになった。

プロトタイプは粗くて良い。重要なのは、早く動かして、現実と向き合うことだ。

最初のバグとデバッグの過程

プロトタイプが動いた喜びは、1時間後に最初の重大バグで打ち砕かれた。

症状はこうだった。4社でターンを進めたとき、1社だけ市場シェアの計算がおかしい。3社のシェアの合計が100%になっていて、4社目のシェアが0になる。計算ロジックは正しいはずだ。どこがおかしいのか。

まずログを仕込んだ。ターン計算の各ステップで、各社のスコアをprintで出力する。実行してみると、4社目のcompany_idが正しく渡されていない。decisionsテーブルへの問い合わせで、4社目のレコードが取得できていないことが分かった。

SQLを確認する。WHERE句の条件を確認する。ここで原因が見えた。decisionsテーブルへの問い合わせに「AND is_submitted = TRUE」という条件が入っていた。ターン計算をトリガーするとき、先に3社が意思決定を「提出済み」にしていたが、4社目は提出フラグが立っていなかった。

なぜ4社目だけフラグが立っていないのか。フロントエンドの送信ボタンのコードを確認する。「全社が提出したら自動でターン計算を開始する」ロジックに問題があった。提出カウントが3になった時点で「全社提出」と判定する条件が入っていた(参加企業数の初期値が3になっていた)。

修正は簡単だった。参加企業数を動的に取得する1行の修正だ。しかしこのバグを発見するまでに2時間かかった。

AIにデバッグを相談する前に「自分でログを仕込んで原因を絞り込む」プロセスをたどったことは、後から良かったと思う。「どのデータがどこで変わるか」を自分で追跡する過程で、コードの全体像への理解が深まった。AIへの相談は「絞り込んだ後の確認」に使うと効率が上がる。


*次回は「ゲームの『ルール』を決めるのが一番難しかった」*

ターン計算の順序バグ:具体的なデバッグログ

最初に動かした計算エンジンで、ターン1の計算結果が正しいのに、ターン2で突然シェアが0になる企業が出た。症状は再現性があった。必ず2社目のプレイヤーに発生した。

デバッグの手順として、まずAPIログを見た。リクエストは正しく届いている。レスポンスのJSONを確認すると、2社目のmarket_shareフィールドがnullになっていた。計算関数の中でprint文を仕込み、各企業のスコアがどの時点で消えるかを追った。

ターン計算関数の第3行目で、前ターンのスコアをリセットする処理があった。scores = {} で全社のスコアを空にしてから再計算する設計だったが、このリセットが「まだ意思決定を送信していない企業のスコア」も消していた。ターン2で2社目のプレイヤーの意思決定がDBに存在しない状態で計算が走り、スコアが空になっていた。

修正は scores = {company_id: 0 for company_id in active_companies} に変えるだけだった。5分で直った。しかし発見まで1時間かかった。「どこで消えるか」を順番に追うデバッグの基本を、AIとの対話の前に自分でやることの価値を実感した。

*シンプルシステム株式会社 代表 伊藤勝彦*