Tenuki is a JavaScript implementation of the game of go/baduk/weiqi with full support for HTML rendering out of the box.
The API is still subject to change at any point. Treat it as beta software!
There are two main pieces. First, an interactive HTML go board with all the basic rules of the game. Second, a JavaScript interface to control gameplay. By hooking into the JavaScript API, you can extend the board to, e.g., create your own UI for undo, etc.
Features:
- Ko rule.
- Pass.
- Undo.
- Optional gutter markers for points A19 through T1.
- Built-in mobile support for touch devices and small screens, even with a 19x19 board.
- End-game detection: dead stone marking, area/territory scoring.
For live examples, see examples/
, or view them on GitHub:
example_with_simple_controls.html
— Board with an example of simple custom controls and updating game info.example_with_simple_controls_and_gutter.html
— Same as above, but with the A19 to T1 gutter markers.example_multiboard.html
— Multiple 9x9 boards on a single page.example.html
— Just the board.
These examples are also set up to work on mobile/touch displays.
- With bower:
bower install tenuki
- With npm:
npm install tenuki
- Download the
zip
ortar.gz
file for a specific version from the releases page, then usebuild/
however you want.
You can also clone this repo and get the build/
files that way.
Create a new tenuki.Game
instance with a DOM element, then call setup()
, 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(boardElement);
game.setup();
</script>
There are no other dependencies.
For a textured board, add the class tenuki-board-textured
:
<div class="tenuki-board tenuki-board-textured"></div>
You can pass a second argument to new tenuki.Game
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.
// use a 13x13 board
new tenuki.Game(boardElement, 13);
I've tested this on Chrome, Firefox, Safari and Opera.
On a desktop, because the browser is rendered with pure CSS and no images, there are some pixel rounding issues when the browser's zoom level is not 100% after zooming with Ctrl-+
(or Cmd-+
). This can create positioning/alignment problems, for instance, at 110%, because widths and lines on the board are not consistent with each other.
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();
// game.boardSize = 13;
game.setup();
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'
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. Returnstrue
if the move is successful, otherwisefalse
.isOver()
: returnstrue
if the most recent 2 moves were passes, indicating the game is over, otherwisefalse
.toggleDeadAt(y, x)
: sets the group of stones at(y, x)
to be dead as part of marking territory. Only useful ifisOver()
istrue
.territoryScore()
andareaScore()
: return an object containing score information, e.g.,{ black: 150, white: 130 }
. Only useful ifisOver()
istrue
, since proper scoring requires dead stone marking at the end of the game.undo()
: undo the most recent move.
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.setup();
game.callbacks.postRender = function(game) {
if (game.currentMove().pass) {
console.log(game.currentMove().color + " passed");
} else {
console.log(game.currentMove().color + " played " + game.currentMove().y + "," + game.currentMove().x);
}
};
Open test.html
in your browser. If the tests all pass, you'll see "PASS" shown with black stones.
You'll need browserify
. You can install it with npm
by running npm install -g browserify
.
To make changes, update individual files in lib/
and css/
. Then, run ./build.sh
to generate build/js/tenuki.js
and build/css/tenuki.css
, suitable for use in a browser.
To test changes, use test.html
and the files in examples/
to check that things still work.