-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
152 lines (136 loc) · 5.49 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
We store our game status element here to allow us to more easily use it later on
*/
const statusDisplay = document.querySelector('.game--status');
/*
Here we declare some variables that we will use to track the game state
throught the game.
*/
/*
We will use gameActive to pause the game in case of an end scenario
*/
let gameActive = true;
/*
We will store our current player here, so we know whos turn
*/
let currentPlayer = "X";
/*
We will store our current game state here, the form of empty strings in an array
will allow us to easily track played cells and validate the game state later on
*/
let gameState = ["", "", "", "", "", "", "", "", ""];
/*
Here we have declared some message we will display to the user during the game.
Since we have some dynamic factors in those message, namely the current player,
we have declared them as functions, so that the actual message gets created with
current data every time we need it.
*/
const winningMessage = ()=> `Player ${currentPlayer} has won!`;
const drawMessage = () => `Draw!!!`;
const currentPlayerTurn = () => `It's ${currentPlayer}'s turn`;
// We set the initial message to let the players know whose turn it is
statusDisplay.innerHTML = currentPlayerTurn();
function handleCellPlayed() {}
function handlePlayerChange() {}
function handleResultValidation() {}
function handleCellClick() {}
function handleRestartGame() {}
// And finally we add our event listners to the actural game cells, as well as
// our restrat button
let cells = document.querySelectorAll('.cell');
cells.forEach(cell => cell.addEventListener('click', handleCellClick));
document.querySelector('.game--restart')
.addEventListener('click', handleRestartGame);
// handleCellClick ++++++++++++++++++++++++++++++++++++++++++++++
function handleCellClick(clickedCellEvent) {
// We will save the clicked html element in a variable for easier further use
const clickedCell = clickedCellEvent.target;
// Here we will grab the 'data-cell-index' attribute from the clicked cell
// to identify where that cell is in our grid.
// Please not that the getAttribute will return a string value. Since we need an
// actual number we will parse it to an integer(number).
const clickedCellIndex = parseInt(
clickedCell.getAttribute('data-cell-index')
);
// Next up we need to check whether the cell has alredy been played,
// or if the game is paused. If either of those is true we will simply
// ignore the click.
if(gameState[clickedCellIndex] !== "" || !gameActive) {
return;
}
// If everything if in order we will proceed with the game flow.
handleCellPlayed(clickedCell, clickedCellIndex);
handleResultValidation();
}
// handleCellPlayed ++++++++++++++++++++++++++++++++++++++++++++++++
function handleCellPlayed(clickedCell, clickedCellIndex) {
// we update our internal game state to reflect the played move,
// as well as update the used interface to reflect the played move.
gameState[clickedCellIndex] = currentPlayer;
clickedCell.innerHTML = currentPlayer;
}
// handleResultValidation ++++++++++++++++++++++++++++++++++++++++++
const winningConditions = [
[0,1,2], [3,4,5], [6,7,8],
[0,3,6], [1,4,7], [2,5,8],
[0,4,8], [2,4,6]
];
function handleResultValidation() {
let roundWon = false;
for(let i = 0; i <= 7; i++) {
const winCondition = winningConditions[i];
let a = gameState[winCondition[0]];
let b = gameState[winCondition[1]];
let c = gameState[winCondition[2]];
if(a === '' || b === '' || c === '') {
continue;
}
if(a === b && b === c) {
roundWon = true;
colorChangeOnWinning(winCondition);
break;
}
}
if(roundWon) {
statusDisplay.innerHTML = winningMessage();
gameActive = false;
return;
}
// We will check weather there are any values in our game state array
// that are still not populated with a player sign
let roundDraw = !gameState.includes("");
if(roundDraw) {
statusDisplay.innerHTML = drawMessage();
gameActive = false;
return;
}
// If we get to here we knwo that the no one won the game yet, and that there
// are still moves to be played, so we continue by changing the current player.
handlePlayerChange();
}
// handlePlayerChange +++++++++++++++++++++++++++++++++++++++++++++++++++
function handlePlayerChange() {
currentPlayer = currentPlayer === "X" ? "O" : "X";
statusDisplay.innerHTML = currentPlayerTurn();
}
// handleRestartGame ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function handleRestartGame() {
gameActive = true;
currentPlayer = "X";
gameState = ["", "", "", "", "", "", "", "", ""];
statusDisplay.innerHTML = currentPlayerTurn();
document.querySelectorAll('.cell')
.forEach(cell => {
cell.innerHTML = "";
cell.style.backgroundColor = document.body.style.backgroundColor;
});
}
// colorChangeOnWinning ++++++++++++++++++++++++++++++++++++++++++++++++++++
function colorChangeOnWinning(winCondition) {
for(let i = 0; i < 3; i++) {
cells[winCondition[i]].style.backgroundColor = "#fffa79";
if(cells[winCondition[i]].classList.contains("dark-mode")) {
cells[winCondition[i]].style.backgroundColor = "rgb(0 13 149)";
}
}
}