From c76445b732b3d750970ad96fd9083411641f3c00 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Tue, 13 Dec 2016 12:23:02 -0800 Subject: [PATCH 01/49] inital setup of src and spec files --- spec/board.spec.js | 1 + spec/game.spec.js | 1 + spec/player.spec.js | 1 + src/board.js | 12 ++++++++++++ src/game.js | 13 +++++++++++++ src/player.js | 10 ++++++++++ 6 files changed, 38 insertions(+) create mode 100644 spec/board.spec.js create mode 100644 spec/game.spec.js create mode 100644 spec/player.spec.js create mode 100644 src/board.js create mode 100644 src/game.js create mode 100644 src/player.js diff --git a/spec/board.spec.js b/spec/board.spec.js new file mode 100644 index 0000000..78b878d --- /dev/null +++ b/spec/board.spec.js @@ -0,0 +1 @@ +import Board from 'board'; diff --git a/spec/game.spec.js b/spec/game.spec.js new file mode 100644 index 0000000..ebbbb01 --- /dev/null +++ b/spec/game.spec.js @@ -0,0 +1 @@ +import Game from 'game'; diff --git a/spec/player.spec.js b/spec/player.spec.js new file mode 100644 index 0000000..a5dd2cd --- /dev/null +++ b/spec/player.spec.js @@ -0,0 +1 @@ +import Player from 'player'; diff --git a/src/board.js b/src/board.js new file mode 100644 index 0000000..b5fce3a --- /dev/null +++ b/src/board.js @@ -0,0 +1,12 @@ +var Board = function() { + +}; + + + + + + + + +export default Board; diff --git a/src/game.js b/src/game.js new file mode 100644 index 0000000..3389cc4 --- /dev/null +++ b/src/game.js @@ -0,0 +1,13 @@ +var Game = function () { + +}; + + + + + + + + + +export default Game; diff --git a/src/player.js b/src/player.js new file mode 100644 index 0000000..72878d5 --- /dev/null +++ b/src/player.js @@ -0,0 +1,10 @@ +var Player = function() { + +}; + + + + + + +export default Player; From cf6dd78272fb490e5663c53a32956124db4507b4 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Tue, 13 Dec 2016 13:50:49 -0800 Subject: [PATCH 02/49] initial test for Game is passing --- spec/game.spec.js | 9 +++++++++ src/game.js | 4 ++++ src/player.js | 4 +++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index ebbbb01..c088aa8 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -1 +1,10 @@ import Game from 'game'; + +describe('Game', function(){ + describe('constructor', function() { + it('should make a new game', function(){ + var game1 = new Game(); + expect(game1 instanceof Game).toBeTruthy(); + }); + }); +}); diff --git a/src/game.js b/src/game.js index 3389cc4..7f1beef 100644 --- a/src/game.js +++ b/src/game.js @@ -1,3 +1,7 @@ +import Player from 'player'; +import Board from 'board'; + + var Game = function () { }; diff --git a/src/player.js b/src/player.js index 72878d5..5b5bb8a 100644 --- a/src/player.js +++ b/src/player.js @@ -1,5 +1,7 @@ -var Player = function() { +import Board from 'board'; +var Player = function() { +//if Game assigns attributes, do we need to put anything here for Player? }; From 8793346cef7f830361d8266be1e7e217b751f73f Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 13 Dec 2016 14:00:21 -0800 Subject: [PATCH 03/49] game constructor tests creation of players and board --- spec/game.spec.js | 8 ++++++++ src/game.js | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/spec/game.spec.js b/spec/game.spec.js index c088aa8..4cdc220 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -1,10 +1,18 @@ import Game from 'game'; +import Player from 'player'; +import Board from 'board'; describe('Game', function(){ describe('constructor', function() { it('should make a new game', function(){ var game1 = new Game(); expect(game1 instanceof Game).toBeTruthy(); + + expect(game1.player1 instanceof Player).toBeTruthy(); + + expect(game1.player2 instanceof Player).toBeTruthy(); + + expect(game1.board instanceof Board).toBeTruthy(); }); }); }); diff --git a/src/game.js b/src/game.js index 7f1beef..f2eac34 100644 --- a/src/game.js +++ b/src/game.js @@ -3,7 +3,11 @@ import Board from 'board'; var Game = function () { + // for each game, we make two players + this.player1 = new Player(); + this.player2 = new Player(); + this.board = new Board(); }; From 9cf42a28f95c2b597fe8bbcdb1a8f0ab4a029d7d Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 13 Dec 2016 14:27:07 -0800 Subject: [PATCH 04/49] added constructor tests for Board --- spec/board.spec.js | 13 +++++++++++++ spec/game.spec.js | 6 +++++- src/board.js | 5 ++++- src/game.js | 4 +++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/spec/board.spec.js b/spec/board.spec.js index 78b878d..09b4b91 100644 --- a/spec/board.spec.js +++ b/spec/board.spec.js @@ -1 +1,14 @@ import Board from 'board'; + +describe('Board', function(){ + describe('constructor', function(){ + it('should make a positions array of length 9', function(){ + var board1 = new Board(); + expect(board1.positions instanceof Array).toBeTruthy(); + + expect(board1.positions[0]).toEqual(" "); + + expect(board1.positions.length).toEqual(9); + }); + }); +}); diff --git a/spec/game.spec.js b/spec/game.spec.js index 4cdc220..3dcc277 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -10,9 +10,13 @@ describe('Game', function(){ expect(game1.player1 instanceof Player).toBeTruthy(); + expect(game1.player1.mark).toEqual("X"); + expect(game1.player2 instanceof Player).toBeTruthy(); - expect(game1.board instanceof Board).toBeTruthy(); + expect(game1.player2.mark).toEqual("O"); + + expect(game1.board instanceof Board).toBeTruthy(); }); }); }); diff --git a/src/board.js b/src/board.js index b5fce3a..5ea3d8a 100644 --- a/src/board.js +++ b/src/board.js @@ -1,5 +1,8 @@ var Board = function() { - + this.positions = []; + for(var i = 0; i < 9; i++){ + this.positions.push(" "); + } }; diff --git a/src/game.js b/src/game.js index f2eac34..1988852 100644 --- a/src/game.js +++ b/src/game.js @@ -5,9 +5,11 @@ import Board from 'board'; var Game = function () { // for each game, we make two players this.player1 = new Player(); + this.player1.mark = "X"; this.player2 = new Player(); + this.player2.mark = "O"; - this.board = new Board(); + this.board = new Board(); }; From a1e56c71b6b39316a57f97b87bd1f5bd89208328 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Tue, 13 Dec 2016 15:14:37 -0800 Subject: [PATCH 05/49] positive and negative tests for Player play function are passing --- spec/player.spec.js | 27 +++++++++++++++++++++++++++ src/player.js | 12 +++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/spec/player.spec.js b/spec/player.spec.js index a5dd2cd..b09cd8f 100644 --- a/spec/player.spec.js +++ b/spec/player.spec.js @@ -1 +1,28 @@ import Player from 'player'; + +describe('Player', function(){ + describe('play', function(){ + it('should pass a position between 0 and 8', function(){ + var player = new Player(); + + expect(player.play(1)).toEqual(1); + + expect(player.play(0)).toEqual(0); + + expect(player.play(8)).toEqual(8); + + expect(function() { + player.play("cat"); + }).toThrow(new Error('Input must be an integer between 0 and 8')); + + expect(function() { + player.play(9); + }).toThrow(new Error('Input must be an integer between 0 and 8')); + + expect(function() { + player.play(-1); + }).toThrow(new Error('Input must be an integer between 0 and 8')); + + }); + }); +}); diff --git a/src/player.js b/src/player.js index 5b5bb8a..ef48f87 100644 --- a/src/player.js +++ b/src/player.js @@ -1,7 +1,17 @@ import Board from 'board'; var Player = function() { -//if Game assigns attributes, do we need to put anything here for Player? + +}; + +Player.prototype.play = function (position) { + if (!(Number.isInteger(position))) { + throw new Error('Input must be an integer between 0 and 8'); + } else if ( position < 0|| position > 8) { + throw new Error('Input must be an integer between 0 and 8'); + } else { + return position; + } }; From 909147df39ea9810f4bc8bcf1e95046b361083a6 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Tue, 13 Dec 2016 15:32:34 -0800 Subject: [PATCH 06/49] positive test for validPlay function in Game is passing --- spec/game.spec.js | 11 +++++++++++ spec/player.spec.js | 1 - src/game.js | 10 +++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index 3dcc277..f61ec59 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -19,4 +19,15 @@ describe('Game', function(){ expect(game1.board instanceof Board).toBeTruthy(); }); }); + + describe('validPlay', function(){ + var game2 = new Game(); + it('should return true if position is available', function() { + expect(game2.validPlay(1)).toBeTruthy(); + }); + + xit('should return false if position is unavailable', function(){ + + }); + }); }); diff --git a/spec/player.spec.js b/spec/player.spec.js index b09cd8f..77be23e 100644 --- a/spec/player.spec.js +++ b/spec/player.spec.js @@ -22,7 +22,6 @@ describe('Player', function(){ expect(function() { player.play(-1); }).toThrow(new Error('Input must be an integer between 0 and 8')); - }); }); }); diff --git a/src/game.js b/src/game.js index 1988852..b8ad0ca 100644 --- a/src/game.js +++ b/src/game.js @@ -7,11 +7,19 @@ var Game = function () { this.player1 = new Player(); this.player1.mark = "X"; this.player2 = new Player(); - this.player2.mark = "O"; + this.player2.mark = "O"; this.board = new Board(); }; +Game.prototype.validPlay = function (position) { + if(this.board.positions[position] == " ") { + return true; + } else { + return false; + } +}; + From 2d87021ad786b56dc1b902adc6c7689a42a3e490 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Tue, 13 Dec 2016 15:47:45 -0800 Subject: [PATCH 07/49] added markPlay and validPlay to Board, negative validPlay test in progress --- spec/board.spec.js | 22 +++++++++++++++++++++- spec/game.spec.js | 11 +---------- src/board.js | 15 ++++++++++++++- src/game.js | 7 ------- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/spec/board.spec.js b/spec/board.spec.js index 09b4b91..671167e 100644 --- a/spec/board.spec.js +++ b/spec/board.spec.js @@ -6,9 +6,29 @@ describe('Board', function(){ var board1 = new Board(); expect(board1.positions instanceof Array).toBeTruthy(); - expect(board1.positions[0]).toEqual(" "); + expect(board1.positions[0]).toEqual(" "); expect(board1.positions.length).toEqual(9); }); }); + + describe('validPlay', function(){ + var board2 = new Board(); + it('should return true if position is available', function() { + expect(board2.validPlay(1)).toBeTruthy(); + }); + + xit('should return false if position is unavailable', function(){ + + }); + }); + + describe('markPlay', function() { + var board2 = new Board(); + it('should mark the board with the play for that player', function(){ + expect(board2.markPlay('X', 1)).toEqual(1); + + expect(board2.positions[1]).toEqual('X'); + }); + }); }); diff --git a/spec/game.spec.js b/spec/game.spec.js index f61ec59..14dec59 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -20,14 +20,5 @@ describe('Game', function(){ }); }); - describe('validPlay', function(){ - var game2 = new Game(); - it('should return true if position is available', function() { - expect(game2.validPlay(1)).toBeTruthy(); - }); - - xit('should return false if position is unavailable', function(){ - - }); - }); + }); diff --git a/src/board.js b/src/board.js index 5ea3d8a..bdd2c86 100644 --- a/src/board.js +++ b/src/board.js @@ -2,7 +2,20 @@ var Board = function() { this.positions = []; for(var i = 0; i < 9; i++){ this.positions.push(" "); - } + } +}; + +Board.prototype.validPlay = function (position) { + if(this.positions[position] == " ") { + return true; + } else { + return false; + } +}; + +Board.prototype.markPlay = function (mark, position) { + this.positions[position] = mark; + return position; }; diff --git a/src/game.js b/src/game.js index b8ad0ca..a31d7e4 100644 --- a/src/game.js +++ b/src/game.js @@ -12,13 +12,6 @@ var Game = function () { this.board = new Board(); }; -Game.prototype.validPlay = function (position) { - if(this.board.positions[position] == " ") { - return true; - } else { - return false; - } -}; From 7bef251e238736fec1cd8838796c4fbde4fc5245 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Tue, 13 Dec 2016 15:52:25 -0800 Subject: [PATCH 08/49] updated markPlay --- src/board.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/board.js b/src/board.js index bdd2c86..aaafa92 100644 --- a/src/board.js +++ b/src/board.js @@ -11,11 +11,15 @@ Board.prototype.validPlay = function (position) { } else { return false; } -}; +}; Board.prototype.markPlay = function (mark, position) { - this.positions[position] = mark; - return position; + if (this.validPlay(position)) { + this.positions[position] = mark; + return position; + } else { + throw new Error('that position is already taken'); + } }; From d3707b7686ab853dd54addba8527b6fc84a0fda9 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Wed, 14 Dec 2016 09:34:25 -0800 Subject: [PATCH 09/49] added negative test case for validPlay and added error handling for markPlay --- spec/board.spec.js | 12 +++++++++++- src/board.js | 4 +++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/spec/board.spec.js b/spec/board.spec.js index 671167e..0d74ea0 100644 --- a/spec/board.spec.js +++ b/spec/board.spec.js @@ -18,8 +18,12 @@ describe('Board', function(){ expect(board2.validPlay(1)).toBeTruthy(); }); - xit('should return false if position is unavailable', function(){ + it('should return false if position is unavailable', function(){ + expect(board2.validPlay(2)).toBeTruthy(); + board2.markPlay('X', 2); + + expect(board2.validPlay(2)).toBeFalsy(); }); }); @@ -30,5 +34,11 @@ describe('Board', function(){ expect(board2.positions[1]).toEqual('X'); }); + + it('should throw an error if 2 arguments are not passed to it', function(){ + expect(function() { + board2.markPlay(2); + }).toThrow(new Error('Wrong number of arguments')); + }); }); }); diff --git a/src/board.js b/src/board.js index aaafa92..d23e428 100644 --- a/src/board.js +++ b/src/board.js @@ -14,7 +14,9 @@ Board.prototype.validPlay = function (position) { }; Board.prototype.markPlay = function (mark, position) { - if (this.validPlay(position)) { + if(position === undefined) { + throw new Error('Wrong number of arguments'); + } else if(this.validPlay(position)) { this.positions[position] = mark; return position; } else { From e815d32cbc10e990f4085dad4411e137e8c679e3 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Wed, 14 Dec 2016 09:59:43 -0800 Subject: [PATCH 10/49] built toggleTurn in Game and wrote passing positive test --- spec/game.spec.js | 9 ++++++++- src/game.js | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index 14dec59..0ea4b33 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -17,8 +17,15 @@ describe('Game', function(){ expect(game1.player2.mark).toEqual("O"); expect(game1.board instanceof Board).toBeTruthy(); + + expect(game1.turn).toEqual(game1.player1); }); }); - + describe('toggleTurn', function() { + var game2 = new Game(); + it('should switch to player2 after player1', function() { + expect(game2.toggleTurn()).toEqual(game2.player2); + }); + }); }); diff --git a/src/game.js b/src/game.js index a31d7e4..2d6d5a7 100644 --- a/src/game.js +++ b/src/game.js @@ -10,6 +10,18 @@ var Game = function () { this.player2.mark = "O"; this.board = new Board(); + + //starting game with turn being equal to player 1 (X) + this.turn = this.player1; +}; + +Game.prototype.toggleTurn = function () { + if (this.turn == this.player1) { + this.turn = this.player2; + } else if (this.turn == this.player2) { + this.turn = this.player1; + } + return this.turn; }; @@ -21,4 +33,7 @@ var Game = function () { + + + export default Game; From 0ee580e4ad32698af5307193cced9c000520b3b6 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Wed, 14 Dec 2016 11:24:55 -0800 Subject: [PATCH 11/49] moved all validation into board, added gameOver function, tests pass --- spec/board.spec.js | 14 ++++++++++++++ spec/game.spec.js | 20 +++++++++++++++++++- spec/player.spec.js | 36 ++++++++++++++---------------------- src/board.js | 4 +++- src/game.js | 9 +++++++++ src/player.js | 18 +++++------------- 6 files changed, 64 insertions(+), 37 deletions(-) diff --git a/spec/board.spec.js b/spec/board.spec.js index 0d74ea0..7adc392 100644 --- a/spec/board.spec.js +++ b/spec/board.spec.js @@ -16,6 +16,10 @@ describe('Board', function(){ var board2 = new Board(); it('should return true if position is available', function() { expect(board2.validPlay(1)).toBeTruthy(); + + expect(board2.validPlay(0)).toBeTruthy(); + + expect(board2.validPlay(8)).toBeTruthy(); }); it('should return false if position is unavailable', function(){ @@ -25,6 +29,16 @@ describe('Board', function(){ expect(board2.validPlay(2)).toBeFalsy(); }); + + it('should throw an error if position is not an integer', function(){ + expect(function() { + board2.validPlay("cat"); + }).toThrow(new Error('Input must be an integer between 0 and 8')); + }); + + it('will return false if position is not in the positions array', function(){ + expect(board2.validPlay(9)).toBeFalsy(); + }); }); describe('markPlay', function() { diff --git a/spec/game.spec.js b/spec/game.spec.js index 0ea4b33..b35c4a1 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -23,9 +23,27 @@ describe('Game', function(){ }); describe('toggleTurn', function() { - var game2 = new Game(); + var game2 = new Game(); it('should switch to player2 after player1', function() { expect(game2.toggleTurn()).toEqual(game2.player2); }); }); + + describe('gameOver', function(){ + var game3 = new Game(); + game3.board.positions = ["O","X","X","X","X","O","O","O","X"]; + it('should return true if all positions are filled', function(){ + expect(game3.board.positions.length).toEqual(9); + + expect(game3.gameOver()).toBeTruthy(); + }); + + it('should return false if any positions are empty string', function(){ + game3.board.positions[1] = " "; + + expect(game3.gameOver()).toBeFalsy(); + + }); + + }); }); diff --git a/spec/player.spec.js b/spec/player.spec.js index 77be23e..e145719 100644 --- a/spec/player.spec.js +++ b/spec/player.spec.js @@ -1,27 +1,19 @@ import Player from 'player'; describe('Player', function(){ - describe('play', function(){ - it('should pass a position between 0 and 8', function(){ - var player = new Player(); + // describe('play', function(){ + // it('should pass a position between 0 and 8', function(){ + // var player = new Player(); + // + // expect(player.play(1)).toEqual(1); + // + // expect(player.play(0)).toEqual(0); + // + // expect(player.play(8)).toEqual(8); - expect(player.play(1)).toEqual(1); - - expect(player.play(0)).toEqual(0); - - expect(player.play(8)).toEqual(8); - - expect(function() { - player.play("cat"); - }).toThrow(new Error('Input must be an integer between 0 and 8')); - - expect(function() { - player.play(9); - }).toThrow(new Error('Input must be an integer between 0 and 8')); - - expect(function() { - player.play(-1); - }).toThrow(new Error('Input must be an integer between 0 and 8')); - }); - }); + // expect(function() { + // player.play(-1); + // }).toThrow(new Error('Input must be an integer between 0 and 8')); + // }); + // }); }); diff --git a/src/board.js b/src/board.js index d23e428..64b94be 100644 --- a/src/board.js +++ b/src/board.js @@ -6,7 +6,9 @@ var Board = function() { }; Board.prototype.validPlay = function (position) { - if(this.positions[position] == " ") { + if (!(Number.isInteger(position))) { + throw new Error('Input must be an integer between 0 and 8'); + } else if (this.positions[position] == " ") { return true; } else { return false; diff --git a/src/game.js b/src/game.js index 2d6d5a7..36efb74 100644 --- a/src/game.js +++ b/src/game.js @@ -24,6 +24,15 @@ Game.prototype.toggleTurn = function () { return this.turn; }; +Game.prototype.gameOver = function () { + for (var i = 0; i < this.board.positions.length; i++) { + if(this.board.positions[i] == " "){ + return false; + } + } + return true; +}; + diff --git a/src/player.js b/src/player.js index ef48f87..4537a5a 100644 --- a/src/player.js +++ b/src/player.js @@ -1,18 +1,10 @@ import Board from 'board'; -var Player = function() { - -}; - -Player.prototype.play = function (position) { - if (!(Number.isInteger(position))) { - throw new Error('Input must be an integer between 0 and 8'); - } else if ( position < 0|| position > 8) { - throw new Error('Input must be an integer between 0 and 8'); - } else { - return position; - } -}; +var Player = function() {}; + +// Player.prototype.play = function (position) { +// return position; +// }; From fac54c3971dce7cc33882d613fca1b5153df5062 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Wed, 14 Dec 2016 12:04:45 -0800 Subject: [PATCH 12/49] added winHorizontal, negative and positive tests pass --- spec/game.spec.js | 27 ++++++++++++++++++++++++++- src/game.js | 11 +++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index b35c4a1..4dfb141 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -41,9 +41,34 @@ describe('Game', function(){ it('should return false if any positions are empty string', function(){ game3.board.positions[1] = " "; - expect(game3.gameOver()).toBeFalsy(); + expect(game3.gameOver()).toBeFalsy(); + }); + }); + describe('winHorizontal', function(){ + var game4 = new Game(); + it('should return false if matches are empty strings', function(){ + expect(game4.winHorizontal()).toBeFalsy(); }); + it('should return true if there is a horizontal win in the first row', function(){ + game4.board.positions = ["X","X","X","O"," ","O","O","O","X"]; + expect(game4.winHorizontal()).toBeTruthy(); + }); + + it('should return true if there is a horizontal win in the second row', function(){ + game4.board.positions = ["X","X"," ","O","O","O","X"," ","X"]; + expect(game4.winHorizontal()).toBeTruthy(); + }); + + it('should return true if there is a horizontal win in the third row', function(){ + game4.board.positions = ["X","X","O","O"," ","O","X","X","X"]; + expect(game4.winHorizontal()).toBeTruthy(); + }); + + it('should return false if there is no horizontal win yet', function (){ + game4.board.positions = ["X"," "," ","O"," "," "," "," "," "]; + expect(game4.winHorizontal()).toBeFalsy(); + }); }); }); diff --git a/src/game.js b/src/game.js index 36efb74..a1268fb 100644 --- a/src/game.js +++ b/src/game.js @@ -33,6 +33,17 @@ Game.prototype.gameOver = function () { return true; }; +Game.prototype.winHorizontal = function () { + for(var i = 0; i < this.board.positions.length; i += 3){ + if ((this.board.positions[i] == this.board.positions[i+1]) && (this.board.positions[i] == this.board.positions[i+2])){ + if(this.board.positions[i] != " "){ + return true; + } + } + } + return false; +}; + From 295efbddbc9967f6992bdd7d8a165a5b6ca04c29 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Wed, 14 Dec 2016 12:22:51 -0800 Subject: [PATCH 13/49] added winVertical and tests are passing --- spec/game.spec.js | 27 +++++++++++++++++++++++++++ src/game.js | 11 +++++++++++ 2 files changed, 38 insertions(+) diff --git a/spec/game.spec.js b/spec/game.spec.js index 4dfb141..0f31fe9 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -71,4 +71,31 @@ describe('Game', function(){ expect(game4.winHorizontal()).toBeFalsy(); }); }); + + describe('winVertical', function() { + var game5 = new Game(); + it('should return false if matches are empty strings', function(){ + expect(game5.winVertical()).toBeFalsy(); + }); + + it('should return true if there is a vertical win in the first column', function(){ + game5.board.positions = ["X"," ","X","X"," ","O","X","O","X"]; + expect(game5.winVertical()).toBeTruthy(); + }); + + it('should return true if there is a vertical win in the second column', function(){ + game5.board.positions = [" ","X"," ","O","X","O","O","X"," "]; + expect(game5.winVertical()).toBeTruthy(); + }); + + it('should return true if there is a vertical win in the third column', function(){ + game5.board.positions = [" "," ","X","O"," ","X","O","O","X"]; + expect(game5.winVertical()).toBeTruthy(); + }); + + it('should return false if there is no vertical win yet', function (){ + game5.board.positions = ["X"," "," ","O"," "," "," "," "," "]; + expect(game5.winVertical()).toBeFalsy(); + }); + }); }); diff --git a/src/game.js b/src/game.js index a1268fb..bd5a9f9 100644 --- a/src/game.js +++ b/src/game.js @@ -44,6 +44,17 @@ Game.prototype.winHorizontal = function () { return false; }; +Game.prototype.winVertical = function () { + for(var i = 0; i < 3; i++) { + if((this.board.positions[i] == this.board.positions[i+3]) && (this.board.positions[i] == this.board.positions[i+6])) { + if(this.board.positions[i] != " ") { + return true; + } + } + } + return false; +}; + From 75c58a7450b8a8ce0bd3bd3bd7e831ab9360f995 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Wed, 14 Dec 2016 13:50:28 -0800 Subject: [PATCH 14/49] tests and function written for winDiagonal --- spec/game.spec.js | 22 ++++++++++++++++++++++ src/game.js | 18 ++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/spec/game.spec.js b/spec/game.spec.js index 0f31fe9..f81a2af 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -98,4 +98,26 @@ describe('Game', function(){ expect(game5.winVertical()).toBeFalsy(); }); }); + + describe('winDiagonal', function(){ + var game5 = new Game(); + it('should return false if matches are empty strings', function(){ + expect(game5.winDiagonal()).toBeFalsy(); + }); + + it('should return true if there is a diagonal win left to right', function(){ + game5.board.positions = ["X"," ","O","X","X","O","X","O","X"]; + expect(game5.winDiagonal()).toBeTruthy(); + }); + + it('should return true if there is a diagonal win right to left', function(){ + game5.board.positions = [" ","X","O","O","O","X","O","X"," "]; + expect(game5.winDiagonal()).toBeTruthy(); + }); + + it('should return false if there is no diagonal win yet', function (){ + game5.board.positions = ["X"," "," ","O"," "," "," "," "," "]; + expect(game5.winDiagonal()).toBeFalsy(); + }); + }); }); diff --git a/src/game.js b/src/game.js index bd5a9f9..37d2062 100644 --- a/src/game.js +++ b/src/game.js @@ -55,6 +55,24 @@ Game.prototype.winVertical = function () { return false; }; +Game.prototype.winDiagonal = function () { + // both diagonals use index 4, so check to make sure that it's not an empty string, and if it is, return false + if(this.board.positions[4] == " "){ + return false; + } + + // this is the left to right diagonal + if((this.board.positions[0] == this.board.positions[4]) && (this.board.positions[0] == this.board.positions[8])) { + return true; + } + + // this is the right to left diagonal + if((this.board.positions[2] == this.board.positions[4]) && (this.board.positions[2] == this.board.positions[6])) { + return true; + } + return false; +}; + From c7cf6336ae4e18cb951736d9cb77d51527f86a33 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Wed, 14 Dec 2016 14:01:09 -0800 Subject: [PATCH 15/49] gameWin function and tests passing --- spec/game.spec.js | 21 +++++++++++++++++++++ src/game.js | 10 +++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index f81a2af..795258a 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -120,4 +120,25 @@ describe('Game', function(){ expect(game5.winDiagonal()).toBeFalsy(); }); }); + + describe('gameWin', function(){ + var game6 = new Game(); + it('should return false at game start', function(){ + expect(game6.gameWin()).toBeFalsy(); + }); + + it('should return true if a win in any direction', function(){ + game6.board.positions = ["X","X","O","O"," ","O","X","X","X"]; + expect(game6.gameWin()).toBeTruthy(); + + game6.board.positions = [" "," ","X","O"," ","X","O","O","X"]; + expect(game6.gameWin()).toBeTruthy(); + + game6.board.positions = [" ","X","O","O","O","X","O","X"," "]; + expect(game6.gameWin()).toBeTruthy(); + + }); + + + }); }); diff --git a/src/game.js b/src/game.js index 37d2062..e2edc14 100644 --- a/src/game.js +++ b/src/game.js @@ -70,7 +70,15 @@ Game.prototype.winDiagonal = function () { if((this.board.positions[2] == this.board.positions[4]) && (this.board.positions[2] == this.board.positions[6])) { return true; } - return false; + return false; +}; + +Game.prototype.gameWin = function () { + if(this.winVertical() || this.winHorizontal() || this.winDiagonal()) { + return true; + } else { + return false; + } }; From 02b5a9f27f49e146efd2fa13d67963753c0ac870 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Wed, 14 Dec 2016 14:26:35 -0800 Subject: [PATCH 16/49] modified win functions to set the player that won, tests passing --- spec/game.spec.js | 19 +++++++++++++++++-- src/game.js | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index 795258a..3211a1c 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -54,16 +54,21 @@ describe('Game', function(){ it('should return true if there is a horizontal win in the first row', function(){ game4.board.positions = ["X","X","X","O"," ","O","O","O","X"]; expect(game4.winHorizontal()).toBeTruthy(); + expect(game4.winner).toEqual(game4.player1); }); it('should return true if there is a horizontal win in the second row', function(){ game4.board.positions = ["X","X"," ","O","O","O","X"," ","X"]; + game4.turn = game4.player2; expect(game4.winHorizontal()).toBeTruthy(); + expect(game4.winner).toEqual(game4.player2); }); it('should return true if there is a horizontal win in the third row', function(){ game4.board.positions = ["X","X","O","O"," ","O","X","X","X"]; + game4.turn = game4.player1; expect(game4.winHorizontal()).toBeTruthy(); + expect(game4.winner).toEqual(game4.player1); }); it('should return false if there is no horizontal win yet', function (){ @@ -80,17 +85,23 @@ describe('Game', function(){ it('should return true if there is a vertical win in the first column', function(){ game5.board.positions = ["X"," ","X","X"," ","O","X","O","X"]; + game5.turn = game5.player1; expect(game5.winVertical()).toBeTruthy(); + expect(game5.winner).toEqual(game5.player1); }); it('should return true if there is a vertical win in the second column', function(){ game5.board.positions = [" ","X"," ","O","X","O","O","X"," "]; + game5.turn = game5.player1; expect(game5.winVertical()).toBeTruthy(); + expect(game5.winner).toEqual(game5.player1); }); it('should return true if there is a vertical win in the third column', function(){ game5.board.positions = [" "," ","X","O"," ","X","O","O","X"]; + game5.turn = game5.player1; expect(game5.winVertical()).toBeTruthy(); + expect(game5.winner).toEqual(game5.player1); }); it('should return false if there is no vertical win yet', function (){ @@ -107,12 +118,16 @@ describe('Game', function(){ it('should return true if there is a diagonal win left to right', function(){ game5.board.positions = ["X"," ","O","X","X","O","X","O","X"]; + game5.turn = game5.player1; expect(game5.winDiagonal()).toBeTruthy(); + expect(game5.winner).toEqual(game5.player1); }); it('should return true if there is a diagonal win right to left', function(){ game5.board.positions = [" ","X","O","O","O","X","O","X"," "]; + game5.turn = game5.player2; expect(game5.winDiagonal()).toBeTruthy(); + expect(game5.winner).toEqual(game5.player2); }); it('should return false if there is no diagonal win yet', function (){ @@ -136,9 +151,9 @@ describe('Game', function(){ game6.board.positions = [" ","X","O","O","O","X","O","X"," "]; expect(game6.gameWin()).toBeTruthy(); - }); - }); + + }); diff --git a/src/game.js b/src/game.js index e2edc14..6045fb5 100644 --- a/src/game.js +++ b/src/game.js @@ -13,6 +13,7 @@ var Game = function () { //starting game with turn being equal to player 1 (X) this.turn = this.player1; + this.winner = undefined; }; Game.prototype.toggleTurn = function () { @@ -37,6 +38,7 @@ Game.prototype.winHorizontal = function () { for(var i = 0; i < this.board.positions.length; i += 3){ if ((this.board.positions[i] == this.board.positions[i+1]) && (this.board.positions[i] == this.board.positions[i+2])){ if(this.board.positions[i] != " "){ + this.winner = this.turn; return true; } } @@ -48,6 +50,7 @@ Game.prototype.winVertical = function () { for(var i = 0; i < 3; i++) { if((this.board.positions[i] == this.board.positions[i+3]) && (this.board.positions[i] == this.board.positions[i+6])) { if(this.board.positions[i] != " ") { + this.winner = this.turn; return true; } } @@ -63,11 +66,13 @@ Game.prototype.winDiagonal = function () { // this is the left to right diagonal if((this.board.positions[0] == this.board.positions[4]) && (this.board.positions[0] == this.board.positions[8])) { + this.winner = this.turn; return true; } // this is the right to left diagonal if((this.board.positions[2] == this.board.positions[4]) && (this.board.positions[2] == this.board.positions[6])) { + this.winner = this.turn; return true; } return false; From f17ddf77ff2627be7ac5f112b0133c3c7a09e3ba Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Wed, 14 Dec 2016 15:22:39 -0800 Subject: [PATCH 17/49] wrote takeTurn, tests pass. wave 1 complete --- spec/game.spec.js | 27 ++++++++++++++++++++++++++- src/game.js | 16 ++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index 3211a1c..b87edd2 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -152,8 +152,33 @@ describe('Game', function(){ game6.board.positions = [" ","X","O","O","O","X","O","X"," "]; expect(game6.gameWin()).toBeTruthy(); }); - }); + describe('takeTurn', function(){ + var game = new Game(); + + it('should throw an error if the position is not valid', function(){ + game.board.positions[0] = "X"; + expect(function(){ + game.takeTurn(0);}).toThrow(new Error('that position is already taken')); + }); + + it('should return the winner if someone won', function(){ + game.board.positions = [" "," "," ","O"," ","X","O","O","X"]; + expect(game.takeTurn(2)).toEqual(game.player1); + }); + it('should return gameOver if no one wins', function(){ + game.board.positions = ["O","X","X","X","X","O","O","O"," "]; + expect(game.takeTurn(8)).toEqual("gameOver"); + }); + + it('should toggle the turn if nobody won and game is not over', function(){ + game.board.positions = ["X"," "," ","O"," "," "," "," "," "]; + expect(game.turn).toEqual(game.player1); + game.takeTurn(2); + expect(game.board.positions).toEqual(["X"," ","X","O"," "," "," "," "," "]); + expect(game.turn).toEqual(game.player2); + }); + }); }); diff --git a/src/game.js b/src/game.js index 6045fb5..bb056e7 100644 --- a/src/game.js +++ b/src/game.js @@ -86,6 +86,22 @@ Game.prototype.gameWin = function () { } }; +Game.prototype.takeTurn = function (position) { + //this.turn is whose turn it is + this.board.markPlay(this.turn.mark, position); + + //let that exception fly! + if (this.gameWin()) { + console.log("Congrats " + this.winner.mark + " !"); + return this.winner; + } else if (this.gameOver()) { + console.log("No one won. Congratulations"); + return "gameOver"; + } else { + this.toggleTurn(); + } +}; + From c2c12d0f50c9a91a3164b5594b13bf2a2c879c81 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Wed, 14 Dec 2016 15:23:53 -0800 Subject: [PATCH 18/49] cleaned up and removed console.logs --- src/game.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/game.js b/src/game.js index bb056e7..6817100 100644 --- a/src/game.js +++ b/src/game.js @@ -92,10 +92,8 @@ Game.prototype.takeTurn = function (position) { //let that exception fly! if (this.gameWin()) { - console.log("Congrats " + this.winner.mark + " !"); return this.winner; } else if (this.gameOver()) { - console.log("No one won. Congratulations"); return "gameOver"; } else { this.toggleTurn(); From 816e0e4fa4214d02ee55be27482e523b7c5d2e27 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Fri, 16 Dec 2016 15:13:48 -0800 Subject: [PATCH 19/49] set up Backbone model and view files, did html --- build/index.html | 17 +++++++++++++++++ src/app/app.js | 0 src/{ => app/models}/board.js | 0 src/{ => app/models}/game.js | 0 src/{ => app/models}/player.js | 0 src/app/views/board_view.js | 0 src/app/views/game_view.js | 0 7 files changed, 17 insertions(+) create mode 100644 src/app/app.js rename src/{ => app/models}/board.js (100%) rename src/{ => app/models}/game.js (100%) rename src/{ => app/models}/player.js (100%) create mode 100644 src/app/views/board_view.js create mode 100644 src/app/views/game_view.js diff --git a/build/index.html b/build/index.html index 00eb541..7ed7f5a 100644 --- a/build/index.html +++ b/build/index.html @@ -6,5 +6,22 @@ +
+ +
+

Tic Tac Toe with Backbone

+
+ +
+
+ +
+ +
+ +
+
+ +
diff --git a/src/app/app.js b/src/app/app.js new file mode 100644 index 0000000..e69de29 diff --git a/src/board.js b/src/app/models/board.js similarity index 100% rename from src/board.js rename to src/app/models/board.js diff --git a/src/game.js b/src/app/models/game.js similarity index 100% rename from src/game.js rename to src/app/models/game.js diff --git a/src/player.js b/src/app/models/player.js similarity index 100% rename from src/player.js rename to src/app/models/player.js diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js new file mode 100644 index 0000000..e69de29 diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js new file mode 100644 index 0000000..e69de29 From b884520f5828fe95442e9c6f4362fd71574d6fa0 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Fri, 16 Dec 2016 15:30:39 -0800 Subject: [PATCH 20/49] added document.ready to run html, tried to get tests working --- spec/{ => app/models}/board.spec.js | 0 spec/{ => app/models}/game.spec.js | 0 spec/{ => app/models}/player.spec.js | 0 src/app/app.js | 3 +++ 4 files changed, 3 insertions(+) rename spec/{ => app/models}/board.spec.js (100%) rename spec/{ => app/models}/game.spec.js (100%) rename spec/{ => app/models}/player.spec.js (100%) diff --git a/spec/board.spec.js b/spec/app/models/board.spec.js similarity index 100% rename from spec/board.spec.js rename to spec/app/models/board.spec.js diff --git a/spec/game.spec.js b/spec/app/models/game.spec.js similarity index 100% rename from spec/game.spec.js rename to spec/app/models/game.spec.js diff --git a/spec/player.spec.js b/spec/app/models/player.spec.js similarity index 100% rename from spec/player.spec.js rename to spec/app/models/player.spec.js diff --git a/src/app/app.js b/src/app/app.js index e69de29..c380210 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -0,0 +1,3 @@ +$(document).ready(function(){ + +}); From f22eaaeabb182471919727b79fa298e0a5f13bb3 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Fri, 16 Dec 2016 15:41:24 -0800 Subject: [PATCH 21/49] moved models back into src' --- spec/{app/models => }/board.spec.js | 0 spec/{app/models => }/game.spec.js | 0 spec/{app/models => }/player.spec.js | 0 src/{app/models => }/board.js | 0 src/{app/models => }/game.js | 0 src/{app/models => }/player.js | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename spec/{app/models => }/board.spec.js (100%) rename spec/{app/models => }/game.spec.js (100%) rename spec/{app/models => }/player.spec.js (100%) rename src/{app/models => }/board.js (100%) rename src/{app/models => }/game.js (100%) rename src/{app/models => }/player.js (100%) diff --git a/spec/app/models/board.spec.js b/spec/board.spec.js similarity index 100% rename from spec/app/models/board.spec.js rename to spec/board.spec.js diff --git a/spec/app/models/game.spec.js b/spec/game.spec.js similarity index 100% rename from spec/app/models/game.spec.js rename to spec/game.spec.js diff --git a/spec/app/models/player.spec.js b/spec/player.spec.js similarity index 100% rename from spec/app/models/player.spec.js rename to spec/player.spec.js diff --git a/src/app/models/board.js b/src/board.js similarity index 100% rename from src/app/models/board.js rename to src/board.js diff --git a/src/app/models/game.js b/src/game.js similarity index 100% rename from src/app/models/game.js rename to src/game.js diff --git a/src/app/models/player.js b/src/player.js similarity index 100% rename from src/app/models/player.js rename to src/player.js From e519dcd3cd1e587314ddae2e75d523d87dc69850 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Fri, 16 Dec 2016 15:45:57 -0800 Subject: [PATCH 22/49] using foundation cdn stylesheet --- build/index.html | 3 ++- src/app/models/board.js | 0 src/app/models/game.js | 0 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/app/models/board.js create mode 100644 src/app/models/game.js diff --git a/build/index.html b/build/index.html index 7ed7f5a..a84b94c 100644 --- a/build/index.html +++ b/build/index.html @@ -3,6 +3,7 @@ Tic-Tac-Toe + @@ -21,7 +22,7 @@

Tic Tac Toe with Backbone

- + diff --git a/src/app/models/board.js b/src/app/models/board.js new file mode 100644 index 0000000..e69de29 diff --git a/src/app/models/game.js b/src/app/models/game.js new file mode 100644 index 0000000..e69de29 From 586f688f65137c731362cd12c5bc5fa3c620ad9f Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Mon, 19 Dec 2016 09:31:25 -0800 Subject: [PATCH 23/49] added html/css to board to see click events --- build/css/app.css | 11 +++++++++++ build/index.html | 21 +++++++++++++++++++-- src/app/models/board.js | 3 +++ src/app/models/game.js | 5 +++++ src/app/views/board_view.js | 4 ++++ src/app/views/game_view.js | 5 +++++ 6 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 build/css/app.css diff --git a/build/css/app.css b/build/css/app.css new file mode 100644 index 0000000..b74baaf --- /dev/null +++ b/build/css/app.css @@ -0,0 +1,11 @@ +table { + width: 50%; +} + +td { + height: 100px; + width: 100px; + background-color: pink; + padding: 5px; + border: 1px solid white; +} diff --git a/build/index.html b/build/index.html index a84b94c..568bc43 100644 --- a/build/index.html +++ b/build/index.html @@ -4,7 +4,9 @@ Tic-Tac-Toe + +
@@ -14,12 +16,27 @@

Tic Tac Toe with Backbone

-
- +
Someone Won
+
+ + + + + + + + + + + + + + +
diff --git a/src/app/models/board.js b/src/app/models/board.js index e69de29..8efe5e0 100644 --- a/src/app/models/board.js +++ b/src/app/models/board.js @@ -0,0 +1,3 @@ +import Backbone from 'backbone'; + +export default Board; diff --git a/src/app/models/game.js b/src/app/models/game.js index e69de29..5baa059 100644 --- a/src/app/models/game.js +++ b/src/app/models/game.js @@ -0,0 +1,5 @@ +import Backbone from 'backbone'; +//may need to import board model + + +export default Game; diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index e69de29..34b7486 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -0,0 +1,4 @@ +import Backbone from 'backbone'; +import Board from 'app/models/board'; + +export default BoardView; diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index e69de29..9db9a04 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -0,0 +1,5 @@ +import Backbone from 'backbone'; +import Game from 'app/models/game'; +import Board from 'app/models/board'; + +export default GameView; From 991cd8a38f5e2015c170531db23392f0554db18e Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Mon, 19 Dec 2016 09:52:44 -0800 Subject: [PATCH 24/49] added imports for views and models into app.js and put app.js in right place --- src/app.js | 14 ++++++++++++++ src/app/app.js | 3 --- src/app/models/board.js | 4 ++++ src/app/models/game.js | 2 ++ src/app/views/board_view.js | 21 +++++++++++++++++++++ 5 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/app.js delete mode 100644 src/app/app.js diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..5c876d4 --- /dev/null +++ b/src/app.js @@ -0,0 +1,14 @@ +import $ from 'jquery'; +import _ from 'underscore'; +import Backbone from 'backbone'; + +import Game from 'app/models/game'; +import Board from 'app/models/board'; +import BoardView from 'app/views/board_view'; +import GameView from 'app/views/game_view'; + +$(document).ready(function(){ + var boardview = new BoardView({ + el: 'board' + }); +}); diff --git a/src/app/app.js b/src/app/app.js deleted file mode 100644 index c380210..0000000 --- a/src/app/app.js +++ /dev/null @@ -1,3 +0,0 @@ -$(document).ready(function(){ - -}); diff --git a/src/app/models/board.js b/src/app/models/board.js index 8efe5e0..d68e156 100644 --- a/src/app/models/board.js +++ b/src/app/models/board.js @@ -1,3 +1,7 @@ import Backbone from 'backbone'; +const Board = Backbone.Model.extend({ + +}); + export default Board; diff --git a/src/app/models/game.js b/src/app/models/game.js index 5baa059..22a560d 100644 --- a/src/app/models/game.js +++ b/src/app/models/game.js @@ -1,5 +1,7 @@ import Backbone from 'backbone'; //may need to import board model +const Game = Backbone.Model.extend({ +}); export default Game; diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index 34b7486..5528919 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -1,4 +1,25 @@ import Backbone from 'backbone'; import Board from 'app/models/board'; +const BoardView = Backbone.View.extend({ + initialize: function(options) { + + }, + + render: function() { + + return this; + }, + + + events: { + 'click #0': 'markPosition'; + }, + + markPosition: function(event) { + console.log('markPosition called'); + } + +}); + export default BoardView; From 298e416dd4e1171281236d1eb7e56a2248ba5b04 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Mon, 19 Dec 2016 10:15:05 -0800 Subject: [PATCH 25/49] added click handler for board squares, passing square id also --- src/app.js | 4 +++- src/app/views/board_view.js | 5 ++++- src/app/views/game_view.js | 12 ++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/app.js b/src/app.js index 5c876d4..09cc80c 100644 --- a/src/app.js +++ b/src/app.js @@ -9,6 +9,8 @@ import GameView from 'app/views/game_view'; $(document).ready(function(){ var boardview = new BoardView({ - el: 'board' + el: '.board' }); + + boardview.render(); }); diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index 5528919..d3319c1 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -7,16 +7,19 @@ const BoardView = Backbone.View.extend({ }, render: function() { + // reattach dom even listeners to our brand spanking new HTML + this.delegateEvents(); return this; }, events: { - 'click #0': 'markPosition'; + 'click td': 'markPosition' }, markPosition: function(event) { + console.log(event.currentTarget.id); console.log('markPosition called'); } diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 9db9a04..e35b2c1 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -2,4 +2,16 @@ import Backbone from 'backbone'; import Game from 'app/models/game'; import Board from 'app/models/board'; + +const GameView = Backbone.View.extend({ + initialize: function(options) { + + }, + + render: function() { + + return this; + }, +}); + export default GameView; From 2464cbfa5b9e3e4c3ee4707fc626a35057261867 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Mon, 19 Dec 2016 11:15:11 -0800 Subject: [PATCH 26/49] resolved stack overflow on gameview, click event on play again working --- src/app.js | 12 ++++++------ src/app/views/game_view.js | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/app.js b/src/app.js index 09cc80c..b66a0a5 100644 --- a/src/app.js +++ b/src/app.js @@ -2,15 +2,15 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; -import Game from 'app/models/game'; -import Board from 'app/models/board'; -import BoardView from 'app/views/board_view'; +// import Game from 'app/models/game'; +// import Board from 'app/models/board'; +// import BoardView from 'app/views/board_view'; import GameView from 'app/views/game_view'; $(document).ready(function(){ - var boardview = new BoardView({ - el: '.board' + var gameview = new GameView({ + el: '#game' }); - boardview.render(); + gameview.render(); }); diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index e35b2c1..58e6f1b 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -1,17 +1,30 @@ import Backbone from 'backbone'; -import Game from 'app/models/game'; -import Board from 'app/models/board'; +// import Game from 'app/models/game'; +// import Board from 'app/models/board'; +import BoardView from 'app/views/board_view'; const GameView = Backbone.View.extend({ initialize: function(options) { + var board = new BoardView({ + el: '.board' + }); + board.render(); }, render: function() { return this; }, + + events: { + 'click button': 'restartGame' + }, + + restartGame: function(event) { + console.log('restartGame called'); + } }); export default GameView; From 0833d3b070cc73630a3c5e663360f0458406b75e Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Mon, 19 Dec 2016 11:33:10 -0800 Subject: [PATCH 27/49] added html and CSS to get board to center and display winner/play again correctly --- build/css/app.css | 3 +++ build/index.html | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/build/css/app.css b/build/css/app.css index b74baaf..745784d 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -1,4 +1,7 @@ + + table { + padding: 20px; width: 50%; } diff --git a/build/index.html b/build/index.html index 568bc43..d25595c 100644 --- a/build/index.html +++ b/build/index.html @@ -15,13 +15,13 @@

Tic Tac Toe with Backbone

-
-
Someone Won
- +
+
Someone Won
+
-
- +
+
From 8e6bdd11abcb8e7e135d32ba74c2d632b5b9989b Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Mon, 19 Dec 2016 11:57:06 -0800 Subject: [PATCH 28/49] changed board from table to listso we can iterate through board array --- build/css/app.css | 9 +++------ build/index.html | 28 +++++++++++----------------- src/app/views/board_view.js | 9 +++++++-- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/build/css/app.css b/build/css/app.css index 745784d..305e979 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -1,11 +1,8 @@ - - -table { - padding: 20px; - width: 50%; +ul { + list-style: none; } -td { +li { height: 100px; width: 100px; background-color: pink; diff --git a/build/index.html b/build/index.html index d25595c..223d729 100644 --- a/build/index.html +++ b/build/index.html @@ -21,23 +21,17 @@

Tic Tac Toe with Backbone

-
- - - - - - - - - - - - - - - -
+
    +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index d3319c1..0fef276 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -3,10 +3,15 @@ import Board from 'app/models/board'; const BoardView = Backbone.View.extend({ initialize: function(options) { - + // var boardArray = []; }, render: function() { + const boardTable = this.$('#board-display'); + // boardTable.empty(); + + var row1 = + // reattach dom even listeners to our brand spanking new HTML this.delegateEvents(); @@ -15,7 +20,7 @@ const BoardView = Backbone.View.extend({ events: { - 'click td': 'markPosition' + 'click li': 'markPosition' }, markPosition: function(event) { From a23be33b939eb3222a069b7f3fad4f5d5d225813 Mon Sep 17 00:00:00 2001 From: Yuri Nakashima Date: Mon, 19 Dec 2016 12:03:34 -0800 Subject: [PATCH 29/49] styled ul to represent board; click handlers still work --- build/css/app.css | 1 + build/index.html | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/build/css/app.css b/build/css/app.css index 305e979..cf96d30 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -1,4 +1,5 @@ ul { + width: 50%; list-style: none; } diff --git a/build/index.html b/build/index.html index 223d729..e270b4e 100644 --- a/build/index.html +++ b/build/index.html @@ -20,17 +20,17 @@

Tic Tac Toe with Backbone

-
-
    -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • +
    +
      +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    From db278bf6997e09acbe609818da504708188a92aa Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Mon, 19 Dec 2016 12:18:44 -0800 Subject: [PATCH 30/49] moved html for board into boardview render --- src/app/views/board_view.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index 0fef276..88160bf 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -3,14 +3,18 @@ import Board from 'app/models/board'; const BoardView = Backbone.View.extend({ initialize: function(options) { - // var boardArray = []; + // this will actually come from the model, and not have anything in it at initialize. + this.positions = ["X"," "," ","O"," "," "," "," "," "]; }, render: function() { - const boardTable = this.$('#board-display'); - // boardTable.empty(); + const boardList = this.$('#board-display'); + boardList.empty(); - var row1 = + for(var i=0; i < this.positions.length; i++) { + var square = "
  • " + this.positions[i] + "
  • "; + boardList.append(square); + } // reattach dom even listeners to our brand spanking new HTML this.delegateEvents(); From 9cf1544a57cd33814429143a289bebb2fa168d47 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Mon, 19 Dec 2016 12:23:09 -0800 Subject: [PATCH 31/49] experimenting with markPosition --- src/app/views/board_view.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index 88160bf..ad4e12e 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -29,7 +29,11 @@ const BoardView = Backbone.View.extend({ markPosition: function(event) { console.log(event.currentTarget.id); + + // this should eventually set the positions array equal to whoever's turn it is, not hardcoded to "X"; + this.positions[event.currentTarget.id] = "X"; console.log('markPosition called'); + this.render(); } }); From 88b23bf6e846c86c047c7ea6cf9387f4d6c85d95 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Mon, 19 Dec 2016 15:04:35 -0800 Subject: [PATCH 32/49] moved js classes into backbone models --- spec/board.spec.js | 2 +- spec/game.spec.js | 6 +- spec/player.spec.js | 2 +- src/app/models/board.js | 27 ++++++++ src/app/models/game.js | 98 ++++++++++++++++++++++++++++ src/{ => app/models}/player.js | 5 +- src/board.js | 36 ----------- src/game.js | 115 --------------------------------- 8 files changed, 133 insertions(+), 158 deletions(-) rename src/{ => app/models}/player.js (51%) delete mode 100644 src/board.js delete mode 100644 src/game.js diff --git a/spec/board.spec.js b/spec/board.spec.js index 7adc392..4ac22ae 100644 --- a/spec/board.spec.js +++ b/spec/board.spec.js @@ -1,4 +1,4 @@ -import Board from 'board'; +import Board from 'app/models/board'; describe('Board', function(){ describe('constructor', function(){ diff --git a/spec/game.spec.js b/spec/game.spec.js index b87edd2..87cc5bd 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -1,6 +1,6 @@ -import Game from 'game'; -import Player from 'player'; -import Board from 'board'; +import Game from 'app/models/game'; +import Player from 'app/models/player'; +import Board from 'app/models/board'; describe('Game', function(){ describe('constructor', function() { diff --git a/spec/player.spec.js b/spec/player.spec.js index e145719..a8fa200 100644 --- a/spec/player.spec.js +++ b/spec/player.spec.js @@ -1,4 +1,4 @@ -import Player from 'player'; +import Player from 'app/models/player'; describe('Player', function(){ // describe('play', function(){ diff --git a/src/app/models/board.js b/src/app/models/board.js index d68e156..e6f1155 100644 --- a/src/app/models/board.js +++ b/src/app/models/board.js @@ -1,6 +1,33 @@ import Backbone from 'backbone'; const Board = Backbone.Model.extend({ + initialize: function(){ + this.positions = []; + for(var i = 0; i < 9; i++){ + this.positions.push(" "); + } + }, + + validPlay: function (position) { + if (!(Number.isInteger(position))) { + throw new Error('Input must be an integer between 0 and 8'); + } else if (this.positions[position] == " ") { + return true; + } else { + return false; + } + }, + + markPlay: function (mark, position) { + if(position === undefined) { + throw new Error('Wrong number of arguments'); + } else if(this.validPlay(position)) { + this.positions[position] = mark; + return position; + } else { + throw new Error('that position is already taken'); + } + } }); diff --git a/src/app/models/game.js b/src/app/models/game.js index 22a560d..5202b50 100644 --- a/src/app/models/game.js +++ b/src/app/models/game.js @@ -1,7 +1,105 @@ import Backbone from 'backbone'; + +import Player from 'app/models/player'; +import Board from 'app/models/board'; //may need to import board model const Game = Backbone.Model.extend({ + initialize: function(options){ + this.player1 = new Player(); + this.player1.mark = "X"; + this.player2 = new Player(); + this.player2.mark = "O"; + + this.board = new Board(); + + //starting game with turn being equal to player 1 (X) + this.turn = this.player1; + this.winner = undefined; + }, + + toggleTurn: function () { + if (this.turn == this.player1) { + this.turn = this.player2; + } else if (this.turn == this.player2) { + this.turn = this.player1; + } + return this.turn; + }, + + gameOver: function () { + for (var i = 0; i < this.board.positions.length; i++) { + if(this.board.positions[i] == " "){ + return false; + } + } + return true; + }, + + winHorizontal: function () { + for(var i = 0; i < this.board.positions.length; i += 3){ + if ((this.board.positions[i] == this.board.positions[i+1]) && (this.board.positions[i] == this.board.positions[i+2])){ + if(this.board.positions[i] != " "){ + this.winner = this.turn; + return true; + } + } + } + return false; + }, + + winVertical: function () { + for(var i = 0; i < 3; i++) { + if((this.board.positions[i] == this.board.positions[i+3]) && (this.board.positions[i] == this.board.positions[i+6])) { + if(this.board.positions[i] != " ") { + this.winner = this.turn; + return true; + } + } + } + return false; + }, + + winDiagonal: function () { + // both diagonals use index 4, so check to make sure that it's not an empty string, and if it is, return false + if(this.board.positions[4] == " "){ + return false; + } + + // this is the left to right diagonal + if((this.board.positions[0] == this.board.positions[4]) && (this.board.positions[0] == this.board.positions[8])) { + this.winner = this.turn; + return true; + } + + // this is the right to left diagonal + if((this.board.positions[2] == this.board.positions[4]) && (this.board.positions[2] == this.board.positions[6])) { + this.winner = this.turn; + return true; + } + return false; + }, + + gameWin: function () { + if(this.winVertical() || this.winHorizontal() || this.winDiagonal()) { + return true; + } else { + return false; + } + }, + + takeTurn: function (position) { + //this.turn is whose turn it is + this.board.markPlay(this.turn.mark, position); + //let that exception fly! + if (this.gameWin()) { + return this.winner; + } else if (this.gameOver()) { + return "gameOver"; + } else { + this.toggleTurn(); + } + } }); export default Game; diff --git a/src/player.js b/src/app/models/player.js similarity index 51% rename from src/player.js rename to src/app/models/player.js index 4537a5a..de45d8f 100644 --- a/src/player.js +++ b/src/app/models/player.js @@ -1,6 +1,7 @@ -import Board from 'board'; +// import Board from 'board'; +import Backbone from 'backbone'; -var Player = function() {}; +var Player = Backbone.Model.extend({}); // Player.prototype.play = function (position) { // return position; diff --git a/src/board.js b/src/board.js deleted file mode 100644 index 64b94be..0000000 --- a/src/board.js +++ /dev/null @@ -1,36 +0,0 @@ -var Board = function() { - this.positions = []; - for(var i = 0; i < 9; i++){ - this.positions.push(" "); - } -}; - -Board.prototype.validPlay = function (position) { - if (!(Number.isInteger(position))) { - throw new Error('Input must be an integer between 0 and 8'); - } else if (this.positions[position] == " ") { - return true; - } else { - return false; - } -}; - -Board.prototype.markPlay = function (mark, position) { - if(position === undefined) { - throw new Error('Wrong number of arguments'); - } else if(this.validPlay(position)) { - this.positions[position] = mark; - return position; - } else { - throw new Error('that position is already taken'); - } -}; - - - - - - - - -export default Board; diff --git a/src/game.js b/src/game.js deleted file mode 100644 index 6817100..0000000 --- a/src/game.js +++ /dev/null @@ -1,115 +0,0 @@ -import Player from 'player'; -import Board from 'board'; - - -var Game = function () { - // for each game, we make two players - this.player1 = new Player(); - this.player1.mark = "X"; - this.player2 = new Player(); - this.player2.mark = "O"; - - this.board = new Board(); - - //starting game with turn being equal to player 1 (X) - this.turn = this.player1; - this.winner = undefined; -}; - -Game.prototype.toggleTurn = function () { - if (this.turn == this.player1) { - this.turn = this.player2; - } else if (this.turn == this.player2) { - this.turn = this.player1; - } - return this.turn; -}; - -Game.prototype.gameOver = function () { - for (var i = 0; i < this.board.positions.length; i++) { - if(this.board.positions[i] == " "){ - return false; - } - } - return true; -}; - -Game.prototype.winHorizontal = function () { - for(var i = 0; i < this.board.positions.length; i += 3){ - if ((this.board.positions[i] == this.board.positions[i+1]) && (this.board.positions[i] == this.board.positions[i+2])){ - if(this.board.positions[i] != " "){ - this.winner = this.turn; - return true; - } - } - } - return false; -}; - -Game.prototype.winVertical = function () { - for(var i = 0; i < 3; i++) { - if((this.board.positions[i] == this.board.positions[i+3]) && (this.board.positions[i] == this.board.positions[i+6])) { - if(this.board.positions[i] != " ") { - this.winner = this.turn; - return true; - } - } - } - return false; -}; - -Game.prototype.winDiagonal = function () { - // both diagonals use index 4, so check to make sure that it's not an empty string, and if it is, return false - if(this.board.positions[4] == " "){ - return false; - } - - // this is the left to right diagonal - if((this.board.positions[0] == this.board.positions[4]) && (this.board.positions[0] == this.board.positions[8])) { - this.winner = this.turn; - return true; - } - - // this is the right to left diagonal - if((this.board.positions[2] == this.board.positions[4]) && (this.board.positions[2] == this.board.positions[6])) { - this.winner = this.turn; - return true; - } - return false; -}; - -Game.prototype.gameWin = function () { - if(this.winVertical() || this.winHorizontal() || this.winDiagonal()) { - return true; - } else { - return false; - } -}; - -Game.prototype.takeTurn = function (position) { - //this.turn is whose turn it is - this.board.markPlay(this.turn.mark, position); - - //let that exception fly! - if (this.gameWin()) { - return this.winner; - } else if (this.gameOver()) { - return "gameOver"; - } else { - this.toggleTurn(); - } -}; - - - - - - - - - - - - - -export default Game; From 0072d49d97c811e3f00a69cf27a427cd7854544d Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Mon, 19 Dec 2016 16:30:26 -0800 Subject: [PATCH 33/49] restartGame now makes a new Game --- src/app.js | 7 +++++-- src/app/views/board_view.js | 7 +++++-- src/app/views/game_view.js | 16 +++++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/app.js b/src/app.js index b66a0a5..b77bd34 100644 --- a/src/app.js +++ b/src/app.js @@ -2,14 +2,17 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; -// import Game from 'app/models/game'; +import Game from 'app/models/game'; // import Board from 'app/models/board'; // import BoardView from 'app/views/board_view'; import GameView from 'app/views/game_view'; $(document).ready(function(){ + var game = new Game(); + var gameview = new GameView({ - el: '#game' + el: '#game', + model: game }); gameview.render(); diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index ad4e12e..eb08fcd 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -4,7 +4,7 @@ import Board from 'app/models/board'; const BoardView = Backbone.View.extend({ initialize: function(options) { // this will actually come from the model, and not have anything in it at initialize. - this.positions = ["X"," "," ","O"," "," "," "," "," "]; + this.positions = this.model.positions; }, render: function() { @@ -12,10 +12,13 @@ const BoardView = Backbone.View.extend({ boardList.empty(); for(var i=0; i < this.positions.length; i++) { + // this should probably be a template var square = "
  • " + this.positions[i] + "
  • "; boardList.append(square); } + console.log(this.positions); + // reattach dom even listeners to our brand spanking new HTML this.delegateEvents(); @@ -30,7 +33,7 @@ const BoardView = Backbone.View.extend({ markPosition: function(event) { console.log(event.currentTarget.id); - // this should eventually set the positions array equal to whoever's turn it is, not hardcoded to "X"; + // this should eventually set the positions array equal to whoever's turn it is, not hardcoded to "X"; this.positions[event.currentTarget.id] = "X"; console.log('markPosition called'); this.render(); diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 58e6f1b..52ca97d 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -1,13 +1,16 @@ import Backbone from 'backbone'; -// import Game from 'app/models/game'; -// import Board from 'app/models/board'; +import Game from 'app/models/game'; +import Board from 'app/models/board'; import BoardView from 'app/views/board_view'; const GameView = Backbone.View.extend({ initialize: function(options) { + var playBoard = this.model.board; + var board = new BoardView({ - el: '.board' + el: '.board', + model: playBoard }); board.render(); @@ -24,6 +27,13 @@ const GameView = Backbone.View.extend({ restartGame: function(event) { console.log('restartGame called'); + var game = new Game(); + var newGame = new GameView({ + el: ('#game'), + model: game + }); + newGame.render(); + } }); From 50fad5e807ed98f3a6aa3dc0c20755aaf08a0f63 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Mon, 19 Dec 2016 17:01:14 -0800 Subject: [PATCH 34/49] trying to get play again button to work, getting multiple copies of board --- src/app/views/board_view.js | 3 +++ src/app/views/game_view.js | 1 + 2 files changed, 4 insertions(+) diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index eb08fcd..5202d98 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -31,6 +31,9 @@ const BoardView = Backbone.View.extend({ }, markPosition: function(event) { + // for some reason this is getting called multiple times when we're restarting the game in gameview + // event.stopPropagation(); + console.log(event.currentTarget.id); // this should eventually set the positions array equal to whoever's turn it is, not hardcoded to "X"; diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 52ca97d..8e47c11 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -27,6 +27,7 @@ const GameView = Backbone.View.extend({ restartGame: function(event) { console.log('restartGame called'); + this.model.destroy(); var game = new Game(); var newGame = new GameView({ el: ('#game'), From f6224a27c45020f3d210f6276b25a2f86232ae39 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 20 Dec 2016 11:58:55 -0800 Subject: [PATCH 35/49] updated player to be an attribute of game, tests pass --- spec/game.spec.js | 49 ++++++++++++++++++---------------------- spec/player.spec.js | 19 ---------------- src/app/models/game.js | 24 +++++++++----------- src/app/models/player.js | 15 ------------ 4 files changed, 33 insertions(+), 74 deletions(-) delete mode 100644 spec/player.spec.js delete mode 100644 src/app/models/player.js diff --git a/spec/game.spec.js b/spec/game.spec.js index 87cc5bd..50305ca 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -1,5 +1,4 @@ import Game from 'app/models/game'; -import Player from 'app/models/player'; import Board from 'app/models/board'; describe('Game', function(){ @@ -8,24 +7,20 @@ describe('Game', function(){ var game1 = new Game(); expect(game1 instanceof Game).toBeTruthy(); - expect(game1.player1 instanceof Player).toBeTruthy(); + expect(game1.get("player1")).toEqual("X"); - expect(game1.player1.mark).toEqual("X"); - - expect(game1.player2 instanceof Player).toBeTruthy(); - - expect(game1.player2.mark).toEqual("O"); + expect(game1.get("player2")).toEqual("O"); expect(game1.board instanceof Board).toBeTruthy(); - expect(game1.turn).toEqual(game1.player1); + expect(game1.turn).toEqual(game1.get("player1")); }); }); describe('toggleTurn', function() { var game2 = new Game(); it('should switch to player2 after player1', function() { - expect(game2.toggleTurn()).toEqual(game2.player2); + expect(game2.toggleTurn()).toEqual(game2.get("player2")); }); }); @@ -54,21 +49,21 @@ describe('Game', function(){ it('should return true if there is a horizontal win in the first row', function(){ game4.board.positions = ["X","X","X","O"," ","O","O","O","X"]; expect(game4.winHorizontal()).toBeTruthy(); - expect(game4.winner).toEqual(game4.player1); + expect(game4.winner).toEqual(game4.get("player1")); }); it('should return true if there is a horizontal win in the second row', function(){ game4.board.positions = ["X","X"," ","O","O","O","X"," ","X"]; - game4.turn = game4.player2; + game4.turn = game4.get("player2"); expect(game4.winHorizontal()).toBeTruthy(); - expect(game4.winner).toEqual(game4.player2); + expect(game4.winner).toEqual(game4.get("player2")); }); it('should return true if there is a horizontal win in the third row', function(){ game4.board.positions = ["X","X","O","O"," ","O","X","X","X"]; - game4.turn = game4.player1; + game4.turn = game4.get("player1"); expect(game4.winHorizontal()).toBeTruthy(); - expect(game4.winner).toEqual(game4.player1); + expect(game4.winner).toEqual(game4.get("player1")); }); it('should return false if there is no horizontal win yet', function (){ @@ -85,23 +80,23 @@ describe('Game', function(){ it('should return true if there is a vertical win in the first column', function(){ game5.board.positions = ["X"," ","X","X"," ","O","X","O","X"]; - game5.turn = game5.player1; + game5.turn = game5.get("player1"); expect(game5.winVertical()).toBeTruthy(); - expect(game5.winner).toEqual(game5.player1); + expect(game5.winner).toEqual(game5.get("player1")); }); it('should return true if there is a vertical win in the second column', function(){ game5.board.positions = [" ","X"," ","O","X","O","O","X"," "]; - game5.turn = game5.player1; + game5.turn = game5.get("player1"); expect(game5.winVertical()).toBeTruthy(); - expect(game5.winner).toEqual(game5.player1); + expect(game5.winner).toEqual(game5.get("player1")); }); it('should return true if there is a vertical win in the third column', function(){ game5.board.positions = [" "," ","X","O"," ","X","O","O","X"]; - game5.turn = game5.player1; + game5.turn = game5.get("player1"); expect(game5.winVertical()).toBeTruthy(); - expect(game5.winner).toEqual(game5.player1); + expect(game5.winner).toEqual(game5.get("player1")); }); it('should return false if there is no vertical win yet', function (){ @@ -118,16 +113,16 @@ describe('Game', function(){ it('should return true if there is a diagonal win left to right', function(){ game5.board.positions = ["X"," ","O","X","X","O","X","O","X"]; - game5.turn = game5.player1; + game5.turn = game5.get("player1"); expect(game5.winDiagonal()).toBeTruthy(); - expect(game5.winner).toEqual(game5.player1); + expect(game5.winner).toEqual(game5.get("player1")); }); it('should return true if there is a diagonal win right to left', function(){ game5.board.positions = [" ","X","O","O","O","X","O","X"," "]; - game5.turn = game5.player2; + game5.turn = game5.get("player2"); expect(game5.winDiagonal()).toBeTruthy(); - expect(game5.winner).toEqual(game5.player2); + expect(game5.winner).toEqual(game5.get("player2")); }); it('should return false if there is no diagonal win yet', function (){ @@ -165,7 +160,7 @@ describe('Game', function(){ it('should return the winner if someone won', function(){ game.board.positions = [" "," "," ","O"," ","X","O","O","X"]; - expect(game.takeTurn(2)).toEqual(game.player1); + expect(game.takeTurn(2)).toEqual(game.get("player1")); }); it('should return gameOver if no one wins', function(){ @@ -175,10 +170,10 @@ describe('Game', function(){ it('should toggle the turn if nobody won and game is not over', function(){ game.board.positions = ["X"," "," ","O"," "," "," "," "," "]; - expect(game.turn).toEqual(game.player1); + expect(game.turn).toEqual(game.get("player1")); game.takeTurn(2); expect(game.board.positions).toEqual(["X"," ","X","O"," "," "," "," "," "]); - expect(game.turn).toEqual(game.player2); + expect(game.turn).toEqual(game.get("player2")); }); }); }); diff --git a/spec/player.spec.js b/spec/player.spec.js deleted file mode 100644 index a8fa200..0000000 --- a/spec/player.spec.js +++ /dev/null @@ -1,19 +0,0 @@ -import Player from 'app/models/player'; - -describe('Player', function(){ - // describe('play', function(){ - // it('should pass a position between 0 and 8', function(){ - // var player = new Player(); - // - // expect(player.play(1)).toEqual(1); - // - // expect(player.play(0)).toEqual(0); - // - // expect(player.play(8)).toEqual(8); - - // expect(function() { - // player.play(-1); - // }).toThrow(new Error('Input must be an integer between 0 and 8')); - // }); - // }); -}); diff --git a/src/app/models/game.js b/src/app/models/game.js index 5202b50..9bf9f2a 100644 --- a/src/app/models/game.js +++ b/src/app/models/game.js @@ -1,28 +1,26 @@ import Backbone from 'backbone'; -import Player from 'app/models/player'; import Board from 'app/models/board'; -//may need to import board model const Game = Backbone.Model.extend({ - initialize: function(options){ - this.player1 = new Player(); - this.player1.mark = "X"; - this.player2 = new Player(); - this.player2.mark = "O"; + defaults: { + player1: "X", + player2: "O" + }, + initialize: function(options){ this.board = new Board(); //starting game with turn being equal to player 1 (X) - this.turn = this.player1; + this.turn = this.get("player1"); this.winner = undefined; }, toggleTurn: function () { - if (this.turn == this.player1) { - this.turn = this.player2; - } else if (this.turn == this.player2) { - this.turn = this.player1; + if (this.turn == this.get("player1")) { + this.turn = this.get("player2"); + } else if (this.turn == this.get("player2")) { + this.turn = this.get("player1"); } return this.turn; }, @@ -90,7 +88,7 @@ const Game = Backbone.Model.extend({ takeTurn: function (position) { //this.turn is whose turn it is - this.board.markPlay(this.turn.mark, position); + this.board.markPlay(this.turn, position); //let that exception fly! if (this.gameWin()) { diff --git a/src/app/models/player.js b/src/app/models/player.js deleted file mode 100644 index de45d8f..0000000 --- a/src/app/models/player.js +++ /dev/null @@ -1,15 +0,0 @@ -// import Board from 'board'; -import Backbone from 'backbone'; - -var Player = Backbone.Model.extend({}); - -// Player.prototype.play = function (position) { -// return position; -// }; - - - - - - -export default Player; From 094da804d8cfc2f68bcef6406c525d78410b0186 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 20 Dec 2016 12:44:36 -0800 Subject: [PATCH 36/49] turnPlay in gameview calling takeTurn on model --- src/app/models/board.js | 2 +- src/app/views/board_view.js | 5 ++--- src/app/views/game_view.js | 13 ++++++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/app/models/board.js b/src/app/models/board.js index e6f1155..3928d2f 100644 --- a/src/app/models/board.js +++ b/src/app/models/board.js @@ -10,7 +10,7 @@ const Board = Backbone.Model.extend({ validPlay: function (position) { if (!(Number.isInteger(position))) { - throw new Error('Input must be an integer between 0 and 8'); + throw new Error('Input is' + position + 'must be an integer between 0 and 8'); } else if (this.positions[position] == " ") { return true; } else { diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index 5202d98..4fc5600 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -31,13 +31,12 @@ const BoardView = Backbone.View.extend({ }, markPosition: function(event) { - // for some reason this is getting called multiple times when we're restarting the game in gameview - // event.stopPropagation(); console.log(event.currentTarget.id); + this.trigger('userPlay', {model: this.model, position: event.currentTarget.id}); // this should eventually set the positions array equal to whoever's turn it is, not hardcoded to "X"; - this.positions[event.currentTarget.id] = "X"; + // this.positions[event.currentTarget.id] = "X"; console.log('markPosition called'); this.render(); } diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 8e47c11..5e394f3 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -12,6 +12,7 @@ const GameView = Backbone.View.extend({ el: '.board', model: playBoard }); + this.listenTo(board, 'userPlay', this.turnPlay); board.render(); }, @@ -25,9 +26,17 @@ const GameView = Backbone.View.extend({ 'click button': 'restartGame' }, + turnPlay: function(options){ + console.log("turnPlay!"); + console.log(JSON.parse(options.position)); + // this.model.board.markPlay(this.model.turn, options.position); + this.model.takeTurn(JSON.parse(options.position)); + }, + restartGame: function(event) { + // this probably needs to happen up a level from here - cannot destroy all the things from within here. console.log('restartGame called'); - this.model.destroy(); + this.model.destroy(); var game = new Game(); var newGame = new GameView({ el: ('#game'), @@ -36,6 +45,8 @@ const GameView = Backbone.View.extend({ newGame.render(); } + + }); export default GameView; From dd096c7f8d53e98b3bbce7ef67e7f6bf2807b6ae Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 20 Dec 2016 14:03:36 -0800 Subject: [PATCH 37/49] cannot keep playing if someone has won --- src/app/models/game.js | 1 + src/app/views/board_view.js | 6 +----- src/app/views/game_view.js | 11 +++++++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/app/models/game.js b/src/app/models/game.js index 9bf9f2a..cf990f7 100644 --- a/src/app/models/game.js +++ b/src/app/models/game.js @@ -91,6 +91,7 @@ const Game = Backbone.Model.extend({ this.board.markPlay(this.turn, position); //let that exception fly! + // toggle turn unless someone has won or game is over. if (this.gameWin()) { return this.winner; } else if (this.gameOver()) { diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index 4fc5600..6f204e7 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -30,13 +30,9 @@ const BoardView = Backbone.View.extend({ 'click li': 'markPosition' }, - markPosition: function(event) { - - console.log(event.currentTarget.id); + markPosition: function(event) { this.trigger('userPlay', {model: this.model, position: event.currentTarget.id}); - // this should eventually set the positions array equal to whoever's turn it is, not hardcoded to "X"; - // this.positions[event.currentTarget.id] = "X"; console.log('markPosition called'); this.render(); } diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 5e394f3..7fc3ef1 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -12,6 +12,7 @@ const GameView = Backbone.View.extend({ el: '.board', model: playBoard }); + this.listenTo(board, 'userPlay', this.turnPlay); board.render(); @@ -29,8 +30,14 @@ const GameView = Backbone.View.extend({ turnPlay: function(options){ console.log("turnPlay!"); console.log(JSON.parse(options.position)); - // this.model.board.markPlay(this.model.turn, options.position); - this.model.takeTurn(JSON.parse(options.position)); + + // if no one has won yet or game is not over, call takeTurn. + if(!(this.model.gameWin() ||this.model.gameOver())){ + this.model.takeTurn(JSON.parse(options.position)); + } else { + // else, print something to the screen saying game is over. + console.log("You can't keep playing, the game is over!"); + } }, restartGame: function(event) { From 49938b7f542635ffdea102a1b97fa913c3d2c1ea Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 20 Dec 2016 14:44:22 -0800 Subject: [PATCH 38/49] added game attribute and listener for gameisOver, tests still pass --- build/css/app.css | 4 ++++ src/app/models/board.js | 2 +- src/app/models/game.js | 5 ++++- src/app/views/game_view.js | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/build/css/app.css b/build/css/app.css index cf96d30..a57f2d6 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -10,3 +10,7 @@ li { padding: 5px; border: 1px solid white; } + +.end-of-game { + display: none; +} diff --git a/src/app/models/board.js b/src/app/models/board.js index 3928d2f..e6f1155 100644 --- a/src/app/models/board.js +++ b/src/app/models/board.js @@ -10,7 +10,7 @@ const Board = Backbone.Model.extend({ validPlay: function (position) { if (!(Number.isInteger(position))) { - throw new Error('Input is' + position + 'must be an integer between 0 and 8'); + throw new Error('Input must be an integer between 0 and 8'); } else if (this.positions[position] == " ") { return true; } else { diff --git a/src/app/models/game.js b/src/app/models/game.js index cf990f7..2533b11 100644 --- a/src/app/models/game.js +++ b/src/app/models/game.js @@ -5,7 +5,8 @@ import Board from 'app/models/board'; const Game = Backbone.Model.extend({ defaults: { player1: "X", - player2: "O" + player2: "O", + isOver: false }, initialize: function(options){ @@ -31,6 +32,7 @@ const Game = Backbone.Model.extend({ return false; } } + this.set("isOver", true); return true; }, @@ -80,6 +82,7 @@ const Game = Backbone.Model.extend({ gameWin: function () { if(this.winVertical() || this.winHorizontal() || this.winDiagonal()) { + this.set("isOver", true); return true; } else { return false; diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 7fc3ef1..a81fad4 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -14,6 +14,7 @@ const GameView = Backbone.View.extend({ }); this.listenTo(board, 'userPlay', this.turnPlay); + this.listenTo(this.model, 'change', this.showBanner); board.render(); }, @@ -40,6 +41,10 @@ const GameView = Backbone.View.extend({ } }, + showBanner: function(){ + console.log("showBanner!"); + }, + restartGame: function(event) { // this probably needs to happen up a level from here - cannot destroy all the things from within here. console.log('restartGame called'); From 1c257d5a8cdf7a5e0884d39d8d56b0c0ed39cc04 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 20 Dec 2016 15:54:10 -0800 Subject: [PATCH 39/49] hiding the gameover banner on game play, displays winner at end of game --- build/css/app.css | 2 +- build/index.html | 2 +- src/app/views/game_view.js | 13 ++++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/build/css/app.css b/build/css/app.css index a57f2d6..e8d950c 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -12,5 +12,5 @@ li { } .end-of-game { - display: none; + display: none; } diff --git a/build/index.html b/build/index.html index e270b4e..3e3417b 100644 --- a/build/index.html +++ b/build/index.html @@ -16,7 +16,7 @@

    Tic Tac Toe with Backbone

    -
    Someone Won
    +
    diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index a81fad4..ac1fd9f 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -1,4 +1,5 @@ import Backbone from 'backbone'; +import $ from 'jquery'; import Game from 'app/models/game'; import Board from 'app/models/board'; import BoardView from 'app/views/board_view'; @@ -9,12 +10,13 @@ const GameView = Backbone.View.extend({ var playBoard = this.model.board; var board = new BoardView({ - el: '.board', + el: $('.board'), model: playBoard }); + this.banner = this.$('.end-of-game'); this.listenTo(board, 'userPlay', this.turnPlay); - this.listenTo(this.model, 'change', this.showBanner); + this.model.on('change:isOver', this.showBanner, this); board.render(); }, @@ -41,8 +43,13 @@ const GameView = Backbone.View.extend({ } }, - showBanner: function(){ + showBanner: function(options){ console.log("showBanner!"); + console.log(options.winner); //this is the winner, should use to populate the html. + //set the winner in the html + var message = $('#win-banner'); + message.append(options.winner + " is the winner!"); + this.banner.show(); }, restartGame: function(event) { From d7469afc75a6fc53b338344c7a5a93e238bfdefc Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Tue, 20 Dec 2016 16:27:07 -0800 Subject: [PATCH 40/49] made the board look nicer --- build/css/app.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/build/css/app.css b/build/css/app.css index e8d950c..e30b16a 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -1,3 +1,11 @@ +#game { + max-width: 600px; +} + +h1 { + text-align: center; +} + ul { width: 50%; list-style: none; @@ -9,6 +17,10 @@ li { background-color: pink; padding: 5px; border: 1px solid white; + line-height: 100px; + text-align: center; + font-size: 4em; + color: white; } .end-of-game { From f07cb659a59502eb587620ac8d30804c62a712b0 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Wed, 21 Dec 2016 10:36:48 -0800 Subject: [PATCH 41/49] play again still busted, moving on to API --- src/app/views/game_view.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index ac1fd9f..844922e 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -55,6 +55,7 @@ const GameView = Backbone.View.extend({ restartGame: function(event) { // this probably needs to happen up a level from here - cannot destroy all the things from within here. console.log('restartGame called'); + this.model.board.destroy(); this.model.destroy(); var game = new Game(); var newGame = new GameView({ @@ -62,6 +63,7 @@ const GameView = Backbone.View.extend({ model: game }); newGame.render(); + console.log(game.get("isOver")); } From 147e96d33371b1b8c65f243be7e5eb0389844419 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Wed, 21 Dec 2016 11:50:20 -0800 Subject: [PATCH 42/49] added functionality for displaying if it is a draw --- src/app/views/game_view.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 844922e..0fcf8c9 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -48,7 +48,14 @@ const GameView = Backbone.View.extend({ console.log(options.winner); //this is the winner, should use to populate the html. //set the winner in the html var message = $('#win-banner'); - message.append(options.winner + " is the winner!"); + + message.empty(); + + if (options.winner !== undefined){ + message.append(options.winner + " is the winner!"); + }else { + message.append("It's a draw.") + } this.banner.show(); }, From 7e04825049311a1689edf8d9bfb68c7bd2f0ad4c Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Thu, 22 Dec 2016 10:25:25 -0800 Subject: [PATCH 43/49] successfully posting games to API using toJSON --- src/app.js | 11 +++++----- src/app/collections/games.js | 14 ++++++++++++ src/app/models/game.js | 42 ++++++++++++++++++++++++++++-------- src/app/views/game_view.js | 8 +++---- src/app/views/games_view.js | 37 +++++++++++++++++++++++++++++++ 5 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 src/app/collections/games.js create mode 100644 src/app/views/games_view.js diff --git a/src/app.js b/src/app.js index b77bd34..ae24ea1 100644 --- a/src/app.js +++ b/src/app.js @@ -3,17 +3,18 @@ import _ from 'underscore'; import Backbone from 'backbone'; import Game from 'app/models/game'; +import Games from 'app/collections/games'; +import GamesView from 'app/views/games_view'; // import Board from 'app/models/board'; // import BoardView from 'app/views/board_view'; import GameView from 'app/views/game_view'; $(document).ready(function(){ - var game = new Game(); - var gameview = new GameView({ - el: '#game', - model: game + var games = new Games(); + var gameList = new GamesView({ + el: $('body'), //this will be something else later. + model: games }); - gameview.render(); }); diff --git a/src/app/collections/games.js b/src/app/collections/games.js new file mode 100644 index 0000000..cc7e369 --- /dev/null +++ b/src/app/collections/games.js @@ -0,0 +1,14 @@ +//this is the collection of games, specifically for interacting with the API +import Backbone from 'backbone'; +import Game from 'app/models/game'; + +var Games = Backbone.Collection.extend({ + model: Game, + url: 'http://localhost:3000/api/v1/games', + parse: function(data) { + return data.games; + } + +}); + +export default Games; diff --git a/src/app/models/game.js b/src/app/models/game.js index 2533b11..f04aae8 100644 --- a/src/app/models/game.js +++ b/src/app/models/game.js @@ -6,7 +6,8 @@ const Game = Backbone.Model.extend({ defaults: { player1: "X", player2: "O", - isOver: false + isOver: false, + winner: null }, initialize: function(options){ @@ -14,9 +15,9 @@ const Game = Backbone.Model.extend({ //starting game with turn being equal to player 1 (X) this.turn = this.get("player1"); - this.winner = undefined; }, + toggleTurn: function () { if (this.turn == this.get("player1")) { this.turn = this.get("player2"); @@ -32,7 +33,8 @@ const Game = Backbone.Model.extend({ return false; } } - this.set("isOver", true); + this.set("isOver", true); + this.set('winner', "draw"); return true; }, @@ -40,7 +42,7 @@ const Game = Backbone.Model.extend({ for(var i = 0; i < this.board.positions.length; i += 3){ if ((this.board.positions[i] == this.board.positions[i+1]) && (this.board.positions[i] == this.board.positions[i+2])){ if(this.board.positions[i] != " "){ - this.winner = this.turn; + this.set('winner',this.turn); return true; } } @@ -52,7 +54,7 @@ const Game = Backbone.Model.extend({ for(var i = 0; i < 3; i++) { if((this.board.positions[i] == this.board.positions[i+3]) && (this.board.positions[i] == this.board.positions[i+6])) { if(this.board.positions[i] != " ") { - this.winner = this.turn; + this.set('winner', this.turn); return true; } } @@ -68,13 +70,13 @@ const Game = Backbone.Model.extend({ // this is the left to right diagonal if((this.board.positions[0] == this.board.positions[4]) && (this.board.positions[0] == this.board.positions[8])) { - this.winner = this.turn; + this.set('winner', this.turn); return true; } // this is the right to left diagonal if((this.board.positions[2] == this.board.positions[4]) && (this.board.positions[2] == this.board.positions[6])) { - this.winner = this.turn; + this.set('winner', this.turn); return true; } return false; @@ -96,12 +98,34 @@ const Game = Backbone.Model.extend({ //let that exception fly! // toggle turn unless someone has won or game is over. if (this.gameWin()) { - return this.winner; + this.saveGame(); + return this.get('winner'); } else if (this.gameOver()) { - return "gameOver"; + this.saveGame(); + return 'gameOver'; } else { this.toggleTurn(); } + }, + + toJSON: function() { + + var output = { + players: [this.get('player1'), this.get('player2')], + outcome: this.get('winner'), + board: this.board.positions + }; + + return output; + }, + + saveGame: function(){ + var outcome = this.get('winner'); + this.set('outcome', outcome); + console.log("saveGame got called"); + + this.trigger('createGame', this); + // this.create(rawGame); } }); export default Game; diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 0fcf8c9..8803d13 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -45,16 +45,16 @@ const GameView = Backbone.View.extend({ showBanner: function(options){ console.log("showBanner!"); - console.log(options.winner); //this is the winner, should use to populate the html. + console.log(options.attributes.winner); //this is the winner, should use to populate the html. //set the winner in the html var message = $('#win-banner'); message.empty(); - if (options.winner !== undefined){ - message.append(options.winner + " is the winner!"); + if (options.attributes.winner !== undefined){ + message.append(options.attributes.winner + " is the winner!"); }else { - message.append("It's a draw.") + message.append("It's a draw."); } this.banner.show(); }, diff --git a/src/app/views/games_view.js b/src/app/views/games_view.js new file mode 100644 index 0000000..011d0b9 --- /dev/null +++ b/src/app/views/games_view.js @@ -0,0 +1,37 @@ +import Backbone from 'backbone'; +import $ from 'jquery'; +import Game from 'app/models/game'; +import GameView from 'app/views/game_view'; + + +const GamesView = Backbone.View.extend({ + + initialize: function(){ + + var game = new Game(); + + var gameview = new GameView({ + el: '#game', + model: game + }); + gameview.render(); + + this.listenTo(game,'createGame', this.createGame); + this.listenTo(this.model, 'add', this.addGame); + }, + + addGame: function() { + console.log("add game getting called on the collection"); + + }, + + createGame: function(options){ + console.log('create game here'); + console.log(options); + + this.model.create(options); + } + +}); + +export default GamesView; From 5f3bdf10076b34a43984f5e8714ac94477c69c62 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Thu, 22 Dec 2016 10:30:03 -0800 Subject: [PATCH 44/49] fixed bug with banner display when game ends in a draw --- src/app/views/game_view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 8803d13..6be85cd 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -51,7 +51,7 @@ const GameView = Backbone.View.extend({ message.empty(); - if (options.attributes.winner !== undefined){ + if (options.attributes.winner !== null){ message.append(options.attributes.winner + " is the winner!"); }else { message.append("It's a draw."); From 9655f271ceda870d3342e79d7ebec8fcdcd21c7d Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Thu, 22 Dec 2016 10:56:21 -0800 Subject: [PATCH 45/49] fixed failing tests with references to .winner --- spec/game.spec.js | 16 ++++++++-------- src/app/views/games_view.js | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/spec/game.spec.js b/spec/game.spec.js index 50305ca..4f5b1be 100644 --- a/spec/game.spec.js +++ b/spec/game.spec.js @@ -49,21 +49,21 @@ describe('Game', function(){ it('should return true if there is a horizontal win in the first row', function(){ game4.board.positions = ["X","X","X","O"," ","O","O","O","X"]; expect(game4.winHorizontal()).toBeTruthy(); - expect(game4.winner).toEqual(game4.get("player1")); + expect(game4.get('winner')).toEqual(game4.get("player1")); }); it('should return true if there is a horizontal win in the second row', function(){ game4.board.positions = ["X","X"," ","O","O","O","X"," ","X"]; game4.turn = game4.get("player2"); expect(game4.winHorizontal()).toBeTruthy(); - expect(game4.winner).toEqual(game4.get("player2")); + expect(game4.get('winner')).toEqual(game4.get("player2")); }); it('should return true if there is a horizontal win in the third row', function(){ game4.board.positions = ["X","X","O","O"," ","O","X","X","X"]; game4.turn = game4.get("player1"); expect(game4.winHorizontal()).toBeTruthy(); - expect(game4.winner).toEqual(game4.get("player1")); + expect(game4.get('winner')).toEqual(game4.get("player1")); }); it('should return false if there is no horizontal win yet', function (){ @@ -82,21 +82,21 @@ describe('Game', function(){ game5.board.positions = ["X"," ","X","X"," ","O","X","O","X"]; game5.turn = game5.get("player1"); expect(game5.winVertical()).toBeTruthy(); - expect(game5.winner).toEqual(game5.get("player1")); + expect(game5.get('winner')).toEqual(game5.get("player1")); }); it('should return true if there is a vertical win in the second column', function(){ game5.board.positions = [" ","X"," ","O","X","O","O","X"," "]; game5.turn = game5.get("player1"); expect(game5.winVertical()).toBeTruthy(); - expect(game5.winner).toEqual(game5.get("player1")); + expect(game5.get('winner')).toEqual(game5.get("player1")); }); it('should return true if there is a vertical win in the third column', function(){ game5.board.positions = [" "," ","X","O"," ","X","O","O","X"]; game5.turn = game5.get("player1"); expect(game5.winVertical()).toBeTruthy(); - expect(game5.winner).toEqual(game5.get("player1")); + expect(game5.get('winner')).toEqual(game5.get("player1")); }); it('should return false if there is no vertical win yet', function (){ @@ -115,14 +115,14 @@ describe('Game', function(){ game5.board.positions = ["X"," ","O","X","X","O","X","O","X"]; game5.turn = game5.get("player1"); expect(game5.winDiagonal()).toBeTruthy(); - expect(game5.winner).toEqual(game5.get("player1")); + expect(game5.get('winner')).toEqual(game5.get("player1")); }); it('should return true if there is a diagonal win right to left', function(){ game5.board.positions = [" ","X","O","O","O","X","O","X"," "]; game5.turn = game5.get("player2"); expect(game5.winDiagonal()).toBeTruthy(); - expect(game5.winner).toEqual(game5.get("player2")); + expect(game5.get('winner')).toEqual(game5.get("player2")); }); it('should return false if there is no diagonal win yet', function (){ diff --git a/src/app/views/games_view.js b/src/app/views/games_view.js index 011d0b9..7cdb288 100644 --- a/src/app/views/games_view.js +++ b/src/app/views/games_view.js @@ -30,6 +30,7 @@ const GamesView = Backbone.View.extend({ console.log(options); this.model.create(options); + console.log(this.model); } }); From dded5d0ccde8fe5219086e3d1fd2cdf3acf0876b Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Thu, 22 Dec 2016 11:05:34 -0800 Subject: [PATCH 46/49] play again refreshes page --- build/index.html | 2 +- src/app/views/game_view.js | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/build/index.html b/build/index.html index 3e3417b..0953473 100644 --- a/build/index.html +++ b/build/index.html @@ -17,7 +17,7 @@

    Tic Tac Toe with Backbone

    - +
    diff --git a/src/app/views/game_view.js b/src/app/views/game_view.js index 6be85cd..fdd5ea2 100644 --- a/src/app/views/game_view.js +++ b/src/app/views/game_view.js @@ -27,7 +27,7 @@ const GameView = Backbone.View.extend({ }, events: { - 'click button': 'restartGame' + // 'click button': 'restartGame' }, turnPlay: function(options){ @@ -59,20 +59,20 @@ const GameView = Backbone.View.extend({ this.banner.show(); }, - restartGame: function(event) { - // this probably needs to happen up a level from here - cannot destroy all the things from within here. - console.log('restartGame called'); - this.model.board.destroy(); - this.model.destroy(); - var game = new Game(); - var newGame = new GameView({ - el: ('#game'), - model: game - }); - newGame.render(); - console.log(game.get("isOver")); - - } + // restartGame: function(event) { + // // this probably needs to happen up a level from here - cannot destroy all the things from within here. + // console.log('restartGame called'); + // this.model.board.destroy(); + // this.model.destroy(); + // var game = new Game(); + // var newGame = new GameView({ + // el: ('#game'), + // model: game + // }); + // newGame.render(); + // console.log(game.get("isOver")); + // + // } }); From 276b9733e8aa207b779dc35314d8db069bf99d40 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Thu, 22 Dec 2016 11:28:18 -0800 Subject: [PATCH 47/49] fetching the collection from the api on document.ready --- src/app.js | 5 ++++- src/app/collections/games.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app.js b/src/app.js index ae24ea1..57ebf8b 100644 --- a/src/app.js +++ b/src/app.js @@ -12,9 +12,12 @@ import GameView from 'app/views/game_view'; $(document).ready(function(){ var games = new Games(); - var gameList = new GamesView({ + var gameListView = new GamesView({ el: $('body'), //this will be something else later. model: games }); + games.fetch(); + console.log(games); + }); diff --git a/src/app/collections/games.js b/src/app/collections/games.js index cc7e369..aca6700 100644 --- a/src/app/collections/games.js +++ b/src/app/collections/games.js @@ -6,7 +6,7 @@ var Games = Backbone.Collection.extend({ model: Game, url: 'http://localhost:3000/api/v1/games', parse: function(data) { - return data.games; + return data; } }); From a7ba8085c67ee9dbb952eae30267804f63883418 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Thu, 22 Dec 2016 12:33:31 -0800 Subject: [PATCH 48/49] adding html for displaying games list --- build/css/app.css | 6 +++++- build/index.html | 5 +++++ src/app/views/games_view.js | 10 +++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/build/css/app.css b/build/css/app.css index e30b16a..f63b6a6 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -1,5 +1,5 @@ #game { - max-width: 600px; + max-width: 600px; } h1 { @@ -26,3 +26,7 @@ li { .end-of-game { display: none; } + +button { + width: 45%; +} diff --git a/build/index.html b/build/index.html index 0953473..549285e 100644 --- a/build/index.html +++ b/build/index.html @@ -35,5 +35,10 @@

    Tic Tac Toe with Backbone

    +
    +
    + +
    +
    diff --git a/src/app/views/games_view.js b/src/app/views/games_view.js index 7cdb288..0388da8 100644 --- a/src/app/views/games_view.js +++ b/src/app/views/games_view.js @@ -20,6 +20,10 @@ const GamesView = Backbone.View.extend({ this.listenTo(this.model, 'add', this.addGame); }, + events: { + 'click #show-all-games': 'showGames' + }, + addGame: function() { console.log("add game getting called on the collection"); @@ -30,7 +34,11 @@ const GamesView = Backbone.View.extend({ console.log(options); this.model.create(options); - console.log(this.model); + console.log(this.model); + }, + + showGames: function(){ + console.log('show games called'); } }); From 1d43afdd7f318a10ac0a38b0890c6de6fcdef6d0 Mon Sep 17 00:00:00 2001 From: Karin Kubischta Date: Thu, 22 Dec 2016 14:50:30 -0800 Subject: [PATCH 49/49] show games button now displays all the games --- build/css/app.css | 10 +++------- build/index.html | 37 ++++++++++++++++++++++++------------- src/app/views/board_view.js | 4 ++-- src/app/views/games_view.js | 16 ++++++++++++++-- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/build/css/app.css b/build/css/app.css index f63b6a6..1ddcd24 100644 --- a/build/css/app.css +++ b/build/css/app.css @@ -1,4 +1,4 @@ -#game { +#game, #game-list { max-width: 600px; } @@ -6,12 +6,12 @@ h1 { text-align: center; } -ul { +#board-display { width: 50%; list-style: none; } -li { +.board-square { height: 100px; width: 100px; background-color: pink; @@ -26,7 +26,3 @@ li { .end-of-game { display: none; } - -button { - width: 45%; -} diff --git a/build/index.html b/build/index.html index 549285e..87f6a9c 100644 --- a/build/index.html +++ b/build/index.html @@ -15,29 +15,40 @@

    Tic Tac Toe with Backbone

    -
    -
    - +
    +
    +

    +
    +
    + +
      -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • -
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    • +
    - +
    +
    +
    +
    +
    + +
    +
    diff --git a/src/app/views/board_view.js b/src/app/views/board_view.js index 6f204e7..f92afef 100644 --- a/src/app/views/board_view.js +++ b/src/app/views/board_view.js @@ -13,7 +13,7 @@ const BoardView = Backbone.View.extend({ for(var i=0; i < this.positions.length; i++) { // this should probably be a template - var square = "
  • " + this.positions[i] + "
  • "; + var square = "
  • " + this.positions[i] + "
  • "; boardList.append(square); } @@ -30,7 +30,7 @@ const BoardView = Backbone.View.extend({ 'click li': 'markPosition' }, - markPosition: function(event) { + markPosition: function(event) { this.trigger('userPlay', {model: this.model, position: event.currentTarget.id}); console.log('markPosition called'); diff --git a/src/app/views/games_view.js b/src/app/views/games_view.js index 0388da8..1b568ad 100644 --- a/src/app/views/games_view.js +++ b/src/app/views/games_view.js @@ -38,8 +38,20 @@ const GamesView = Backbone.View.extend({ }, showGames: function(){ - console.log('show games called'); - } + // var button = this.$('#show-all-games'); + + var list = this.$('#prev-games'); + + for(var i = 0; i < this.model.length; i++){ + console.log(this.model.models[i].attributes); + var game = this.model.models[i].attributes; + + var tabledata = '' + game.id + ' Date/Time: ' + game.played_at + ' Winner: ' + game.outcome + ''; + list.append(tabledata); + } + + this.render(); + }, });