Giter Site home page Giter Site logo

aprescott / tenuki Goto Github PK

View Code? Open in Web Editor NEW
101.0 11.0 25.0 795 KB

Tenuki is a web-based go board and JavaScript library

License: MIT License

JavaScript 88.41% HTML 1.77% Makefile 0.68% SCSS 9.13%
go game board board-game baduk weiqi igo web javascript html

tenuki's Introduction

Build Status

Tenuki is a web-based board and JavaScript library for the game of go/baduk/weiqi.

The API is still subject to change at any point. Treat it as beta software!

There are two main pieces:

  1. A JavaScript engine representing the board, game, and rules.
  2. A go board interface.

The JavaScript engine is not dependent on the renderer and works stand-alone. You can use it by itself as part of a larger JavaScript application.

The go board interface is intended to be a robust, functional component that can be embedded in a web page. By using the JavaScript API you could then build your own custom controls for undo/pass/etc.

The game engine supports playing an entire game and has various features and configuration settings:

  • Both Simple ko and superko rules.
  • Handicap stones, with or without free placement.
  • End-game functionality: dead stone marking and scoring.
  • Different scoring rules: territory, area, equivalence (with pass stones).
  • Komi.
  • Seki detection for territory scoring rules.

The board UI also has its own features:

  • A responsive UI for comfortably playing on touch devices and small screens.
  • Automatic board resizing to fit the layout.
  • Ko point markers.
  • Optional coordinate markers for points A19 through T1.
  • Optional fuzzy stone placement with collision movement animations.

Live examples

For live examples, see examples/, or view them on GitHub:

These examples are also set up to work on mobile/touch displays, because the board is set to fit within the browser window.

Installation

If you use npm, then npm install tenuki. Otherwise, you can download source and built files from GitHub.

It's also possible to clone this repo and run make against the latest commit, which will generate files in build/ provided you have developer dependencies satisfied.

Simple usage

Create a new tenuki.Game instance, which displays the board itself and configures click handlers on each intersection:

<link rel="stylesheet" href="build/tenuki.css">
<script src="build/tenuki.js"></script>

<div class="tenuki-board"></div>

<script>
  var boardElement = document.querySelector(".tenuki-board");
  var game = new tenuki.Game({ element: boardElement });
</script>

There are no other dependencies.

Flat stone styling

For a completely flat board with no stone shadows or gradients, add the class tenuki-board-flat:

<div class="tenuki-board tenuki-board-flat"></div>

Fuzzy stone placement

For fuzzy stone placement, pass fuzzyStonePlacement: true as a game option:

new tenuki.Game({
  fuzzyStonePlacement: true
});

When enabled, played stones will be randomly placed slightly off-center. If stones overlap after placement, existing stones are bumped out of the way.

Auto-scaling and responsiveness

By default, the .tenuki-board element will take up only the necessary amount of space in the document.

If your CSS causes the .tenuki-board HTML element to be set to a smaller size than it would ordinarily be, then the board will automatically shrink to fit within that size.

Similarly, if your CSS causes .tenuki-board to be larger than the board ordinarily would be, then the board will automatically expand to fit the container.

For example, let's say you'd like the board to be a width of 200px:

<style>
  .my-class {
    width: 200px;
  }
</style>

<div class="my-class tenuki-board"></div>

A full 19x19 board is usually larger than 200px. But, here, because of the .my-class styling, the entire board will automatically scale down to fit the 200px constraint.

Similarly, suppose the board is set to have a dynamic size based on the viewport:

<style>
  .my-class {
    width: 50%; /* say this is 50% of the body */
  }
</style>

<div class="my-class tenuki-board"></div>

Now the board will be sized dynamically. If the viewport changes, the board will resize.

Coordinate markers

For coordinate markers, indicating positions A19 through T1, add data-include-coordinates=true to the HTML element for the board:

<div class="tenuki-board" data-include-coordinates="true"></div>

SVG renderer

The default renderer uses SVG to display the board. If this is a problem, you can pass renderer: "dom" as a game setup option to switch to using a renderer based solely on DOM elements. This is not recommended. The all-DOM approach has worse performance and has alignment issues at browser zoom levels other than 100%, 200%, etc.

Board sizes other than 19x19

You can pass a boardSize option to specify the board size. If no size is given, the default of 19 is used. All sizes between 1x1 and 19x19 should work. Sizes above 19x19 will error and won't render.

var game = new tenuki.Game({
  element: boardElement,
  // use a 13x13 board
  boardSize: 13
});

Handicap stones

Handicap stones (2 through 9) are supported on sizes 9x9, 13x13 and 19x19.

new tenuki.Game({
  handicapStones: 5
});

