feat(core): decide and enforce Draw-1 stock recycle limit (or document unlimited as intentional) #117

Closed
opened 2026-07-06 19:18:59 +00:00 by funman300 · 0 comments
Owner

Severity: Medium (rules/design decision)

Problem

In solitaire_core the draw() path applies score penalties for stock recycles but never returns an error — recycling is unbounded in every mode. MoveError has no variant for a recycle limit (solitaire_core/src/error.rs — closest is StockEmpty).

Classic Klondike Draw-1 scoring rules cap the number of passes through the stock (commonly 1 or 3 passes for Draw-1). Right now infinite recycling is possible, which:

  • makes the score penalty the only deterrent,
  • diverges from the classic ruleset the game otherwise follows,
  • is undocumented as a deliberate choice.

This was first flagged in the 500-game UX audit (June 2026) and is the last item from that audit still open.

Suggested resolution (either is fine, but pick one explicitly)

  1. Implement: add an optional recycle_limit to the game config, return a new MoveError::RecycleLimitReached when exhausted, and surface it in the UI (the no-moves detection must then treat an exhausted stock as no-moves).
  2. Document: record in ARCHITECTURE.md / rules docs that unlimited recycling with score penalties is the intended house rule, and add a core test asserting unlimited recycling so the behaviour is locked in deliberately.

Found during scripted repo review, 2026-07-06.

**Severity: Medium (rules/design decision)** ## Problem In `solitaire_core` the `draw()` path applies score penalties for stock recycles but never returns an error — recycling is unbounded in every mode. `MoveError` has no variant for a recycle limit (`solitaire_core/src/error.rs` — closest is `StockEmpty`). Classic Klondike Draw-1 scoring rules cap the number of passes through the stock (commonly 1 or 3 passes for Draw-1). Right now infinite recycling is possible, which: - makes the score penalty the only deterrent, - diverges from the classic ruleset the game otherwise follows, - is undocumented as a deliberate choice. This was first flagged in the 500-game UX audit (June 2026) and is the last item from that audit still open. ## Suggested resolution (either is fine, but pick one explicitly) 1. **Implement**: add an optional `recycle_limit` to the game config, return a new `MoveError::RecycleLimitReached` when exhausted, and surface it in the UI (the no-moves detection must then treat an exhausted stock as no-moves). 2. **Document**: record in `ARCHITECTURE.md` / rules docs that unlimited recycling with score penalties is the intended house rule, and add a core test asserting unlimited recycling so the behaviour is locked in deliberately. Found during scripted repo review, 2026-07-06.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: funman300/Ferrous-Solitaire#117