npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

dawikk-scan

v0.6.5

Published

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

Readme

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

# Using npm
npm install dawikk-scan --save

# Or using Yarn
yarn add dawikk-scan

iOS Setup

cd ios && pod install

Basic Usage

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.

const success = await Scan.init();

setConfig(config)

Configures the library's behavior regarding event throttling and emission.

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.

await Scan.sendCommand('pos pos=Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww');
await Scan.sendCommand('go think');

shutdown()

Shuts down the engine and frees resources.

await Scan.shutdown();

addMessageListener(callback)

Adds a listener for raw output messages from the engine.

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.

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.

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.

await Scan.analyzePosition('Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww', {
  depth: 20,
  movetime: 5000
});

stopAnalysis()

Stops the current analysis.

await Scan.stopAnalysis();

getComputerMove(position, movetime, depth)

Helper method to get a computer move in a game.

// Computer has 1 second to choose a move
await Scan.getComputerMove('Wbbbbbbbbbbbbbbbbbbbbeeeeeeeeeewwwwwwwwwwwwwwwwwwww', 1000, 15);

Data Structures

ScanConfig

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

interface AnalysisData {
  type: 'info' | 'bestmove';
  depth?: number;
  score?: number;
  bestMove?: string;
  line?: string;
  move?: string;
  nodes?: number;
  time?: number;
  nps?: number;
}

BestMoveData

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

// 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:

await Scan.sendCommand('set-param name=variant value=frisian');

Example: Playing Against Computer

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:

    // 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:

    // 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.