Dice Game JavaScript: Bank the Turn Before Declaring a Winner

Player B reaches 20 on the turn display, and your game announces victory. But those points are still provisional: a one would discard them, and Hold has not added them to the bank.

The subtotal and banked score need separate state and separate win checks.

Use an original two-player dice game JavaScript specification with target 20, a controlled roll queue, and a readable action ledger. It is a short Pig-style teaching variant, with no money or rewards involved.

Bank it · controlled dice game — Keep a turn subtotal separate from banked points, discard only the subtotal on a one and award victory only after banking.
Bank it · controlled dice game — Keep a turn subtotal separate from banked points, discard only the subtotal on a one and award victory only after banking.
Open the full example ↗

Separate the bank from the current turn

Jenny Kraft's Pig project explains rolling into a round score, losing that round's points on a one, and using Hold to add them to the total. Her described target is 100. This original local variant chooses 20, with players A and B, A starting, banked scores [0, 0] and turn subtotal 0.

The bank is committed history; the subtotal belongs only to the active turn. A valid face from 2 through 6 increases the subtotal. A one discards the subtotal and switches the active player, leaving both banked scores unchanged.

Hold adds the subtotal to the active player's bank and clears it. If the new bank is at least 20, that player wins and the game stops without switching turns. Otherwise, switch once. This specification allows Hold with subtotal zero: it banks nothing but still ends the turn.

Follow one controlled trace through bust and victory

Use fixture queue [4, 5, 1, 6, 6, 6, 2]. Label fixture mode prominently; this sequence is test data, not a random simulation.

Action Actor Subtotal afterward Banked A/B Phase
Roll 4 A 4 0 / 0 A active
Roll 5 A 9 0 / 0 A active
Roll 1 A 0 0 / 0 B active
Roll 6, 6, 6, 2 B 20 0 / 0 B active; no winner
Hold B 0 0 / 20 B wins

The one removes A's unbanked 9, not any banked score. B's provisional 20 is not victory until Hold commits it.

For an independent branch, stop after A's 4 and 5 and choose Hold. A banks 9, subtotal becomes zero and B becomes active. In another staged fixture, A already has banked 9 and subtotal 4: rolling one preserves the banked 9 and discards only 4. These are separate expected records, not one uninterrupted played route.

Treat face validation as a transaction

Require an integer face from 1 through 6. Reject zero, seven, fractions and missing input without changing actor, subtotal, banks, winner or confirmed ledger. In fixture mode, validate the next queued entry before advancing the cursor. An invalid entry remains unconsumed and needs correction; silently skipping it changes the fixture.

At queue exhaustion, report that more fixture data is required. Do not recycle the sequence or generate an extra face. Hold can still bank an existing subtotal without drawing another entry. Keep any later live face-generation mode separate from the controlled queue, with no claim of tested fairness or security.

Use one action path and an inspectable ledger

Provide native Roll, Hold and Reset buttons, plus readable die face, active player, subtotal, banked totals, target, mode and result. Each confirmed ledger row snapshots its actor and before/after scores.

Fresh activation performs one action. Ignore held-key repeat, avoid duplicate pointerdown/click handlers, and guard any delayed die animation against a newer Reset or terminal state. Roll and Hold are disabled for terminal play; callbacks cannot award another point after victory.

Reset restores banks [0, 0], subtotal 0, A active, original queue cursor 0, blank face, no winner and empty history. The die display must agree with the accepted face record rather than choose its own result.

Copyable controlled-roll prompt

Create one complete, self-contained US-English HTML companion for “Bank it · controlled dice game”. Return the full HTML document, with inline CSS and any JavaScript needed for the local interactions. Use the original scenario, named records, numbers and expected cases below.

Design the page for this task: use clearly labeled input or source records, a readable result or worked example, and an adjacent explanation of the evidence. Use a restrained visual hierarchy, left-aligned text, readable tables or stacked records, and a responsive layout at 720px and 360px. Provide meaningful labeled controls for Roll; Hold; Reset; Start with this queue. Use keyboard-accessible native controls and visible focus. Keep the complete content readable without an external dependency.

The following brief supplies the substantive content and constraints. Native-format requests describe the material to represent or copy manually; this HTML must not pretend to create DOCX, XLSX, PDF, PPTX, H5P or another native file, run Python/Flask/Django/Snowflake/Power BI, connect a live service, send messages, or perform an authorized real-world action. Where the task requires a native source, actual observation or separate approval, retain that requirement and leave unsupplied evidence blank.

Prepare an original native source plan, action ledger and optional HTML local two-player Pig-style specification. Target 20 is an explicit short variant, not the reference's 100. Initial banks [0,0], subtotal 0, A active; no money, rewards, betting, AI or copied course code/art.

Faces must be integers 1..6. Faces 2..6 add to turn subtotal. Face 1 clears only subtotal and switches player once, preserving banks. Hold adds subtotal to the actor's bank, clears subtotal, and checks bank >= 20 before any turn switch. Winner stops play. Hold with zero is legal and switches once when nonterminal.

