Skip to content
Open

Done #811

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 170 additions & 1 deletion app/assets/javascripts/tictactoe.js
Original file line number Diff line number Diff line change
@@ -1 +1,170 @@
// Code your JavaScript / jQuery solution here
$(function() {
displayGames();
attachListeners();
savingGameButton();
clearGame();
});

winningCombinations = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[6,4,2]]
var turn = 0

function attachListeners() {
$('td').each(function() {
$(this).click(function(event) {
doTurn(event.target);
});
});
}

function player() {
var player = turn % 2 === 0 ? 'X' : 'O';
return player;
}

function updateState(square) {
var playerToken = player();
$(square).text(playerToken);
}

function setMessage(message) {
$('#message').text(message);
}

function doTurn(square) {
if (squareAvailable(square) && !gameOver()) {
updateState(square);
if (checkWinner() || gameTie()) {
saveGame()
resetGame();
turn = 0;
} else {
turn++;
}
}
}


function checkWinner() {
if(gameWon()) {
var state = getState();
var winningCombination = winningCombinations.filter(function(combination) {
return (state[combination[0]] === state[combination[1]] && state[combination[0]] !== "") && state[combination[1]] == state[combination[2]]
});
var winner = state[winningCombination[0][1]];
setMessage(`Player ${winner} Won!`);
return true
} else {
if (gameTie()) {
setMessage(`Tie game.`);
}
return false
}
}

function resetGame() {
$('td').each(function(index, el) {
$(el).text('');
})
turn = 0;
}

function getState() {
var state = []
var squares = $('td').each(function(index, el) {
state[index] = $(el).text()
});
return state;
}

function gameWon() {
var state = getState();
return winningCombinations.some(function(combination) {
return (state[combination[0]] === state[combination[1]] && state[combination[0]] !== "") && state[combination[1]] == state[combination[2]]
});
}

function gameTie(){
var state = getState();
if (!gameWon()) {
return state.every(function(square) {
return square != ''
});
}
}

function squareAvailable(square) {
return $(square).text() === ""
}

function gameOver() {
return gameWon() || gameTie()
}


function savingGameButton (){
$('#save').click(function() {
saveGame();
})
}

function saveGame() {
var id = $('table').attr('data-gameid')
if (id) {
$.ajax({
type: "PATCH",
url: '/games/' + id,
data: { "state": getState()},
success : function(response, textStatus, jqXhr) {
console.log("Venue Successfully Patched!");
}
});
} else {
var createGame = $.post('/games', { state: getState() });
createGame.done(function(data) {
$('table').attr('data-gameid', data['data']['id']);
})
}
}

function displayGames() {
$('#previous').click(function() {
$.get('/games', function(data) {
if (data['data'].length > 0) {
var gamesHTML = ''
for (var i = 0; i < data['data'].length; i++) {
var date = new Date(data['data'][i]['attributes']['updated-at']).toLocaleString();
gamesHTML += '<button>' + data['data'][i]['id'] + ' - ' + date + '</button>'
console.log(data)
}
$('#games').html(gamesHTML)
$('#games button').click(function(event) {
loadGame(event.target.textContent);
})
}
});
});
}

function loadGame(id) {
var state = $.get('/games/' + id, function(data) {
$('td').each(function (index, element) {
$(element).text(data['data']['attributes']['state'][index])
});
$('table').attr('data-gameid', data['data']['id']);
refreshTurn();
});
}

function refreshTurn() {
var state = getState();
turn = state.filter(function(square) {
return square != ''
}).length;
}

