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 🙏

© 2024 – Pkg Stats / Ryan Hefner

surakarta

v1.3.4

Published

Implementation of the Surakarta game

Downloads

585

Readme

Surakarta (JavaScript implementation)

This is a "stateful" library for managing Surakarta games in JavaScript projects.

Installation

npm install surakarta@latest

Usage

In this project, we refer to the pieces as "pebbles". A pebble position is filled with one of three values: RED_PLAYER, BLACK_PLAYER, and NOT_FILLED. Here, the red player refers to the one that moves first while the black player is the other one.

import { Surakarta, RED_PLAYER, BLACK_PLAYER } from 'surakarta';

class App {
  constructor() {
    this.surakarta = new Surakarta();
  }
}

Documentation

Surakarta objects have these properties:

  • states: Array<number>: This an array of 36 values that indicate which pebbles lie on each position. You can access it using indexOf(row, column) if convinient.

  • turn: number: This is the no. of moves that have occured in the game already. To get the turning player, see turnPlayer, which returns either RED_PLAYER or BLACK_PLAYER.

  • responders: Array<SurakartaResponder>[3]: This is an array of array of responder objects (see SurakartaResponder interface below). responders[0] are invoked when it is the red player's turn; responders[1] are invoked when it is the black player's turn. responders[2] are invoked on both player's turns; however, they are notified before the other two.

SurakartaResponder is an interface for objects that listen to events in the game. They should have an onTurn(surakartaInstance: Surakarta) method.

Surakarta Class

import { Surakarta } from 'surakarta`;

This is the only class that users have to familiarize with. It manages the state of a single, active Surakarta game. Apart from the properties mentioned above, the Surakarat provides the following API methods:

step

step(rs: number, cs: number, rd: number, cd: number, noResponder: boolean = false, capture: boolean = false): Void

The step method allows you to move a pebble to from position (rs,cs) to position (rd,cd). It does not do any validation of whether the move is valid, but only if the moving piece is the turning player's and if a capture is occuring when capture=false. If either of these conditions are negative, then an error is thrown.

A valid move would be where the pebble is moving one-step orthogonally or diagonally. Also, direct captures are not allowed in the Surakarta game. To validate these conditions, see safeStep below.

noRespond: Setting this to false means that Surakarta will not treat this operation as a turning move, i.e. the turn won't be incremented and the responders won't be notified.

safeStep

safeStep(rs: number, cs: number, rd: number, cd: number, noResponder: boolean): boolean

This safe-step method only passes moves that are valid, non-capturing step moves. It internally uses the global API function validateStep. It also returns true` if the move was valid.

traverse

traverse(r: number, c: number, dir: Directions, cut: [number, number] = null, saveSteps: boolean = true, perform: boolean = true, noRespond: boolean = false): {boolean | Array<[number,number]> | null}

Verifies capturing moves & operates them. The capturing move starts from (r,c) in the initial direction dir. It is valid iff its ends up on an enemy pebble.

saveSteps will tell this method to keep each intermediate position (including the last one) in an array and return them. If the move isn't valid, null will be returned instead. However, if saveSteps is set to false, then a boolean value will be returned indicating that the move is valid or not.

Surakarta's rules allow to make the "capture" optional, i.e. you can stop at an intermediate position. To indicate that you want to stop at such a position, you can set cut to a valid position that lies on the capturing move's path; however, if it does not lie on that path, it will be ignored.

perform=false will prevent the actual move from happening. It is useful to just get the intermediate positions if such a move were to occur.

forEach

forEach(callback: (state: number, r: number, c: number) => Void): Void

Iterator function that calls the callback function for each position state, providing the state value, row, and column. It is useful when a for-loop is not tasteful.

clone

clone(): Surakarta

Clones this game's state without the responders. This is useful when you want to save the history of the game.

indexOf

indexOf(r: number, c: number): number

Returns the index of the position in the states array.

Players enum

import {
  RED_PLAYER,
  BLACK_PLAYER,
  NOT_FILLED
} from 'surakarta';

This enum is used to indicate which player's pebble lies on a certain position. The RED_PLAYER is the one that moves first while the black one moves after. A NOT_FILLED indicates that the position is not held by any plaer.

Directions enum

import { Directions } from 'surakarta';

const {
  LEFT,
  UP,
  RIGHT,
  DOWN
} = Directions;

This enum is used to commnicate directions of capturing moves.

TODO: Contribute by finishing this documentation!