By default, handicap placement is fixed at the traditional star points. To allow free handicap placement, set freeHandicapPlacement: true:

new tenuki.Game({
  handicapStones: 5,
  freeHandicapPlacement: true
});

Configuring scoring

The default scoring method is territory scoring. The scoring rule is configured as a setup option:

new tenuki.Game({
  scoring: "area" // default is "territory"
});

Valid scoring types are:

  • "area"
  • "territory"
  • "equivalence"

Area scoring

The score for each player under area scoring is the sum of two values:

  • The number of stones on the board.
  • The number of points of territory.

Eyes in seki count as territory under area scoring.

Territory scoring

The score for each player under territory scoring is the number of points of territory, plus opponent stones you captured.

Eyes in seki do not count as points of territory.

When territory scoring is in use, a simple detection algorithm attempts to correctly ignore each of the following as not-territory:

  1. Neutral points, consisting of intersections surrounded by neither player.
  2. Intersections which would be the point of capture for a group in atari, after filling in neutral points.
  3. Eyes in seki.

Counting eyes in seki relies on a way of determining whether a group of stones is in seki. Tenuki detects seki by counting eyes, after filling in other neutral points.

The more neutral points exist on the board, the more likely it is that seki detection will fail in some way.

It is strongly recommended that you fill in all neutral points before passing at the end of a game.

Equivalence scoring

An explanation of equivalence scoring can be found at the Sensei's Library Wiki, and a longer explanation of the equivalence can be found in a commentary appendix to the AGA Rules.

In short, equivalence scoring implements pass stones, plus the requirement that white make one final pass prior to scoring, which makes the score from counting by area equivalent to the score from counting by territory.

Note that using equivalence scoring does not change how the game ends. The game will end with 2 consecutive passes, even if black makes the 2nd pass. The final white pass stone handed to black is implemented in Tenuki by the game.score() function, not a move by a player.

Komi

The default komi value is 0. To alter the value of white's score, specify komi as an option:

new tenuki.Game({
  komi: 6.5
});

Komi is not automatically chosen based on the scoring type.

Ko and superko

The default ko rule is the simple variant: immediately recreating the previous board position is not allowed. Superko is also supported with the koRule configuration option:

new tenuki.Game({
  koRule: "positional-superko" // default is "simple"
})

Valid ko rule values are:

  • "simple" — Immediately recreating the previous board position is illegal.
  • "positional-superko" — Recreating any previous position is illegal.
  • "situational-superko" — Is it illegal for a player to recreate any previous position which that same player was responsible for creating. This is like positional superko, but takes into account the creator of the position.
  • "natural-situational-superko" — The same as situational superko, except a player may place a stone to recreate a previous position, provided that previous position was created by a pass. This is like natural situational superko, but distinguishes between passes and board plays. More details can be found at Sensei's Library.

Usage outside of a browser

The full browser environment is not required in order to use the representation of the game in JavaScript. For example, if you have a node app, you can simply create a new game without passing an element:

var Game = require("tenuki").Game;
game = new Game();

From there, the JavaScript interface is the same as in a browser console:

game.intersectionAt(0, 0).value;
// 'empty'
game.currentPlayer();
// 'black'
game.isOver();
// false
game.playAt(0, 0);
// true
game.intersectionAt(0, 0).value;
// 'black'

Game play functions

There are functions are available on a Game object that can be used to control the gameplay.

Note that all functions which take two integer coordinates (y and x) are measured from the top of the board and left of the board. So y = 0 is the top-most row, and x = 0 is the left-most row. On a 19x19 board, the top left star point (4-4) is thus at y = 3 and x = 3.

  • pass(): passes for the current player.
  • playAt(y, x): attempts to play a stone at (y, x) for the current player. If the move is illegal (because of ko, suicide, etc.), then nothing will happen. Returns true if the move is successful, otherwise false.
  • isOver(): returns true if the most recent 2 moves were passes, indicating the game is over, otherwise false.
  • markDeadAt(y, x), unmarkDeadAt(y, x) and toggleDeadAt(y, x): set the group of stones at (y, x) to dead or undead as part of marking territory. Only useful if the game is over.
  • score() returns scoring information, e.g., { black: 150, white: 130 }. Only useful if isOver() is true, since proper scoring requires dead stone marking at the end of the game. Scoring is dependent on the scoring rules in use.
  • undo(): undo the most recent move.

When rendering to a HTML board element, changing the game state will re-render the board. pass, playAt, markDeadAt, unmarkDeadAt and toggleDeadAt all support { render: false } as an option, which will skip the board rendering step. To manually render the board with render: false, call game.render() explicitly.

Post-render callbacks

There is a configurable callback, postRender, which is fired each time the board is rendered, e.g., after every move.

