Connect-four
Simple game logic featuring "connect-four".
Why
I work for gunDB, and we're building a cool database in Javascript. To showcase some of the real-time collaborative goodness, I've made a connect-four game, which you can try here. All the app code is open source, so feel free to poke through for a working example 😉
</shameless-self-promotion>
Instead of hard coding the game logic, I figured I'd produce it as a separate npm module that other people can use.
Usage
If you haven't installed it, you can do so on npm:
$ npm install connect-four
Now you should be able to require
it from Node.js by placing this in a file:
var Game = require('connect-four');
connect-four is webpack/browserify friendly.
Connect-four exports a game constructor. You can create a new game by running
var myGame = new Game();
The constructor takes an options object with some configuration things.
Options
rows
: the number of rows in the game.cols
: the number of columns in the game.board
: an existing board from a previous game (through something like localStorage).
If you don't pass any options, they'll be filled with these defaults:
cols | rows | board |
---|---|---|
7 | 6 | {} |
The board is a record of all turns and players, and is filled using .play
.
Events
The Game
class extends EventEmitter
from node's core library. Here are some useful events you can listen for:
play
: the game has just taken another turn. You're passed 3 arguments:player
, the unique string identifier.coords
, an object containing therow
andcol
properties.game
, the instance the event was fired on.
end
: the game has just ended. You're passed two arguments:winner
, the unique ID of the player who won.game
, the instance the event fired on.
Example
var game = new Game()game.on('play', function (player, coord) { view.message('Player "' + player + '" finished their turn.') var color = view.getPlayerColor(player) view.board.set(coord, color)});
Methods
.play(player, column)
This is the equivalent of dropping a token into a slot. Be warned though, if you try to place a token in a column that's already full, you'll get a nasty error. Use validMove()
to check first (it'll also make sure it's within the game boundaries).
The first parameter, player
, is a unique string identifying the user who placed the token. What string you use is left up to you, just make sure it's consistent.
The second parameter is the column to place the token into. For instance, if your board is 7 columns wide, calling .play('green', 3)
will drop the token into column 3 (starting from zero) and index it as player 'green'.
.get(column, row)
This method retrieves the name of the player who placed the token there. The name is the unique ID you chose when calling .play
.
.validMove(column)
This method returns a boolean value. If you've entered a column that is either full or out of bounds, this method will return false
, not a valid move. Otherwise it returns true
.
.end(player)
Ends the game and sets the winner. If there is no winner, it defaults to null
. This method will only work once per instance, and won't fire an end
event twice. This all happens under the hood though, since wins and ties are automatically detected. However, if you ever need it, you know where to find it.
.ended
A simple boolean property telling whether the game has ended or not.
.winner
A string representing the match winner. If the game hasn't ended yet, it'll be null
.
.cells
A number representing the remaining spaces left. If that number hits zero, a tie is called and null
is the grand victor.
Examples
Simple game
var Game = require('connect-four')var game = new Game()game.play('green', 0)game.play('green', 1)game.play('green', 2)game.play('green', 3)// `end` event fires, 'green' wins
More complex game
var Game = require('connect-four')var game = new Game({ rows: 5, cols: 10}) game.play('red', 0);game.play('green', 1);game.play('red', 0);game.play('green', 2);game.play('red', 0);game.play('green', 3);game.play('red', 0);// game ends, 'red' wins (vertically) console.log(game.winner) // 'red'console.log(game.ended) // true
Support
If you have any questions or issues, ping us in the gitter channel.
Thanks for checking out the project!