UNPKG

dawikk-scan

Version:

A React Native library that integrates the powerful Scan draughts engine for both iOS and Android platforms

367 lines (287 loc) 8.79 kB
# dawikk-scan A React Native library that integrates the powerful Scan draughts (checkers) engine for both iOS and Android platforms. ## Features - Full HUB protocol support for draughts engines - Native integration with Scan draughts engine - Cross-platform support (iOS and Android) - Simple event-based API for communication with the engine - Bundled with the latest Scan engine (version 3.1) - Performance optimized for mobile devices - Configurable event throttling to prevent UI thread blocking - Selectable event emission to improve performance - Support for multiple draughts variants (Normal, Killer, BT, Frisian, Losing) - Enhanced performance with latest analysis always available ## Installation ```sh # Using npm npm install dawikk-scan --save # Or using Yarn yarn add dawikk-scan ``` ### iOS Setup ```sh cd ios && pod install ``` ## Basic Usage ```javascript import Scan from 'dawikk-scan'; // Configure the engine (optional) Scan.setConfig({ throttling: { analysisInterval: 200, // Emit analysis events every 200ms messageInterval: 300 // Emit raw messages every 300ms }, events: { emitMessage: true, // Enable/disable raw message events emitAnalysis: true, // Enable/disable analysis events emitBestMove: true // Enable/disable bestmove events } }); // Initialize the engine await Scan.init(); // Set up a listener for engine output const unsubscribeMessage = Scan.addMessageListener((message) => { console.log('Engine message:', message); }); // Send HUB commands await Scan.sendCommand('hub'); await Scan.sendCommand('init'); await Scan.sendCommand('pos pos=Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww'); await Scan.sendCommand('level depth=15'); await Scan.sendCommand('go think'); // Clean up when done unsubscribeMessage(); await Scan.shutdown(); ``` ## API Reference ### Methods #### `init()` Initializes the Scan engine. ```javascript const success = await Scan.init(); ``` #### `setConfig(config)` Configures the library's behavior regarding event throttling and emission. ```javascript Scan.setConfig({ throttling: { analysisInterval: 200, // Time in ms between analysis events messageInterval: 300 // Time in ms between message events }, events: { emitMessage: true, // Whether to emit raw message events emitAnalysis: true, // Whether to emit analysis events emitBestMove: true // Whether to emit bestMove events } }); ``` #### `sendCommand(command)` Sends a HUB command to the engine. ```javascript await Scan.sendCommand('pos pos=Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww'); await Scan.sendCommand('go think'); ``` #### `shutdown()` Shuts down the engine and frees resources. ```javascript await Scan.shutdown(); ``` #### `addMessageListener(callback)` Adds a listener for raw output messages from the engine. ```javascript const unsubscribe = Scan.addMessageListener((message) => { console.log('Engine says:', message); }); // Later, to remove the listener unsubscribe(); ``` #### `addAnalysisListener(callback)` Adds a listener for parsed analysis data. ```javascript const unsubscribe = Scan.addAnalysisListener((data) => { console.log('Analysis data:', data); console.log('Best move:', data.bestMove); console.log('Score:', data.score); console.log('Depth:', data.depth); }); ``` #### `addBestMoveListener(callback)` Adds a dedicated listener for "bestmove" events. ```javascript const unsubscribe = Scan.addBestMoveListener((data) => { console.log('Computer chose move:', data.move); // Make the move on your draughts board }); ``` #### `analyzePosition(position, options)` Helper method to set a position and start analysis. ```javascript await Scan.analyzePosition('Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww', { depth: 20, movetime: 5000 }); ``` #### `stopAnalysis()` Stops the current analysis. ```javascript await Scan.stopAnalysis(); ``` #### `getComputerMove(position, movetime, depth)` Helper method to get a computer move in a game. ```javascript // Computer has 1 second to choose a move await Scan.getComputerMove('Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww', 1000, 15); ``` ### Data Structures #### ScanConfig ```typescript interface ScanConfig { throttling: { analysisInterval: number; // Time in ms between analysis event emissions messageInterval: number; // Time in ms between message event emissions }; events: { emitMessage: boolean; // Whether to emit raw message events emitAnalysis: boolean; // Whether to emit analysis events emitBestMove: boolean; // Whether to emit bestMove events }; } ``` #### AnalysisData ```typescript interface AnalysisData { type: 'info' | 'bestmove'; depth?: number; score?: number; bestMove?: string; line?: string; move?: string; nodes?: number; time?: number; nps?: number; } ``` #### BestMoveData ```typescript interface BestMoveData { type: 'bestmove'; move: string; ponder?: string; } ``` ## Position Format Positions in Scan use a specific format: - First character: side to move ('W' for white, 'B' for black) - Followed by 50 characters representing the board squares - Characters: 'w' (white man), 'b' (black man), 'W' (white king), 'B' (black king), 'e' (empty) Example starting position: `Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww` ## Move Format Moves are in standard draughts notation: - Quiet moves: `32-28` - Captures: `28x19x23` (all captured pieces listed) ## Common HUB Commands ```javascript // Initialize engine await Scan.sendCommand('hub'); await Scan.sendCommand('init'); // Set up position await Scan.sendCommand('pos pos=Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww'); // Set analysis depth await Scan.sendCommand('level depth=20'); // Set time limit (in seconds) await Scan.sendCommand('level move-time=3'); // Start analysis await Scan.sendCommand('go analyze'); // Start thinking for a move await Scan.sendCommand('go think'); // Stop calculation await Scan.sendCommand('stop'); // Clear transposition table await Scan.sendCommand('new-game'); // Set engine parameters await Scan.sendCommand('set-param name=variant value=normal'); ``` ## Draughts Variants Scan supports multiple draughts variants: - `normal` - International draughts (10×10) - `killer` - Killer draughts - `bt` - Breakthrough draughts - `frisian` - Frisian draughts - `losing` - Losing draughts (giveaway) Set variant with: ```javascript await Scan.sendCommand('set-param name=variant value=frisian'); ``` ## Example: Playing Against Computer ```javascript import Scan from 'dawikk-scan'; class DraughtsGame { constructor() { this.initialize(); } async initialize() { // Configure for optimal game performance Scan.setConfig({ events: { emitMessage: false, // No need for raw messages emitAnalysis: false, // No need for analysis data emitBestMove: true // Only need the final move } }); await Scan.init(); // Listen for computer moves this.unsubscribe = Scan.addBestMoveListener((data) => { console.log('Computer move:', data.move); this.makeMove(data.move); }); // Initialize engine await Scan.sendCommand('hub'); await Scan.sendCommand('init'); } async makePlayerMove(move) { // Update position after player move // ... update your game state ... // Ask computer to respond await Scan.getComputerMove(this.getCurrentPosition(), 2000, 15); } makeMove(move) { // Apply move to your game board console.log('Applying move:', move); // ... update your game state ... } getCurrentPosition() { // Return current position in HUB format return 'Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww'; // example } cleanup() { this.unsubscribe(); Scan.shutdown(); } } ``` ## Performance Tips 1. **Disable unnecessary events**: ```javascript // For computer games Scan.setConfig({ events: { emitMessage: false, emitAnalysis: false, emitBestMove: true } }); // For position analysis Scan.setConfig({ events: { emitMessage: false, emitAnalysis: true, emitBestMove: false } }); ``` 2. **Adjust throttling for your needs**: ```javascript // More responsive (updates more frequently) Scan.setConfig({ throttling: { analysisInterval: 100, messageInterval: 150 } }); // Smoother UI (less frequent updates) Scan.setConfig({ throttling: { analysisInterval: 300, messageInterval: 400 } }); ``` ## License This project is licensed under the GPL-3.0 License, as it includes Scan code which is GPL-3.0 licensed. For more information about Scan, visit the official repository.