brisca-engine
v1.0.0
Published
Game engine for the Spanish card game Brisca — deck, rules, and turn-by-turn state, framework-agnostic.
Maintainers
Readme
brisca-engine
A framework-agnostic TypeScript game engine for Brisca, the classic Spanish trick-taking card game. Handles the deck, dealing, turn order, trick resolution, and scoring — so you can build a UI, CLI, or bot on top without reimplementing the rules.
No frontend, no server, no database. Just game logic.
Install
npm install brisca-engineQuick start
import { BriscaGame } from 'brisca-engine';
const game = new BriscaGame(2); // 2, 3, or 4 players
console.log(game.trumpSuit); // e.g. 'copas'
console.log(game.getHand(0)); // player 0's 3 starting cards
console.log(game.currentPlayer()); // 0
// Play a card from player 0's hand
const card = game.getHand(0)[0];
const state = game.playCard(0, card);
console.log(state.currentTrick); // cards played so far this trick
console.log(state.scores); // running score per playerRules implemented
- 40-card Spanish deck (no 8s, 9s, or 10-through-Jack face cards from a French deck)
- Correct point values (Ace = 11, Three = 10, King = 4, Knight = 3, Jack = 2, rest = 0)
- Trick-taking strength order (which does not match point order — the classic Brisca twist)
- Trump suit revealed from the deal
- Draw-to-3 after each trick, winner draws first
- 2, 3, or 4 player support
API
new BriscaGame(playerCount: number)
Creates a new game. playerCount must be 2, 3, or 4. Shuffles the deck, deals 3 cards to each player, and reveals the trump card.
Throws BriscaError (code INVALID_PLAYER_COUNT) if playerCount is out of range.
game.trumpSuit: Suit
The suit that's trump for this game ('oros' | 'copas' | 'espadas' | 'bastos').
game.currentPlayer(): number | null
The index of the player whose turn it is, or null if the game has finished.
game.getHand(player: number): Card[]
Returns a copy of the given player's current hand.
game.playCard(player: number, card: Card): GameState
Plays a card on behalf of player. Returns the full updated game state.
Throws BriscaError if:
NOT_YOUR_TURN— it isn't that player's turnCARD_NOT_IN_HAND— the player doesn't hold that cardGAME_FINISHED— the game has already endedINVALID_PLAYER— the player index doesn't exist in this game
game.getState(): GameState
Returns a full snapshot of the current game state (hands, scores, trick history, phase, winner, etc.) without mutating anything.
game.getTrickWinner(cards: Card[], trumpSuit: Suit): Card
Given a set of played cards (in play order) and a trump suit, returns the winning card. Useful if you want to resolve tricks yourself outside of playCard.
Types
type Suit = 'oros' | 'copas' | 'espadas' | 'bastos';
type Rank = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12;
interface Card {
suit: Suit;
rank: Rank;
}
interface GameState {
id: string;
playerCount: number;
hands: Card[][];
trumpCard: Card;
trumpSuit: Suit;
drawQueue: Card[];
currentTrick: PlayedCard[];
leader: number;
scores: number[];
history: TrickRecord[];
phase: 'playing' | 'finished';
winner: number | null;
}Also exported
buildDeck(): Card[]— a fresh, unshuffled 40-card deckshuffle<T>(items: T[]): T[]— Fisher-Yates shufflecardPoints(card: Card): number— point value of a single cardrankStrength(rank: Rank): number— trick-taking strength (higher wins)SUITS,RANKS,CARD_POINTS— raw constants
License
MIT