function clearGame() {
$('#clear').click(function() {
resetGame();
$('table').removeAttr('data-gameid')
});
}
2 changes: 1 addition & 1 deletion app/serializers/game_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
class GameSerializer < ActiveModel::Serializer
attributes :id, :state
attributes :id, :state, :updated_at
end
1 change: 0 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
Expand Down
75 changes: 37 additions & 38 deletions test/tictactoeTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ describe('tictactoe.js', () => {

it('returns "O" when the turn count is odd', () => {
window.turn = 3;

expect(window.player()).to.equal('O');
});
});
Expand Down Expand Up @@ -114,33 +113,33 @@ describe('tictactoe.js', () => {

it('returns true when a player wins horizontally', () => {
populateBoard(['X', 'X', 'X', '', '', '', 'O', 'O', '']);
// X | X | X
// X | X | X
// -----------
// | |
// | |
// -----------
// O | O |
// O | O |

expect(window.checkWinner()).to.be.true;
});

it('returns true when a player wins diagonally', () => {
populateBoard(['X', 'X', 'O', '', 'O', '', 'O', 'X', '']);
// X | X | O
// X | X | O
// -----------
// | O |
// | O |
// -----------
// O | X |
// O | X |

expect(window.checkWinner()).to.be.true;
});

it('returns true when a player wins vertically', () => {
populateBoard(['O', '', 'X', '', 'O', 'X', 'O', '', 'X']);
// O | | X
// O | | X
// -----------
// | O | X
// | O | X
// -----------
// O | | X
// O | | X

expect(window.checkWinner()).to.be.true;
});
Expand All @@ -149,11 +148,11 @@ describe('tictactoe.js', () => {
expect(window.checkWinner()).to.equal(false);

populateBoard(['X', 'O', 'X', 'X', 'O', 'X', 'O', 'X', 'O']);
// X | O | X
// X | O | X
// -----------
// X | O | X
// X | O | X
// -----------
// O | X | O
// O | X | O

expect(window.checkWinner()).to.equal(false);
});
Expand All @@ -162,11 +161,11 @@ describe('tictactoe.js', () => {
const spy = sandbox.stub(window, 'setMessage');

populateBoard(['', '', '', 'X', 'X', 'X', 'O', 'O', '']);
// | |
// | |
// -----------
// X | X | X
// X | X | X
// -----------
// O | O |
// O | O |

window.checkWinner();

Expand All @@ -177,11 +176,11 @@ describe('tictactoe.js', () => {
const spy = sandbox.stub(window, 'setMessage');

populateBoard(['O', '', '', 'X', 'O', 'X', 'X', '', 'O']);
// O | |
// O | |
// -----------
// X | O | X
// X | O | X
// -----------
// X | | O
// X | | O

window.checkWinner();

Expand Down Expand Up @@ -229,11 +228,11 @@ describe('tictactoe.js', () => {
const spy = sandbox.spy(window, 'setMessage');

populateBoard(['X', 'O', 'X', 'X', 'O', 'X', 'O', '', 'O']);
// X | O | X
// X | O | X
// -----------
// X | O | X
// X | O | X
// -----------
// O | | O
// O | | O

window.turn = 8;
window.doTurn(squares[7]);
Expand All @@ -245,11 +244,11 @@ describe('tictactoe.js', () => {
sinon.useFakeXMLHttpRequest();

populateBoard(['X', 'X', 'O', 'X', 'O', 'X', '', 'O', 'O']);
// X | X | O
// X | X | O
// -----------
// X | O | X
// X | O | X
// -----------
// | O | O
// | O | O

window.turn = 8;
window.doTurn(squares[6]);
Expand Down Expand Up @@ -313,11 +312,11 @@ describe('Gameplay', () => {
it('Users cannot play any turns once a game is won or tied', () => {
populateBoard(['X', 'X', 'X', '', '', '', 'O', 'O', '']);
window.turn = 5;
// X | X | X
// X | X | X
// -----------
// | |
// | |
// -----------
// O | O |
// O | O |

squares[4].click();

Expand All @@ -329,11 +328,11 @@ describe('Gameplay', () => {
sinon.useFakeXMLHttpRequest();

populateBoard(['X', 'O', 'X', 'X', 'O', 'X', 'O', '', 'O']);
// X | O | X
// X | O | X
// -----------
// X | O | X
// X | O | X
// -----------
// O | | O
// O | | O

window.turn = 8;
window.doTurn(squares[7]);
Expand Down Expand Up @@ -578,11 +577,11 @@ describe('AJAX interactions with the Rails API', () => {

it('auto-saves tie games', () => {
populateBoard(['X', 'O', 'X', 'X', 'O', 'X', 'O', '', 'O']);
// X | O | X
// X | O | X
// -----------
// X | O | X
// X | O | X
// -----------
// O | | O
// O | | O

window.turn = 8;
window.doTurn(squares[7]);
Expand All @@ -594,11 +593,11 @@ describe('AJAX interactions with the Rails API', () => {
it('auto-saves won games', () => {
populateBoard(['X', 'X', '', '', '', '', 'O', 'O', '']);
window.turn = 4;
// X | X |
// X | X |
// -----------
// | |
// | |
// -----------
// O | O |
// O | O |

squares[2].click();

Expand Down Expand Up @@ -692,4 +691,4 @@ describe('AJAX interactions with the Rails API', () => {
expect(requests[2].url).to.equal('/games/1');
});
});
});
});