connect-four
Version:
Lightweight connect-four game logic
103 lines (81 loc) • 1.85 kB
JavaScript
'use strict';
var Emitter = require('events');
var checkWin = require('./checkWin');
function Game (settings) {
settings = settings || {};
this._events = {};
this.rows = settings.rows || 6;
this.cols = settings.cols || 7;
this.board = settings.board || {};
this.cells = this.rows * this.cols;
this.on('play', checkWin);
}
var API = Game.prototype = new Emitter();
API.setMaxListeners(Infinity);
API.constructor = Game;
API.ended = false;
API.winner = null;
API.format = function (col, row) {
return col + ':' + row;
};
API.get = function (col, row) {
var prop = this.format(col, row);
var has = this.board.hasOwnProperty(prop);
return has ? this.board[prop] : null;
};
API.played = function (col) {
var prop, index = 0;
while (index < this.rows) {
prop = this.format(col, index);
if (!this.board.hasOwnProperty(prop)) {
return index;
}
index += 1;
}
return this.rows;
};
API.validMove = function (col) {
var inBounds = col >= 0 && col < this.cols;
var hasSpace = this.played(col) < this.rows;
return inBounds && hasSpace;
};
API.play = function (player, col) {
if (this.ended) {
return this;
}
var index = this.played(col);
if (!this.validMove(col)) {
throw new Error(
'Move falls out of the game: ' +
'column #' + col + '.' +
'\nUse ".validMove(column)" to check validity ' +
'before calling ".play()".'
);
}
this.board[this.format(col, index)] = player;
this.emit('play', player, {
col: col,
row: index
}, this);
if ((this.cells -= 1) <= 0) {
this.end();
}
return this;
};
API.end = function (player) {
if (this.ended) {
return this;
}
this.ended = true;
this.winner = player || null;
this.emit('end', player, this);
return this;
};
API.toJSON = function () {
return {
cols: this.cols,
rows: this.rows,
board: this.board
};
};
module.exports = Game;