Controlled fixture queue [4,5,1,6,6,6,2]: A reaches subtotal 9 then loses it on 1; banks remain 0/0 and B active. B reaches subtotal 20 but does not win until Hold banks 20. Independent early-Hold branch banks A 9; separate banked A 9/subtotal 4/roll 1 fixture preserves bank 9. Label branches and expected records, not executed play.

Validate queued face before consuming cursor. Invalid 0/7/fraction/missing rejects without state/history/cursor mutation. Exhaustion requests more fixture data, no recycling or automatic extra roll; Hold remains available. Keep future live generation separate with no fairness/security claim. Native Roll/Hold/Reset, readable face/banks/subtotal/actor/target/mode/ledger. One fresh activation, no repeat/double handler; stale callbacks cannot affect reset or terminal game. Reset all original state and cursor. Supply bust, bank preservation, provisional20, Hold win/zero, invalid/exhausted and Reset tests. Mark source, controls, drawing, keyboard, article width, 360 px and NOS runtime checks not_tested. No saved scores or host guarantee.

COMPLETE AUTHORED SCENARIO AND EXPECTED CASES
The following is the supplied reading/teaching/calculation record to represent in the companion. Preserve its particular content, examples, source references and unknowns. Wording about a future native implementation refers to that native task, not permission to omit this HTML companion.

# Dice Game JavaScript: Bank the Turn Before Declaring a Winner

Player B reaches 20 on the turn display, and your game announces victory. But those points are still provisional: a one would discard them, and Hold has not added them to the bank. The subtotal and banked score need separate state and separate win checks.

Use an original two-player dice game JavaScript specification with target 20, a controlled roll queue, and a readable action ledger. It is a short Pig-style teaching variant, with no money or rewards involved.

## Separate the bank from the current turn

[Jenny Kraft's Pig project](https://jennykraft.de/projects/pig-dice-game/) explains rolling into a round score, losing that round's points on a one, and using Hold to add them to the total. Her described target is 100. This original local variant chooses 20, with players A and B, A starting, banked scores [0, 0] and turn subtotal 0.

The bank is committed history; the subtotal belongs only to the active turn. A valid face from 2 through 6 increases the subtotal. A one discards the subtotal and switches the active player, leaving both banked scores unchanged.

Hold adds the subtotal to the active player's bank and clears it. If the new bank is at least 20, that player wins and the game stops without switching turns. Otherwise, switch once. This specification allows Hold with subtotal zero: it banks nothing but still ends the turn.

## Follow one controlled trace through bust and victory

Use fixture queue [4, 5, 1, 6, 6, 6, 2]. Label fixture mode prominently; this sequence is test data, not a random simulation.

| Action | Actor | Subtotal afterward | Banked A/B | Phase |
|---|---|---:|---|---|
| Roll 4 | A | 4 | 0 / 0 | A active |
| Roll 5 | A | 9 | 0 / 0 | A active |
| Roll 1 | A | 0 | 0 / 0 | B active |
| Roll 6, 6, 6, 2 | B | 20 | 0 / 0 | B active; no winner |
| Hold | B | 0 | 0 / 20 | B wins |

The one removes A's unbanked 9, not any banked score. B's provisional 20 is not victory until Hold commits it.

For an independent branch, stop after A's 4 and 5 and choose Hold. A banks 9, subtotal becomes zero and B becomes active. In another staged fixture, A already has banked 9 and subtotal 4: rolling one preserves the banked 9 and discards only 4. These are separate expected records, not one uninterrupted played route.

## Treat face validation as a transaction

Require an integer face from 1 through 6. Reject zero, seven, fractions and missing input without changing actor, subtotal, banks, winner or confirmed ledger. In fixture mode, validate the next queued entry before advancing the cursor. An invalid entry remains unconsumed and needs correction; silently skipping it changes the fixture.

At queue exhaustion, report that more fixture data is required. Do not recycle the sequence or generate an extra face. Hold can still bank an existing subtotal without drawing another entry. Keep any later live face-generation mode separate from the controlled queue, with no claim of tested fairness or security.

## Use one action path and an inspectable ledger

Provide native Roll, Hold and Reset buttons, plus readable die face, active player, subtotal, banked totals, target, mode and result. Each confirmed ledger row snapshots its actor and before/after scores.

Fresh activation performs one action. Ignore held-key repeat, avoid duplicate pointerdown/click handlers, and guard any delayed die animation against a newer Reset or terminal state. Roll and Hold are disabled for terminal play; callbacks cannot award another point after victory.

Reset restores banks [0, 0], subtotal 0, A active, original queue cursor 0, blank face, no winner and empty history. The die display must agree with the accepted face record rather than choose its own result.



Implement the local companion rather than returning a text-only plan. Preserve every numerical fixture and the distinction between illustrative expectations and actual evidence. Any native-runtime or classroom tests mentioned above remain tests to perform in the proper environment; do not mark them passed. Keep edits and practice responses in this open page only, without claiming persistent storage. Provide invalid/missing-input feedback and reset behavior that agree with this specific brief. Do not claim accessibility certification, learning gains, real approvals or test results that were not observed.

Optional use for the prepared dice view

Explore NOS

Keep the native score ledger and controlled fixture as the primary developer materials. The HTML companion is available above for comparison with the original records. Verify score transitions, queue handling and single activation in the actual workspace before treating the game as tested.

Keep reading