This is useful if you want to update some other state:

var game = new tenuki.Game(boardElement);

game.callbacks.postRender = function(game) {
  if (game.currentState().pass) {
    console.log(game.currentState().color + " passed");
  }

  if (game.currentState().playedPoint) {
    console.log(game.currentState().color + " played " + game.currentState().playedPoint.y + "," + game.currentState().playedPoint.x);
  }
};

Running tests

Run tests with npm test.

Developing

First, make sure npm is installed, then run:

npm install && make

To make changes, update individual files in src/ and scss/. Then, run make to generate files in build/.

To test changes, use npm test and load test.html in a browser. You can also smoke test the examples in examples/.

tenuki's People

Contributors

aprescott avatar head avatar maackle avatar vlinder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tenuki's Issues

How to run

Can someone please tell me how to exactly run this on a macbook air ?

How to use via npm?

Thanks for this awesome package.

I installed using npm, but I don't get a "tenuki.css" anywhere.

In fact, there is no build directory at all.

My impression is that npm install is just another way of cloning the repo, you still need to build.

(Which doesn't work inside the nom installed copy)

Built js file references `./lib/` everywhere

The built JS file is not standalone - it requires ./lib/ to be present, which makes it difficult to work with in a static webpage. (See the first 15 lines of build/tenuki.js)

Moreover, the last two releases (0.2.2 and 0.2.1) don't include build and/or lib directories.

No Releases Available

The github readme says you can download files from the latest releases page, but there are no releases there.

How to set stone before game start?

HI,

How can I set stone on board before game start? I have read the doc and load the board successfully, but how can I set stones on the board when I render a flash new game?

Packaging issues

There's some awkwardness with the node and bower packaging setup right now.

Current setup

  • src/ is the actual source.
  • Babel generates lib/ content for compatibility. lib/ is not in the repo. lib/ is included in published npm releases.
  • build/ contains files for browser use. JS files are generated by Browserify. Minified files are then produced by uglify and cleancss. These are included in the repo, but not included in npm releases.

This has a few issues:

  1. npm install aprescott/tenuki (to install from GitHub) is broken because lib/ isn't included in the git source.
  2. Keeping generated files in the repo is just a bad idea. build/ diffs ruin rebasing all the time, for example.
  3. Bower apparently doesn't want minified files for its main field in bower.json: 'bower invalid-meta The "main" field cannot contain minified files'.

Goals

  1. Maintain a single source tree in ES6.
  2. Browser support with ease of installation, even for those without full ES6 support.
  3. Node support, even versions without full ES6 support.
  4. No generated files in the repo. (And generated files should have license headers that'll be preserved by any downstream minifiers.)
  5. Installing from the git repo.
  6. Bower support? It exists right now, at least.

Some of these may conflict.

Thoughts

Is it actually possible to support npm install aprescott/tenuki without extra steps if it's necessary to generate lib/?

GitHub's releases page could host build/ files. That'd make it easy for people who only care about a pure-browser setup to get up and running.

Bower doesn't really have releases in the same way as npm. It installs directly from the git repo, so if the files in a Bower package are not in the repo, then they won't be available immediately after bower install. This conflicts with not having generated files in the repo. Bower seems like a bad fit for JavaScript that isn't explicitly written at source to work in a browser. My first thought is to just remove Bower support entirely. (Side note: removing bower.json doesn't appear to stop bower install for the last tag to have a bower.json.) Maybe there's a way to get Bower to use the built files that'll be available for browser folks?

Loading boards

Is there a way to start from an existing board instead of from an empty board?

Help to make it work!

Can someone explain to me how i am supposed to make it work if i don't have all the code? Can someone help me make a html file that can compile all that code? I tried to make the rules (i have the board and interface) myself, but i couldn't. I just need to know how the rules works

Support for only showing part of the board

I'm considering using tenuki for a tsumego website along the lines of what GoGrinder used to do locally. For tsumego it would be really helpful to be able to only render enough of the board to contain the problem. It's up to the user to know how large of a region they require, but could I put in a feature request to support only rendering a corner of the board?

Do you know KataGo and WGo.js? Why repeat work?

KataGo is a Go-playing AI after AlphaGo and it has a rule set that supports almost all rules of Go.
WGo.js is a JavaScript Go library that can plot Go boards and manage Go games.
It looks like you repeat those work which some other people have done several years ago.

API for navigating history

It would be great if tenuki had some kind of API for scrubbing the history. I'd like to use tenuki for demonstration purposes, show casing a series of moves with buttons for the user to go forward and backward with.

Resigning a game

There is no way to resign a game that I can find.

Is this intentionally left out for the implementor to add?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.