Add complete Texas Hold'em poker gameplay including: - Pure function game engine (deck, dealing, betting, showdown) - Hand evaluator supporting all 10 poker hand ranks - Animated card components with 3D flip transitions - CSS Grid oval poker table layout for up to 9 seats - Player seat components with chip tracking and turn indicators - Bet controls with conditional button visibility - Basic AI opponents with random valid action selection - Turn advancement, all-in auto-advance, and dealer rotation Sync delta specs to main specs: poker-table, card-components, game-engine, player-state.
104 lines
2.0 KiB
Svelte
104 lines
2.0 KiB
Svelte
<script lang="ts">
|
|
import Card from './Card.svelte';
|
|
import type { PlayerSeat as PlayerSeatType } from '$lib/types/player';
|
|
|
|
let { player, isCurrentTurn = false, isHuman = false }: {
|
|
player: PlayerSeatType;
|
|
isCurrentTurn?: boolean;
|
|
isHuman?: boolean;
|
|
} = $props();
|
|
|
|
const showCards = $derived(isHuman || player.holeCards.length === 0);
|
|
</script>
|
|
|
|
<div class="seat" class:active={isCurrentTurn} class:folded={player.status === 'folded'}>
|
|
{#if player.holeCards.length > 0}
|
|
<div class="hole-cards">
|
|
{#each player.holeCards as card (card.rank + card.suit)}
|
|
<Card {card} flipped={!showCards} />
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
|
|
<div class="info">
|
|
<span class="name">{player.name}</span>
|
|
<span class="chips">${player.chips}</span>
|
|
{#if player.currentBet > 0}
|
|
<span class="bet">${player.currentBet}</span>
|
|
{/if}
|
|
</div>
|
|
|
|
{#if player.status === 'folded'}
|
|
<span class="status-badge">FOLD</span>
|
|
{/if}
|
|
{#if player.status === 'all-in'}
|
|
<span class="status-badge all-in">ALL-IN</span>
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.seat {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 8px;
|
|
border-radius: 8px;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.seat.active {
|
|
background: rgba(255, 255, 0, 0.1);
|
|
box-shadow: 0 0 12px rgba(255, 255, 0, 0.4);
|
|
}
|
|
|
|
.seat.folded {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
.hole-cards {
|
|
display: flex;
|
|
gap: 4px;
|
|
}
|
|
|
|
.info {
|
|
text-align: center;
|
|
font-size: 12px;
|
|
color: #ecf0f1;
|
|
}
|
|
|
|
.name {
|
|
font-weight: 600;
|
|
display: block;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.chips {
|
|
background: rgba(0, 0, 0, 0.5);
|
|
padding: 2px 8px;
|
|
border-radius: 10px;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.bet {
|
|
display: block;
|
|
color: #f1c40f;
|
|
font-weight: 600;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.status-badge {
|
|
font-size: 9px;
|
|
font-weight: 700;
|
|
padding: 1px 6px;
|
|
border-radius: 4px;
|
|
background: #e74c3c;
|
|
color: white;
|
|
}
|
|
|
|
.status-badge.all-in {
|
|
background: #f39c12;
|
|
}
|
|
</style>
|