-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
135 lines (124 loc) · 4.95 KB
/
script.js
File metadata and controls
135 lines (124 loc) · 4.95 KB
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
const playerXClass = 'x'
const playerOClass = 'circle'
/* An array of arrays. Each array represents a winning combination. */
const winnerCombination = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
]
/* Selecting all the elements with the attribute data-cell. */
const cellElements = document.querySelectorAll('[data-cell]')
/* Selecting the element with the id of board. */
const boardElement = document.getElementById('board')
/* Selecting the element with the id of winnerMessage. */
const winnerMessageElement = document.getElementById('winnerMessage')
/* Selecting the element with the id of restartButton. */
const restartButton = document.getElementById('restartButton')
/* Selecting the element with the id of winnerMessageText. */
const winnerMessageTextElement = document.getElementById('winnerMessageText')
// We set the variable to false, meaning the first to play will be an x character
let isPlayerOTurn = false
startGame()
/* Adding an event listener to the restartButton. When the restartButton is clicked, the startGame
function is called. */
restartButton.addEventListener('click', startGame)
/* Removing the playerXClass and playerOClass from the cellElement. It is also removing the
event listener from the cellElement. It is adding the event listener to the cellElement. */
function startGame() {
isPlayerOTurn = false
cellElements.forEach(cell => {
cell.classList.remove(playerXClass)
cell.classList.remove(playerOClass)
cell.removeEventListener('click', handleCellClick)
cell.addEventListener('click', handleCellClick, {once: true})
})
/* Setting the class of the boardElement to playerXClass. */
setBoardHoverClass()
/* Removing the class of show from the winnerMessageElement. */
winnerMessageElement.classList.remove('show')
}
function handleCellClick(e) {
const cell = e.target
/* currentClass variable saves the character (x or o), whose turn it is at the moment
Checking if it is player O's turn. If it is, it is setting the currentClass to
playerOClass. If it is not, it is setting the currentClass to playerXClass. */
const currentClass = isPlayerOTurn ? playerOClass : playerXClass
/* Checking if the currentClass is a winning combination. If it is, it is calling the
endGame function. If it is not, it is checking if it is a draw. If it is, it is calling the
endGame
function. If it is not, it is swapping turns and setting the board hover class. */
placeMark(cell, currentClass)
if (checkWin(currentClass)) {
endGame(false)
} else if (isDraw()) {
endGame(true)
} else {
swapTurns()
setBoardHoverClass()
}
}
function endGame(draw) {
/* Checking if it is a draw. If it is, it is setting the winnerMessageTextElement to
a draw. */
if (draw) {
winnerMessageTextElement.innerText = 'It is a draw'
} /* Checking if it is player O's turn. If it is, it is setting the winnerMessageElement to
Player with O's wins! If it is not, it is setting the winnerMessageElement to Player with X's
wins! */
else {
winnerMessageTextElement.innerText = `Player with ${isPlayerOTurn ? "O's" : "X's"} wins!`
}
/* Adding the class of show to the winnerMessageElement. */
winnerMessageElement.classList.add('show')
}
// This one just returns the value in case there is a draw
function isDraw() {
/* Checking if every cell contains either the playerXClass or the playerOClass. If it
does, it is returning true. If it does not, it is returning false. */
return[...cellElements].every(cell => {
return cell.classList.contains(playerXClass) || cell.classList.contains(playerOClass)
})
}
/**
* The placeMark function takes two arguments, a cell and a currentClass, and adds the currentClass to
* the cell's classList.
* @param cell - the cell that was clicked
* @param currentClass - the class that is being added to the cell
*/
function placeMark(cell, currentClass) {
cell.classList.add(currentClass)
}
/**
* If it's player O's turn, then it's now player X's turn. If it's player X's turn, then it's now
* player O's turn.
*/
function swapTurns() {
isPlayerOTurn = !isPlayerOTurn
document.getElementById('text-change').innerHTML = `It is player ${isPlayerOTurn ? "O": "X"}`
}
function setBoardHoverClass() {
boardElement.classList.remove(playerXClass)
boardElement.classList.remove(playerOClass)
if (isPlayerOTurn) {
boardElement.classList.add(playerOClass)
} else {
boardElement.classList.add(playerXClass)
}
}
/**
* If any of the winning combinations are true, then return true.
* @param currentClass - The class of the current player.
* @returns a boolean value.
*/
function checkWin(currentClass) {
return winnerCombination.some(combination => {
return combination.every(index => {
return cellElements[index].classList.contains(currentClass)
})
})
}