JSPM

@devarshmavani/card-engine

0.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q26441F
  • License MIT

A reusable, type-safe card game engine library for TypeScript. Build card games like Rummy, Teen Patti, Poker with fully typed game states and events.

Package Exports

  • @devarshmavani/card-engine
  • @devarshmavani/card-engine/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@devarshmavani/card-engine) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Card Engine

A reusable, type-safe card game engine library for TypeScript. Build card games like Rummy, Teen Patti, Do Teen Panch, Poker, and more with fully typed game states and events.

Features

  • 🎯 Fully Type-Safe - Generic game states and events with complete TypeScript support
  • 🎮 Game Agnostic - Build any card game by extending the RuleEngine
  • 📦 Tree-Shakeable - Import only what you need
  • 🔄 Serializable - Full game state serialization for multiplayer/persistence
  • 🎪 Event-Driven - Type-safe event system for UI synchronization
  • 🌐 Universal - Works in Node.js and browser environments
  • 📝 Pure Logic - No DOM/UI dependencies

Installation

npm install @devarsh-mavani-19/card-engine

Quick Start

import { Game, Player, RuleEngine, GameState } from '@devarsh-mavani-19/card-engine';

// Define your game state
interface MyGameState extends GameState {
  currentRound: number;
  tricks: number;
}

// Create your game rules
class MyGameRules extends RuleEngine<MyGameState> {
  getInitialCardCount(): number {
    return 5;
  }

  canPlayCard(player: Player, card: Card, state: MyGameState): boolean {
    // Your game logic
    return true;
  }

  // ... implement other required methods
}

// Create and start a game
const game = new Game<MyGameState>(new MyGameRules());
game.addPlayer(new Player('p1', 'Alice'));
game.addPlayer(new Player('p2', 'Bob'));

// Listen to type-safe events
game.on('gameStarted', (data) => {
  console.log(`Game started with ${data.players.length} players`);
  console.log(`Round: ${data.state.currentRound}`);
});

game.start();

Core Classes

Card

Represents a single card with rank, suit, and optional metadata.

import { Card } from '@devarsh-mavani-19/card-engine';

const card = new Card('A', 'hearts');
console.log(card.toString()); // "A of hearts"

Deck

Manages a deck of cards with shuffle, draw, and reset operations.

import { Deck } from '@devarsh-mavani-19/card-engine';

const deck = Deck.createStandardDeck(); // 52 cards
deck.shuffle();
const cards = deck.draw(5); // Draw 5 cards

Player

Represents a player with a hand of cards.

import { Player } from '@devarsh-mavani-19/card-engine';

const player = new Player('p1', 'Alice');
player.receiveCard(card);
const playedCard = player.playCard(card);

RuleEngine

Abstract class for implementing game-specific rules.

import { RuleEngine, GameState } from '@devarsh-mavani-19/card-engine';

interface MyState extends GameState {
  // Your game state
}

class MyRules extends RuleEngine<MyState> {
  canPlayCard(player, card, state) { /* ... */ }
  isWinningHand(player, state) { /* ... */ }
  onCardPlayed(player, card, state) { /* ... */ }
  validateMove(move, state) { /* ... */ }
  getInitialCardCount() { /* ... */ }
  getWinners(state) { /* ... */ }
  isGameOver(state) { /* ... */ }
}

Game

Main game controller with turn management and state handling.

import { Game } from '@devarsh-mavani-19/card-engine';

const game = new Game<MyState>(new MyRules());
game.addPlayer(player);
game.start();
game.playCard(card);
game.nextTurn();

Type-Safe Events

All events are fully typed based on your game state:

game.on('gameStarted', (data) => {
  // data: { players: Player[]; state: MyState }
});

game.on('cardPlayed', (data) => {
  // data: { player: Player; card: Card }
});

game.on('turnStarted', (player) => {
  // player: Player
});

game.on('gameEnded', (data) => {
  // data: { winners: string[]; state: MyState }
});

Serialization

Save and restore complete game state:

// Serialize
const serialized = game.serialize();
const json = JSON.stringify(serialized);

// Deserialize
const restored = Game.deserialize(JSON.parse(json), new MyRules());

Example: Do Teen Panch

import { Game, Player, RuleEngine, GameState, Card } from '@devarsh-mavani-19/card-engine';

interface DoTeenPanchState extends GameState {
  roundNumber: number;
  currentSuit?: string;
  tricks: { playerId: string; card: Card }[];
  playerScores: Map<string, number>;
}

class DoTeenPanchRules extends RuleEngine<DoTeenPanchState> {
  getInitialCardCount() {
    return 5;
  }

  canPlayCard(player: Player, card: Card, state: DoTeenPanchState): boolean {
    if (!state.currentSuit) return true;
    const hasSuit = player.getHand().some(c => c.suit === state.currentSuit);
    return !hasSuit || card.suit === state.currentSuit;
  }

  // ... implement other methods
}

const game = new Game<DoTeenPanchState>(new DoTeenPanchRules());
game.addPlayer(new Player('p1', 'Alice'));
game.addPlayer(new Player('p2', 'Bob'));
game.start();

Architecture

card-engine/
├── core/
│   ├── Game.ts          # Main game controller
│   ├── RuleEngine.ts    # Abstract rule engine
│   └── EventEmitter.ts  # Type-safe event system
├── models/
│   ├── Card.ts          # Card representation
│   ├── Deck.ts          # Deck management
│   └── Player.ts        # Player management
└── index.ts             # Public exports

License

MIT

Author

devarsh-mavani-19 (devarshmavani19@gmail.com)

Contributing

Issues and pull requests are welcome on GitHub.