UNPKG

@idealic/poker-engine

Version:

Professional poker game engine and hand evaluator with built-in iterator utilities

142 lines 6.19 kB
import { canCheck, canCall, canBet, canRaise, canFold, isPlayerTurn, isAwaitingDealer, } from '../utils/validation'; import { getRemainingPlayers } from '../utils/position'; /** * Unified validation function for all game commands. * This is a catch-all method that validates whether a specific command can be executed * in the current game state. * * @param game - The current game state * @param command - The command name to validate * @param args - Additional arguments required by specific commands * @returns true if the command is valid and can be executed, false otherwise * * @example * // Check if player 0 can fold * const canPlayerFold = Poker.Game.can(game, 'fold', 0); * * // Check if player 1 can bet 100 chips * const canPlayerBet = Poker.Game.can(game, 'bet', 1, 100); * * // Check if dealer can deal board cards * const canDealBoard = Poker.Game.can(game, 'dealBoard', ['Ah', 'Kh', 'Qh']); */ export function can(game, command, ...args) { switch (command) { case 'fold': { const [playerIndex] = args; if (typeof playerIndex !== 'number' || playerIndex < 0 || playerIndex >= game.players.length) { return false; } return isPlayerTurn(game, playerIndex) && canFold(game, playerIndex); } case 'check': { const [playerIndex] = args; if (typeof playerIndex !== 'number' || playerIndex < 0 || playerIndex >= game.players.length) { return false; } return isPlayerTurn(game, playerIndex) && canCheck(game, playerIndex); } case 'call': { const [playerIndex] = args; if (typeof playerIndex !== 'number' || playerIndex < 0 || playerIndex >= game.players.length) { return false; } return isPlayerTurn(game, playerIndex) && canCall(game, playerIndex); } case 'bet': { const [playerIndex, amount] = args; if (typeof playerIndex !== 'number' || playerIndex < 0 || playerIndex >= game.players.length) { return false; } if (typeof amount !== 'number' || amount <= 0) { return false; } const player = game.players[playerIndex]; const availableStack = player.stack + player.currentBet; return (isPlayerTurn(game, playerIndex) && canBet(game, playerIndex) && amount <= availableStack); } case 'raise': { const [playerIndex, amount] = args; if (typeof playerIndex !== 'number' || playerIndex < 0 || playerIndex >= game.players.length) { return false; } if (typeof amount !== 'number' || amount <= 0) { return false; } const player = game.players[playerIndex]; const availableStack = player.stack + player.currentBet; const minRaiseAmount = game.bet * 2 - player.currentBet; return (isPlayerTurn(game, playerIndex) && canRaise(game, playerIndex) && amount >= minRaiseAmount && amount <= availableStack); } case 'dealBoard': { const [cards] = args; if (!Array.isArray(cards) || cards.length === 0) { return false; } // Can deal board if it's dealer's turn and we need community cards if (!isAwaitingDealer(game)) { return false; } // Check if we need board cards (not all hole cards dealt yet, or betting round complete) const activePlayers = getRemainingPlayers(game); const allPlayersHaveCards = activePlayers.every(p => p.cards.length > 0); if (!allPlayersHaveCards) { return false; // Need to deal hole cards first } // Can deal board if betting is complete and we haven't dealt all board cards return game.isBettingComplete && game.board.length < 5; } case 'dealHoleCards': { const [playerIndex, cards] = args; if (typeof playerIndex !== 'number' || playerIndex < 0 || playerIndex >= game.players.length) { return false; } if (!Array.isArray(cards) || cards.length === 0) { return false; } // Can deal hole cards if it's dealer's turn and the player needs cards if (!isAwaitingDealer(game)) { return false; } const player = game.players[playerIndex]; return !player.isInactive && player.cards.length === 0; } case 'dealStreet': { // Can deal street if it's dealer's turn and conditions are met if (!isAwaitingDealer(game)) { return false; } // Check if all players have cards const activePlayers = getRemainingPlayers(game); const allPlayersHaveCards = activePlayers.every(p => p.cards.length > 0); if (!allPlayersHaveCards) { return false; // Need to deal hole cards first } // Can deal next street if betting is complete and more cards are needed return game.isBettingComplete && game.board.length < 5; } case 'showCards': { // Can show cards if it's showdown time if (!isAwaitingDealer(game)) { return false; } const activePlayers = getRemainingPlayers(game); // Need at least 2 players for showdown if (activePlayers.length < 2) { return false; } // Can show cards if all board cards are dealt and there are players who haven't shown const hasUnshownPlayers = activePlayers.some(p => !p.hasShownCards && p.cards.length > 0); return game.board.length === 5 && hasUnshownPlayers; } default: // Unknown command return false; } } //# sourceMappingURL=validation.js.map