fix(card-sorting): only shrink/fade cards in correct prefix

Changed the shrink and fade behavior to only apply to cards that are part
of the correct prefix of the sorted sequence, not just any card in its
correct absolute position.

**Before:**
If sequence is [10, 30, 20, 40, 50] and correct order is [10, 20, 30, 40, 50]:
- Cards 10, 40, and 50 would shrink/fade (in correct absolute positions)
- Even though 40 and 50 are NOT part of a correct prefix

**After:**
Only card 10 shrinks/fades (the only correct prefix of length 1)

**How it works:**
A card is in the correct prefix if:
1. It's at position i in the current sequence
2. All cards from position 0 to i match the correct order
3. This ensures only the longest correct prefix gets visual feedback

**Updated:**
- AnimatedCard rendering logic to check for correct prefix
- ContinuousSequencePath to apply scale only to prefix cards
- Green borders also now only show for correct prefix

This provides clearer feedback about progress and helps players understand
which cards are definitively correct vs. just happen to be in the right
spot relative to the full answer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-10-23 21:46:52 -05:00
parent 7028cfc511
commit 51368c6ec5
1 changed files with 34 additions and 10 deletions

View File

@ -160,12 +160,21 @@ function ContinuousSequencePath({
const CARD_HALF_WIDTH = CARD_WIDTH / 2
const CARD_HALF_HEIGHT = CARD_HEIGHT / 2
// Helper to check if a card is in correct position (and thus scaled to 50%)
// Helper to check if a card is part of the correct prefix (and thus scaled to 50%)
const isCardCorrect = (card: SortingCard): boolean => {
const positionInSequence = sequence.findIndex((c) => c.id === card.id)
const isCorrectPosition =
positionInSequence >= 0 && correctOrder[positionInSequence]?.id === card.id
return isSpectating ? spectatorEducationalMode && isCorrectPosition : isCorrectPosition
if (positionInSequence < 0) return false
// Check if all positions from 0 to positionInSequence are correct
let isInCorrectPrefix = true
for (let i = 0; i <= positionInSequence; i++) {
if (sequence[i]?.id !== correctOrder[i]?.id) {
isInCorrectPrefix = false
break
}
}
return isSpectating ? spectatorEducationalMode && isInCorrectPrefix : isInCorrectPrefix
}
// Get all card positions (card centers) with scale information
@ -1872,15 +1881,30 @@ export function PlayingPhaseDrag() {
const isDragging = draggingCardId === card.id
// Check if this card is in the correct position in the inferred sequence
// Find the position of this card in the inferred sequence
const positionInSequence = inferredSequence.findIndex((c) => c.id === card.id)
const isCorrectPosition =
positionInSequence >= 0 && state.correctOrder[positionInSequence]?.id === card.id
// Check if this card is part of the correct prefix
// A card is in the correct prefix if:
// 1. It's in the inferred sequence
// 2. All cards before it (positions 0 to positionInSequence-1) are also correct
// 3. This card itself matches the correct order at its position
let isInCorrectPrefix = false
if (positionInSequence >= 0) {
// Check if all positions from 0 to positionInSequence are correct
isInCorrectPrefix = true
for (let i = 0; i <= positionInSequence; i++) {
if (inferredSequence[i]?.id !== state.correctOrder[i]?.id) {
isInCorrectPrefix = false
break
}
}
}
// Show green border based on educational mode for spectators
const isCorrect = isSpectating
? spectatorEducationalMode && isCorrectPosition
: isCorrectPosition
? spectatorEducationalMode && isInCorrectPrefix
: isInCorrectPrefix
// Get draggedByPlayerId from server state
const serverPosition = state.cardPositions.find((p) => p.cardId === card.id)
@ -1895,7 +1919,7 @@ export function PlayingPhaseDrag() {
isResizing={isResizing}
isSpectating={isSpectating}
isCorrect={isCorrect}
isCorrectPosition={isCorrectPosition}
isCorrectPosition={isInCorrectPrefix}
draggedByPlayerId={draggedByPlayerId}
localPlayerId={localPlayerId}
players={players}