UNPKG

connect-four

Version:

Lightweight connect-four game logic

264 lines (222 loc) 5.68 kB
/* globals describe, it, beforeEach*/ 'use strict'; var expect = require('chai').expect; var Game = require('../src/Game'); var game; beforeEach(function () { game = new Game(); }); describe('Game dimensions', function () { it('should respect the width and height instructed', function () { game = new Game({ cols: 10, rows: 10 }); expect(game.cols).to.eq(10); expect(game.rows).to.eq(10); }); it('should set it\'s own constructor', function () { expect(game.constructor).to.eq(Game); }); it('should default to standard size', function () { expect(game.rows).to.eq(6); expect(game.cols).to.eq(7); }); }); describe('A game', function () { it('should accept an existing board', function () { var board = {}; game = new Game({ board: board }); expect(game.board).to.eq(board); }); it('should serialize just the board to json', function () { var copy = JSON.parse(JSON.stringify(game)); expect(copy).to.deep.eq({ rows: game.rows, cols: game.cols, board: game.board }); }); it('should scope events to itself', function () { var comparison = new Game(); comparison.on('play', function () { throw new Error('Event leaked to another instance'); }); game.play('red', 3); }); it('should return the player when given coords', function () { var play = game.get(4, 5); expect(play).to.eq(null); }); it('should keep track of which player played a turn', function () { game.play('green', 3); var player = game.get(3, 0); expect(player).to.eq('green'); }); it('should push a play above the last on a row', function () { game.play('green', 3); game.play('red', 3); expect(game.get(3, 0)).not.to.eq('red'); expect(game.get(3, 1)).to.eq('red'); }); it('should throw an error if you exceed game board height', function () { game = new Game({ rows: 1 }); game.play('green', 3); expect(game.play.bind(game, 'green', 3)).to.throw(); }); it('should throw an error if you play outside the board', function () { expect(game.play.bind(game, 'green', -3)).to.throw(); }); }); describe('A move', function () { it('should be invalid if outside the boundaries', function () { var valid = game.validMove(-1); valid = valid || game.validMove(7); expect(valid).to.eq(false); }); it('should be valid if inside the boundaries', function () { var valid = game.validMove(0); valid = valid && game.validMove(6); valid = valid && game.validMove(3); expect(valid).to.eq(true); }); it('should be invalid if no space is left on top', function () { game = new Game({ rows: 1 }); game.play('green', 0); expect(game.validMove(0)).to.eq(false); }); it('should trigger an event', function () { var player, board; game.on('play', function (name, coord) { player = name; board = coord; }); game.play('blue', 3); expect(player).to.eq('blue'); expect(board.col).to.eq(3); }); it('should cancel if the game is ended', function () { game = new Game({ rows: 5, cols: 2 }); game .play('red', 0) .play('red', 0) .play('red', 0) .play('red', 0) .play('red', 1); expect(game.get(1, 0)).not.to.eq('red'); }); }); describe('A win', function () { it('should happen when four plays are lined up', function () { game.play('red', 1); game.play('red', 2); game.play('red', 3); game.play('red', 4); expect(game.ended).to.eq(true); expect(game.winner).to.eq('red'); }); it('should emit an event showing the winner', function () { var winner; game.on('end', function (player) { winner = player; }); game.play('green', 3); game.play('green', 3); game.play('green', 3); game.play('green', 3); expect(winner).to.eq('green'); }); it('should not happen if a play is prevented', function () { game.play('red', 0); game.play('green', 1); game.play('red', 2); game.play('red', 3); expect(game.winner).not.to.eq('red'); expect(game.ended).to.eq(false); }); it('should work top-left to bottom-right', function () { game .play('red', 0) .play('green', 1) .play('red', 1) .play('green', 2) .play('green', 2) .play('red', 2) .play('green', 3) .play('green', 3) .play('green', 3) .play('red', 3); expect(game.winner).to.eq('red'); }); it('should work top-right to bottom-left', function () { game .play('red', 6) .play('green', 5) .play('red', 5) .play('green', 4) .play('green', 4) .play('red', 4) .play('green', 3) .play('green', 3) .play('green', 3) .play('red', 3); expect(game.winner).to.eq('red'); }); it('should work vertically', function () { game .play('red', 0) .play('red', 0) .play('red', 0) .play('red', 0); expect(game.winner).to.eq('red'); }); it('should work horizontally', function () { game .play('red', 1) .play('red', 2) .play('red', 3) .play('red', 4); expect(game.winner).to.eq('red'); }); }); describe('A tie', function () { it('should happen when no other positions are available', function () { game = new Game({ cols: 2, rows: 2 }); game.play('green', 0) .play('green', 0) .play('green', 1) .play('green', 1); expect(game.ended).to.eq(true); expect(game.winner).to.eq(null); }); it('should fire the game end event', function () { var called = false; game = new Game({ cols: 2, rows: 2 }).on('end', function () { called = true; }); game.play('green', 0) .play('green', 0) .play('green', 1); expect(game.ended).to.eq(false); expect(called).to.eq(false); game.play('green', 1); expect(game.ended).to.eq(true); expect(game.winner).to.eq(null); expect(called).to.eq(true); }); });