# ターン結果画面に「なぜそうなったか」を動的表示する——静的テキストとの決別
「結果は出ているのに、なぜそうなったか分からない」
初回本番のアンケートで最も多かった声だ。数字は表示されている。利益がいくら、シェアが何パーセント、自己資本が何万円——。でも「なぜ」が見えない。
ターン結果画面の「今ターンの着目点」は、改善前こうなっていた。
const insights = [
'',
'DX投資の効果はまだ出ません。今の順位より「何に投資したか」を意識してください。',
'DX投資の効果が少しずつ出始める頃です。全社比較でスピードスコアの差を確認しましょう。',
// ...以下略
];
const insightText = insights[r.turn_no] || '';
ターン番号に対応した固定テキストだ。ターン1なら「まだ効果が出ません」、ターン2なら「少しずつ出始める頃」——。参加者の実際のゲーム状態とは無関係に表示される。
これは「インサイト」とは呼べない。ただの定型文だ。
動的インサイトの設計
問題は明確だった。「ターン番号」ではなく「実際のゲーム状態」に基づいてメッセージを出すべきだ。
では何を見ればいいか。APIはすでに以下のデータを返していた。
price_score:価格競争力スコアholding_cost:在庫保管費unmet:在庫不足による機会損失speed:スピードスコア(DX自動化の蓄積)accounting_profit:当期純利益dx_data_cum:L1 IT基盤の累積値(新規追加)
これらに閾値を設定して、条件に合致したメッセージだけを表示する設計にした。
const lines = [];
if ((r.price_score||0) > 1.1)
lines.push('💰 価格競争力が高く、販売数量が伸びました');
else if ((r.price_score||0) < 0.85)
lines.push('⚠️ 価格が市場平均より高く、競争力が低下しました');
if ((r.holding_cost||0) > 50)
lines.push(`📦 在庫過多で保管費 ${Math.round(r.holding_cost)}万円が利益を圧迫しました`);
if (unmetQty > 5)
lines.push(`🔥 需要 ${Math.round(unmetQty)}個分が在庫不足で販売できませんでした`);
if ((r.speed||0) > 1.25)
lines.push('⚡ 業務DXの蓄積でスピードが向上し、競争力に貢献しました');
if (dxThisTurn)
lines.push('🎉 このターンにDX変革を達成!競争スコアが×3.0になります');
条件に合うものだけが表示される。何も引っかからなければフォールバックメッセージが出る。
historyエンドポイントへの新フィールド追加
動的インサイトを実現するには、APIがより多くのデータを返す必要があった。
従来のhistoryレスポンスにはunmet(機会損失数量)が含まれていなかった。またDX成熟度の累積値も不足していた。
results.pyに追加したフィールドは6つ:
"dx_data_cum": dx_map.get(r.turn_no, {}).get("dx_data", 0.0),
"dx_auto_cum": dx_map.get(r.turn_no, {}).get("dx_auto", 0.0),
"dx_sales_cum": dx_map.get(r.turn_no, {}).get("dx_sales", 0.0),
"dx_decision_cum": dx_map.get(r.turn_no, {}).get("dx_decision", 0.0),
"unmet": float(r.unmet or 0),
"online_ratio": float(d.online_ratio) if d else None,
CompanyDXテーブルはターンごとのDX累積値を持っていたが、historyに含まれていなかった。このデータを取り出してhistoryに追加した。
「なぜ」が分かると何が変わるか
実装後、テスト環境でゲームを走らせてみると、インサイトカードにはこんな文章が並んだ。
📦 在庫過多で保管費 73万円が利益を圧迫しました
⚠️ 価格が市場平均より高く、競争力が低下しました
これが出た参加者は「在庫を減らすか、価格を下げるか」を考える。数字を見るだけより、格段に思考が促される。
逆に:
💰 価格競争力が高く、販売数量が伸びました
⚡ 業務DXの蓄積でスピードが向上し、競争力に貢献しました
が出た参加者は「この戦略を続けよう」と確信できる。
「なぜそうなったか」を見せるだけで、研修の質が変わる。 データがあってもそれを解釈する補助がなければ、多くの人はただ数字を眺めるだけで終わる。
静的テキストから動的インサイトへの移行は、技術的には小さな変更だった。でもユーザー体験としては大きな違いだ。
このアプローチは他の業務システムにも応用できる。ダッシュボードに「前月比マイナス10%」と表示するだけでなく、「在庫回転率の低下が主因です」と添えるだけで、意思決定の速度が変わる。