0.3.0 • Published 10 months ago
@fudapop/hanafuda-js v0.3.0
Hanafuda Koi-Koi
A modular JavaScript library for implementing Hanafuda card games, with a focus on Koi-Koi. This library provides core functionality for card management, game state handling, and scoring according to traditional Koi-Koi rules.
Features
- Complete Hanafuda card game engine
- Scoring system with traditional yaku (combinations)
- State management with serialization support
- Collection-based card management
- Phase-based game flow
Installation
NPM
npm install @fudapop/hanafuda-jsDeno
import { KoiKoi } from "jsr:@fudapop/hanafuda-js"CDN
You can include Hanafuda-JS directly in your HTML:
<script src="https://unpkg.com/@fudapop/hanafuda-js"></script>Then use it globally:
<script>
const game = new hanafudaJS.KoiKoi()
// Start a new round
const { state, teyaku } = game.startRound()
// Access other exports
const deck = hanafudaJS.createStandardDeck()
const collection = hanafudaJS.createCollection()
</script>Usage
ESM/TypeScript
import { KoiKoi, createStandardDeck, createCollection } from "@fudapop/hanafuda-js"
// Create a new game instance
const game = new KoiKoi()
// Start a new round
const { state, teyaku } = game.startRound()CommonJS
const { KoiKoi, createStandardDeck, createCollection } = require("@fudapop/hanafuda-js")
// Create a new game instance
const game = new KoiKoi()
// Start a new round
const { state, teyaku } = game.startRound()Basic Game Setup
import { KoiKoi } from "./src/koikoi/koikoi.js"
// Create a new game instance
const game = new KoiKoi()
// Start a new round
const { state, teyaku } = game.startRound()
// Check for any initial teyaku (hand yaku)
if (Object.keys(teyaku).length > 0) {
for (const [playerId, playerTeyaku] of Object.entries(teyaku)) {
console.log(`Player ${playerId} has teyaku:`, playerTeyaku)
}
}Playing a Turn
// Select a card from hand
const result = game.selectCard(cardIndex, "hand")
if (result.type === "NO_MATCHES") {
// No matches available - card will be discarded
game.placeSelectedCard()
} else if (result.type === "SELECTION_UPDATED") {
// Card selected - now select matching field cards
const fieldResult = game.selectCard(fieldCardIndex, "field")
if (fieldResult.type === "SELECTION_UPDATED") {
// Play the selected cards
const playResult = game.playCards()
// Handle the result (DECK_DRAW, SCORE_UPDATE, etc.)
}
}Handling Drawn Cards
// After playing cards, a card is automatically drawn
// The result will indicate if there are matches
if (result.type === "DECK_DRAW") {
if (result.data.hasMatches) {
// Must select matching cards from the field
const fieldResult = game.selectCard(fieldCardIndex, "field")
if (fieldResult.type === "SELECTION_UPDATED") {
game.playCards()
}
} else {
// Card was automatically placed on the field
// Game moves to next player
}
}Scoring and Koi-Koi Decisions
// When a scoring combination is completed
if (result.type === "SCORE_UPDATE") {
const { completedYaku } = result.data
console.log("Completed yaku:", completedYaku)
// Player decides whether to continue (koi-koi) or end the round
const chooseKoiKoi = confirm("Would you like to declare Koi-Koi and continue?")
const decision = game.makeKoiKoiDecision(chooseKoiKoi)
if (decision.type === "ROUND_END") {
console.log("Round ended! Winner:", decision.data.winner)
console.log("Final yaku:", decision.data.yaku)
}
}State Management
// Get current game state
const state = game.getState()
// Save game state
const savedState = JSON.stringify(state)
localStorage.setItem("hanafudaGameState", savedState)
// Load game state
const loadedState = localStorage.getItem("hanafudaGameState")
if (loadedState) {
const game = new KoiKoi()
// TODO: Implement state loading
}Example Application
An example web application demonstrating the library's features is available in the example/ directory. It provides a basic interface for playing Hanafuda Koi-Koi and showcases:
- Game state management
- Card selection and matching
- Basic game flow implementation
- State persistence using localStorage
See the example README for setup and running instructions.
Game Phases
The game follows these phases:
WAITING_FOR_HAND_CARD: Player needs to select a card from their handWAITING_FOR_FIELD_CARDS: Player needs to select matching cards from the fieldNO_MATCHES_DISCARD: No matches available, card will be discardedWAITING_FOR_DECK_MATCH: Player must capture matching cards for drawn cardWAITING_FOR_KOI_DECISION: Player must decide whether to continue (koi-koi)ROUND_END: Round is complete
Development
# Clone the repository
git clone https://github.com/fudapop/hanafuda-js.git
# Navigate to the project directory
cd hanafuda-js
# Install dependencies (if any)
deno installProject Structure
hanafuda-js/
├── src/
│ ├── core/ # Core game mechanics (cards, matching, collections)
│ ├── koikoi/ # Game state management and main game loop
│ └── scoring/ # Yaku scoring system and rules
├── tests/ # Test suites
└── README.mdLicense
MIT