Skip to content

refactor(game): share hand limit constant - #1457

Merged
Haviles04 merged 1 commit into
cuttle-cards:mainfrom
th060316-lgtm:issue-1449-hand-limit
Oct 24, 2026
Merged

Haviles04 merged 1 commit into
cuttle-cards:mainfrom
th060316-lgtm:issue-1449-hand-limit

Conversation

@th060316-lgtm

@th060316-lgtm th060316-lgtm commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Shares the 8-card hand limit between the client and server instead of defining the same value in multiple places.

The client previously exported HAND_LIMIT = 8 from src/stores/game.js, while backend move helpers repeated the literal value 8 when checking whether a player must discard. Keeping those values separate makes it possible for the client and server rules to drift apart.

This change adds a shared HAND_LIMIT value in utils/GameConstants.json and uses it from both sides without changing the current 8-card gameplay rule.

Changes

  • Added HAND_LIMIT: 8 to utils/GameConstants.json
  • Updated backend move helpers to use the shared constant instead of hard-coded hand-limit values
  • Updated discard-to-hand-limit validation to calculate overflow from the shared constant
  • Updated src/stores/game.js to export the same shared value for the client
  • Updated related comments so they no longer hard-code the numeric limit
  • No gameplay behavior changes
  • No dependency changes

Testing

  • Local Linux validation was not run because I do not have a Linux environment
  • The change keeps the hand limit at 8 and only replaces duplicated literals with the shared constant
  • GitHub Actions will validate lint, unit tests, and E2E tests on Linux

Resolves #1449

@th060316-lgtm
th060316-lgtm marked this pull request as ready for review October 24, 2026 12:47
@Haviles04 Haviles04 added the version-patch An update that warrants a bumping the project's patch version (e.g. 4.0.0 => 4.0.1) label Oct 24, 2026

@Haviles04 Haviles04 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Thanks for you contribution

@Haviles04 Haviles04 added dev experience Improvements to the code base that make it easier/better/more enjoyable to contribute to Cuttle backend Requires changes to the (node) backend webserver frontend Requires changes to the frontend (vue) client labels Oct 24, 2026
@Haviles04
Haviles04 merged commit 186d018 into cuttle-cards:main Oct 24, 2026
14 of 18 checks passed
@th060316-lgtm
th060316-lgtm deleted the issue-1449-hand-limit branch October 24, 2026 17:07
itsalaidbacklife added a commit that referenced this pull request Oct 25, 2026
Follows #1457, which replaced the hard-coded 8 in the other move helpers but
predates discardFour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
itsalaidbacklife added a commit that referenced this pull request Oct 28, 2026
…rd (#1443)

* feat: rework fours to reveal three cards, caster chooses two to discard

The second of the two Four variations trialled this Spades season. A four
one-off now makes the opponent reveal three cards of their choice from hand,
and the four's player chooses two of those for them to discard. Replaces the
3.0.0 random discard. Rules version bumped to 4.0.0.

Rules:
- 4+ cards in hand: the victim reveals three (RESOLVING_FOUR_REVEAL), then the
  caster chooses two of them (RESOLVING_FOUR_DISCARD).
- Exactly 3 cards: the reveal is skipped; the whole hand is revealed.
- 2 or fewer: discarded outright as the four resolves. A four stays playable
  against any hand, including an empty one.

Implementation:
- New GamePhases RESOLVING_FOUR_REVEAL (8) and RESOLVING_FOUR_DISCARD (9), and
  MoveTypes revealFour / discardFour with validate/execute helpers, policy
  arms, AI move-body generation, active-player cases, and log lines.
- Revealed cards persist between the two moves in a new nullable jsonb
  `revealedCards` column on GameStateRow, threaded through pack/unpack,
  validate-gamestate, deal-cards, load-fixture-gamestate, and the socket game
  payload (sent to both players, outside opponent-hand hiding).
- get-log keeps the "at random" wording for rules 3.x games only.
- Legacy RESOLVING_FOUR / resolveFour replay paths are retained untouched.
- New reveal and choose-discard dialogs, waiting overlays (the victim sees
  their revealed cards), store getters/actions, and socket handling.
- Announcement copy, rules text, and move-effect text updated in all locales,
  under a new announcement id so it shows again.

Deploy: production and staging use migrate: 'safe', so before deploying run
  ALTER TABLE gamestaterow ADD COLUMN IF NOT EXISTS "revealedCards" jsonb;

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(get-log): narrate a four against an empty hand

A four resolved against an empty hand carries no discardedCards, so it was
mistaken for a legacy (rules < 3.0.0) row and logged "must discard two cards".
Identify legacy rows by their RESOLVING_FOUR phase instead, which every pre-3.0.0
four resolve entered and no later one does, and give the empty hand its own line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(fours): reveal short-hand discards to the caster, not the victim

create-socket-events flips playedBy on a resolve to the player who played the
one-off, but the RESOLVE case 4 handler assumed it was the resolver. So the
victim saw their own discards flash in the caster's hand, and the caster never
saw the reveal. Invert the check, correct the comment, and cover both sides in
4_fours.spec.js.

Fixes #1440

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(fours): rename revealedCards to fourRevealedCards

Scope the column, socket payload field, revealFour move body and store state to
the four, leaving revealedCards free for #1388's running record of every card
both players have seen.

Deploy note: the column to add is now
ALTER TABLE gamestaterow ADD COLUMN IF NOT EXISTS "fourRevealedCards" jsonb;

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: address first round of review feedback on #1443

- four.js: comment the reveal and reveal-whole-hand branches
- AI move bodies: drop the hand-limit recursion-bound comment now that
  getCombinations serves several move types
- Announcement: "Reveal-Three Fours" activator and "Reveal three, discard
  two" heading, in all five locales
- four.spec.js: group the validation error tests in describe('Errors')
- 4_fours.spec.js: assert the turn passes via #turn-indicator, per the
  basicMoves.spec.js convention

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: address review decisions on #1443

- GameStateRow: document that fourRevealedCards is backfilled by the deploy
  SQL's DEFAULT '[]' rather than left nullable
- inGameEvents: restore main's RESOLVE case 4 comment, plus one line on
  which hands are discarded on resolve
- four.spec.js: validate the resolve tests too, and assert valid moves with
  expect(...).not.to.throw()
- Replace the staged RESOLVING_FOUR_DISCARD e2e test with a reconnect test
  from the four's player's side, and drop the load-fixture override it needed

Deploy note: the column to add is now
ALTER TABLE gamestaterow ADD COLUMN IF NOT EXISTS "fourRevealedCards" jsonb NOT NULL DEFAULT '[]'::jsonb;

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(discard-four): use shared HAND_LIMIT constant

Follows #1457, which replaced the hard-coded 8 in the other move helpers but
predates discardFour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Requires changes to the (node) backend webserver dev experience Improvements to the code base that make it easier/better/more enjoyable to contribute to Cuttle frontend Requires changes to the frontend (vue) client version-patch An update that warrants a bumping the project's patch version (e.g. 4.0.0 => 4.0.1)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DevEx]: Share the hand limit constant between client and server

2 participants