Doteraz sa pri hodeni 4. karty cela kopka na frame stratila (displayedStash padol na lingeredStash nastaveny az v useEffekte) a nasledne sa vsetky karty znovu vlietli. Teraz sa previous_stash cita synchronne, takze posledna karta len pribudne k trom uz leziacim, a potom sa cela kopka odsunie animaciou smerom k sedadlu, ktore kopku vyhralo (stashWinner podla pravidiel enginu). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import type { CardColor, CardValue, Hand, StashData } from '../types';
|
|
|
|
export function computePlayable(hand: Hand, ledColor: CardColor | null): Set<string> {
|
|
const keys = Object.keys(hand);
|
|
if (!ledColor) return new Set(keys);
|
|
|
|
const ledKeys = keys.filter((k) => hand[k].color === ledColor);
|
|
if (ledKeys.length > 0) return new Set(ledKeys);
|
|
|
|
const heartKeys = keys.filter((k) => hand[k].color === 'HEARTS');
|
|
if (heartKeys.length > 0) return new Set(heartKeys);
|
|
|
|
return new Set(keys);
|
|
}
|
|
|
|
const VALUE_ORDER: CardValue[] = ['C7', 'C8', 'C9', 'C10', 'LOWER', 'UPPER', 'KING', 'ACE'];
|
|
|
|
/** Seat that wins a completed 4-card trick — mirrors Stash.get_winner in the
|
|
* engine: HEARTS (červeň) is the permanent trump, otherwise the highest card
|
|
* of the led colour wins. Safe to call on a partial stash (returns the current
|
|
* leader among the cards played so far). */
|
|
export function stashWinner(stash: StashData): number {
|
|
const led = stash.cards[String(stash.first_player)];
|
|
if (!led) return stash.first_player;
|
|
let winner = stash.first_player;
|
|
let best = led;
|
|
for (let i = 0; i < 4; i++) {
|
|
const c = stash.cards[String(i)];
|
|
if (!c) continue;
|
|
if (c.color === led.color || c.color === 'HEARTS') {
|
|
if (c.color === best.color) {
|
|
if (VALUE_ORDER.indexOf(c.value) >= VALUE_ORDER.indexOf(best.value)) {
|
|
best = c;
|
|
winner = i;
|
|
}
|
|
} else if (c.color === 'HEARTS') {
|
|
best = c;
|
|
winner = i;
|
|
}
|
|
}
|
|
}
|
|
return winner;
|
|
}
|
|
|
|
/** The bid the last guesser may not make: the four bids must not sum to the
|
|
* number of tricks in the round (mirrors Round.add_player_guess in the engine).
|
|
* Returns null while earlier players are still guessing. */
|
|
export function forbiddenGuess(cardsInRound: number, guesses: Record<string, number>): number | null {
|
|
if (Object.keys(guesses).length !== 3) return null;
|
|
const alreadySum = Object.values(guesses).reduce((a, b) => a + b, 0);
|
|
return cardsInRound - alreadySum;
|
|
}
|