Spaces:
Running
Running
Download index.html from Peterhe123/CS206_Game: direct link, hf CLI and curl.
- Browser
- Download file 10.9 kB
-
https://huggingface.co/spaces/Peterhe123/CS206_Game/resolve/main/index.html
- Command line
-
hf download hf://spaces/Peterhe123/CS206_Game/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Peterhe123/CS206_Game/resolve/main/index.html
10.9 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <meta name="theme-color" content="#071b45" /> | |
| <meta name="description" content="A free static classroom Sunk Cost game for COMSCI/ECON 206." /> | |
| <title>Sunk Cost Game · COMSCI/ECON 206</title> | |
| <link rel="stylesheet" href="style.css" /> | |
| </head> | |
| <body> | |
| <!-- ============ TOP BAR ============ --> | |
| <header class="topbar"> | |
| <div class="brand"> | |
| <span class="brand-emoji" aria-hidden="true">🪙</span> | |
| <span class="brand-name">COMSCI/ECON 206</span> | |
| <span class="brand-sub">Computational Microeconomics</span> | |
| </div> | |
| <nav class="steps" aria-label="Game steps"> | |
| <button class="step is-active" data-step="1">1 Inquiry</button> | |
| <button class="step" data-step="2">2 Decision</button> | |
| <button class="step" data-step="3">3 Reveal</button> | |
| <button class="step" data-step="4">4 Reflect</button> | |
| </nav> | |
| </header> | |
| <main class="shell"> | |
| <!-- ============ STEP 1 · INQUIRY / LANDING ============ --> | |
| <section class="view" id="view-inquiry" data-view="1"> | |
| <div class="week-badge">Week 3 · Practice Laboratory</div> | |
| <h1 class="hero-title">A wasted cost. <em>Two rational choices.</em></h1> | |
| <p class="hero-sub"> | |
| If money is already gone and unrecoverable, what does a self-interest benchmark | |
| predict — and what will people actually choose? | |
| </p> | |
| <div class="tag-row"> | |
| <span class="tag">Private by design · no server, login, or tracking</span> | |
| </div> | |
| <div class="scenario card"> | |
| <h2>The half-finished project</h2> | |
| <p> | |
| Your company has already spent <strong>$100,000</strong> on Project X, and it is now clearly | |
| underperforming. Finishing it would cost another <strong>$50,000</strong>. The same $50,000 could instead | |
| launch Project Y, whose expected returns are much higher. | |
| </p> | |
| <p class="muted"> | |
| You must allocate the remaining <strong>10 points</strong> (each = $5,000) between | |
| “keep funding X” and “switch to Y.” | |
| </p> | |
| </div> | |
| <div class="roles"> | |
| <article class="role-card" data-role="manager"> | |
| <div class="role-kicker">Role A</div> | |
| <h3>Play the Manager</h3> | |
| <p>You already paid the $100,000. You decide how to spend the next $50,000.</p> | |
| <button class="btn" data-begin="manager">Begin decision →</button> | |
| </article> | |
| <article class="role-card" data-role="advisor"> | |
| <div class="role-kicker">Role B</div> | |
| <h3>Play the Advisor</h3> | |
| <p>Fresh eyes, no sunk cost. You see the same numbers and decide.</p> | |
| <button class="btn" data-begin="advisor">Begin decision →</button> | |
| </article> | |
| </div> | |
| <div class="benchmark card"> | |
| <h2>The self-interest benchmark</h2> | |
| <p> | |
| Because the $100,000 is gone either way, a strictly rational decider ignores it and | |
| puts <strong>all 10 points into Project Y</strong> — <strong>0 into X</strong>. Sunk costs must not drive | |
| tomorrow’s choices. Emotional attachment or loss aversion may produce a different observation. | |
| </p> | |
| </div> | |
| </section> | |
| <!-- ============ STEP 2 · DECISION ============ --> | |
| <section class="view" id="view-decision" data-view="2" hidden> | |
| <div class="week-badge">Step 2 · Decision</div> | |
| <h1 class="hero-title small">Where does the next <em>$50,000</em> go?</h1> | |
| <div class="card decision-card"> | |
| <div class="role-kicker" id="decision-role-kicker">Role A · Manager</div> | |
| <h2 id="decision-role-title">Allocate the next $50,000</h2> | |
| <p class="muted" id="decision-role-copy"> | |
| Drag the slider to split 10 points between continuing Project X and switching to Project Y. | |
| </p> | |
| <div class="slider-block"> | |
| <div class="slider-scale"> | |
| <span>Project X (continue)</span> | |
| <span id="slider-x">5</span> · <span id="slider-y">5</span> | |
| <span>Project Y (switch)</span> | |
| </div> | |
| <input type="range" id="sunk-slider" min="0" max="10" value="5" step="1" aria-label="Allocate points" /> | |
| <div class="slider-bars"> | |
| <div class="bar-x" id="bar-x"><span>X</span></div> | |
| <div class="bar-y" id="bar-y"><span>Y</span></div> | |
| </div> | |
| <div class="money-readout"> | |
| <span id="money-x">$25,000 → X</span> | |
| <span id="money-y">$25,000 → Y</span> | |
| </div> | |
| </div> | |
| <div class="btn-row"> | |
| <button class="btn ghost" data-reset="reset">Reset</button> | |
| <button class="btn" id="lock-decision">Lock decision →</button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ============ STEP 3 · REVEAL ============ --> | |
| <section class="view" id="view-reveal" data-view="3" hidden> | |
| <div class="week-badge">Step 3 · Reveal</div> | |
| <h1 class="hero-title small">What the benchmark <em>predicts</em></h1> | |
| <div class="card reveal-card"> | |
| <div class="reveal-verdict" id="reveal-verdict"></div> | |
| <p class="muted" id="reveal-text"></p> | |
| <div class="reveal-compare"> | |
| <div> | |
| <span class="role-kicker">Rational benchmark</span> | |
| <p><strong>0 points → X</strong> · all 10 → Y</p> | |
| <p class="muted">Sunk cost is ignored.</p> | |
| </div> | |
| <div> | |
| <span class="role-kicker">Your choice</span> | |
| <p><strong id="reveal-your-x">0 → X</strong> · <span id="reveal-your-y">10 → Y</span></p> | |
| <p class="muted" id="reveal-your-verdict"></p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="btn-row"> | |
| <button class="btn" id="to-reflect">See the lesson →</button> | |
| </div> | |
| </section> | |
| <!-- ============ STEP 4 · REFLECT ============ --> | |
| <section class="view" id="view-reflect" data-view="4" hidden> | |
| <div class="week-badge">Step 4 · Reflect</div> | |
| <h1 class="hero-title small">The sunk cost <em>fallacy</em></h1> | |
| <ol class="lessons card"> | |
| <li> | |
| <strong>Only future costs and benefits matter.</strong> Money already spent is gone | |
| whether you continue or stop — it should never tip the scale. | |
| </li> | |
| <li> | |
| <strong>Decision-makers with sunk costs behave differently.</strong> The Manager (who paid) | |
| is systematically more likely to keep funding X than the Advisor (who didn’t), even with | |
| identical numbers. | |
| </li> | |
| <li> | |
| <strong>Good decisions are made from the outside.</strong> Ask: “If I hadn’t already spent | |
| the $100,000, would I still choose X?” If not, cut losses now. | |
| </li> | |
| </ol> | |
| <div class="btn-row"> | |
| <button class="btn" id="restart">Play again ↺</button> | |
| </div> | |
| </section> | |
| </main> | |
| <footer class="foot"> | |
| COMSCI/ECON 206 · Autumn 2026 · Browser-only classroom demonstration · No centralized data collection | |
| </footer> | |
| <script> | |
| (function () { | |
| "use strict"; | |
| const ROLES = { | |
| manager: { | |
| kicker: "Role A · Manager", | |
| title: "You already paid the $100,000", | |
| copy: "You are emotionally invested. Drag the slider to split 10 points between continuing Project X and switching to Project Y." | |
| }, | |
| advisor: { | |
| kicker: "Role B · Advisor", | |
| title: "Fresh eyes, no sunk cost", | |
| copy: "You never paid the $100,000. You see the exact same numbers. Drag the slider to split 10 points between X and Y." | |
| } | |
| }; | |
| const slider = document.getElementById("sunk-slider"); | |
| const barX = document.getElementById("bar-x"); | |
| const barY = document.getElementById("bar-y"); | |
| const moneyX = document.getElementById("money-x"); | |
| const moneyY = document.getElementById("money-y"); | |
| let role = null; | |
| let x = 5; | |
| function showStep(n) { | |
| document.querySelectorAll(".view").forEach(function (v) { | |
| v.hidden = Number(v.dataset.view) !== n; | |
| }); | |
| document.querySelectorAll(".step").forEach(function (s) { | |
| s.classList.toggle("is-active", Number(s.dataset.step) === n); | |
| }); | |
| window.scrollTo({ top: 0, behavior: "smooth" }); | |
| } | |
| function renderSlider() { | |
| x = Number(slider.value); | |
| barX.style.width = (x * 10) + "%"; | |
| barY.style.width = ((10 - x) * 10) + "%"; | |
| moneyX.textContent = "$" + (x * 5000).toLocaleString() + " → X"; | |
| moneyY.textContent = "$" + ((10 - x) * 5000).toLocaleString() + " → Y"; | |
| } | |
| function startDecision(which) { | |
| role = which; | |
| document.getElementById("decision-role-kicker").textContent = ROLES[which].kicker; | |
| document.getElementById("decision-role-title").textContent = ROLES[which].title; | |
| document.getElementById("decision-role-copy").textContent = ROLES[which].copy; | |
| slider.value = 5; | |
| renderSlider(); | |
| showStep(2); | |
| } | |
| function lockDecision() { | |
| renderSlider(); | |
| const verdict = | |
| x === 0 | |
| ? "Perfectly rational — you ignored the sunk cost." | |
| : x <= 3 | |
| ? "Mostly rational — a little sunk-cost pull, but you switched." | |
| : x <= 7 | |
| ? "Strong sunk-cost pull — the spent $100,000 is dragging your decision." | |
| : "Classic sunk-cost fallacy — the unrecoverable $100,000 decided for you."; | |
| document.getElementById("reveal-verdict").textContent = verdict; | |
| document.getElementById("reveal-text").innerHTML = | |
| role === "manager" | |
| ? "You were the <strong>Manager</strong> who paid. Losing $100,000 already, people systematically throw good money after bad. Your choice shows exactly how the sunk cost bends the decision." | |
| : "You were the <strong>Advisor</strong> with fresh eyes. With no sunk cost, the rational benchmark is far easier to reach — exactly why outsiders see it so clearly."; | |
| document.getElementById("reveal-your-x").textContent = x + " → X"; | |
| document.getElementById("reveal-your-y").textContent = (10 - x) + " → Y"; | |
| document.getElementById("reveal-your-verdict").textContent = | |
| x === 0 ? "Textbook rational." : "The sunk cost pulled you."; | |
| showStep(3); | |
| } | |
| document.querySelectorAll("[data-begin]").forEach(function (b) { | |
| b.addEventListener("click", function () { | |
| startDecision(b.getAttribute("data-begin")); | |
| }); | |
| }); | |
| document.querySelectorAll("[data-reset]").forEach(function (b) { | |
| b.addEventListener("click", function () { | |
| slider.value = 5; | |
| renderSlider(); | |
| }); | |
| }); | |
| slider.addEventListener("input", renderSlider); | |
| document.getElementById("lock-decision").addEventListener("click", lockDecision); | |
| document.getElementById("to-reflect").addEventListener("click", function () { | |
| showStep(4); | |
| }); | |
| document.getElementById("restart").addEventListener("click", function () { | |
| role = null; | |
| slider.value = 5; | |
| renderSlider(); | |
| showStep(1); | |
| }); | |
| // Keyboard/Enter also works on the step buttons. | |
| document.querySelectorAll(".step").forEach(function (s) { | |
| s.addEventListener("click", function () { | |
| // Free navigation between already-visited steps is allowed. | |
| showStep(Number(s.dataset.step)); | |
| }); | |
| }); | |
| renderSlider(); | |
| })(); | |
| </script> | |
| </body> | |
| </html> | |