Skip to content

Commit e8d9b78

Browse files
committed
all tests passing, game victory conditions and reset button
1 parent 1443bfb commit e8d9b78

File tree

3 files changed

+126
-27
lines changed

3 files changed

+126
-27
lines changed

index.html

+12-11
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@
22
<html lang="en">
33
<link rel="stylesheet" href="./styles.css">
44
<body>
5-
<h1>Tic-Tac-Toe</h1>
6-
<h2>Player 1 (X) must place their mark</h2>
5+
<h1 id="game-name">Tic-Tac-Toe</h1>
6+
<h2 id="instructions">Instructions</h2>
7+
<p>Click on the squares to make your mark. Play with a friend! Three in a row, column, or diagonal wins!</p>
78
<table>
89
<tr class="top">
9-
<td class="left" >1</td>
10-
<td class="center">2</td>
11-
<td class="right" >3</td>
10+
<td class="left" ></td>
11+
<td class="center"></td>
12+
<td class="right" ></td>
1213
</tr>
1314
<tr class="middle">
14-
<td class="left" >4</td>
15-
<td class="center">5</td>
16-
<td class="right" >6</td>
15+
<td class="left" ></td>
16+
<td class="center"></td>
17+
<td class="right" ></td>
1718
</tr>
1819
<tr class="bottom">
19-
<td class="left" >7</td>
20-
<td class="center">8</td>
21-
<td class="right" >9</td>
20+
<td class="left" ></td>
21+
<td class="center"></td>
22+
<td class="right" ></td>
2223
</tr>
2324
</table>
2425
</body>

index.js

+82-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,93 @@
1-
// ⌛ Call init function when DOM loaded
2-
document.addEventListener("DOMContentLoaded", init);
31
// 🌐 Global Variables
42
const cells = document.querySelectorAll("td");
3+
const instructions = document.querySelector("p")
4+
// 🤹 Tracking Game States
5+
let xTurn = true;
56
// 1️⃣ Init Called on document loaded
67
const init = () => {
78
initCellHandler();
89
};
9-
// 💡 Event Handlers
10+
// 💡 Init Event Handlers
1011
const initCellHandler = () => {
1112
let i = 1;
1213
cells.forEach((cell) => {
14+
// debugger
1315
cell.id = i++;
14-
cell.addEventListener("click", (e) => {
15-
console.log(`${cell.id} clicked`);
16-
});
16+
cell.addEventListener("click", () => cellHandler(cell));
17+
});
18+
};
19+
const resetGame = () => {
20+
cells.forEach((cell) => {
21+
cell.innerHTML = "";
1722
});
18-
};
23+
instructions.textContent = "Click on the squares to make your mark. Play with a friend! Three in a row, column, or diagonal wins!"
24+
xTurn = true
25+
}
26+
// 🎯 Declare Cell Handler
27+
const cellHandler = (cell) => {
28+
const markToPlace = xTurn ? "X" : "O";
29+
if (cell.textContent === "") {
30+
cell.textContent = markToPlace;
31+
if (victoryConditions()) {
32+
// Run victoryConditions to check for win
33+
console.log(`${markToPlace} wins!`)
34+
instructions.textContent = `${markToPlace} wins! Reset game?`;
35+
const resetButton = document.createElement("button")
36+
resetButton.textContent = "Reset Game"
37+
instructions.appendChild(resetButton);
38+
resetButton.addEventListener("click", resetGame);
39+
}
40+
xTurn = !xTurn; // Flip xTurn for next players turn
41+
}
42+
};
43+
// 🥳 Victory Conditions
44+
const victoryConditions = () => {
45+
const horizontalWin = horizontalWinCondition(xTurn ? "X" : "O"); // Only check the mark of the current player
46+
const verticalWin = verticalWinCondition(xTurn ? "X" : "O"); // Only check the mark of the current player
47+
const diagonalWin = diagonalWinCondition(xTurn ? "X" : "O"); // Only check the mark of the current player
48+
return (horizontalWin || verticalWin || diagonalWin)
49+
function horizontalWinCondition(markToCheck = "X") {
50+
let horizontalWinCheck = false;
51+
for (let i = 0; i < 3; i++) {
52+
if (
53+
cells[i * 3 + 0].textContent === markToCheck && // need to check 0, 3, and 6 (element in array)
54+
cells[i * 3 + 1].textContent === markToCheck && // need to check 1, 4, and 7
55+
cells[i * 3 + 2].textContent === markToCheck // need to check 2, 5, and 8
56+
) {
57+
horizontalWinCheck = true;
58+
return horizontalWinCheck;
59+
}
60+
}
61+
return horizontalWinCheck;
62+
}
63+
function verticalWinCondition(markToCheck = "X") {
64+
let verticalWinCheck = false;
65+
for (let i = 0; i < 3; i++) {
66+
if (
67+
cells[i + 0].textContent === markToCheck && // need to check 0, 1, and 2 (element in array)
68+
cells[i + 3].textContent === markToCheck && // need to check 3, 4, and 5
69+
cells[i + 6].textContent === markToCheck // need to check 6, 7, and 8
70+
) {
71+
verticalWinCheck = true;
72+
return verticalWinCheck;
73+
}
74+
}
75+
return verticalWinCheck;
76+
}
77+
function diagonalWinCondition(markToCheck = "X") {
78+
let diagonaWinCheck = false;
79+
for (let i = 0; i < 2; i++) {
80+
if (
81+
cells[i * 2].textContent === markToCheck && // need to check 0, 2
82+
cells[4].textContent === markToCheck && // need to check 4, 4
83+
cells[8 - i * 2].textContent === markToCheck // need to check 8, 6
84+
) {
85+
diagonaWinCheck = true;
86+
return diagonaWinCheck;
87+
}
88+
}
89+
return diagonaWinCheck;
90+
}
91+
};
92+
// ⌛ Call init function when DOM loaded
93+
document.addEventListener("DOMContentLoaded", init);

test.js

+32-9
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,42 @@
11
// 🌐 Global element references for passing tests
22
let testTable = document.querySelectorAll("table");
3+
let testCells = document.querySelectorAll("td")
34

45
// 🌐 Global variables for passing tests
5-
let tableCheckPass = false;
6-
let rowCheckPass = false;
6+
let cellClickPass = false;
7+
let tableCheckPass = false;
8+
let rowCheckPass = false;
79
let columnCheckPass = false;
810

9-
// 🧪 click grid tests
10-
function clickGridTests() {
11-
11+
// 🧪 click grid tests, building a "visual" click test runner...
12+
function testCellClick(timeBetweenClicks = 500) {
13+
// 1️⃣ First test pattern for the board, linear click on each cell 1-9
14+
// Pattern match XOX,OXO,XOX
15+
const testPattern1 = [ // tests clicks, tests turns (alternating game states?)
16+
"X", "O", "X",
17+
"O", "X", "O",
18+
"X", "O", "X",
19+
]
20+
testCells.forEach(cell => {
21+
setTimeout(() => {
22+
cell.click() // Click on each cell
23+
console.log(`clicking Cell ${cell.id}...`)
24+
if (cell.textContent === testPattern1[cell.id -1]) {
25+
console.log(`✅ Expected Cell ${cell.id} to match "${testPattern1[cell.id - 1]}" and the value is ${cell.textContent}!`)
26+
cellClickPass = true
27+
} else {
28+
console.log(`🚫 Expected Cell ${cell.id} to match "${testPattern1[cell.id - 1]}" and the value is ${cell.textContent}!`)
29+
cellClickPass = false
30+
}
31+
}, timeBetweenClicks * [cell.id]) // not necessary, but nice for the visual tests
32+
})
33+
return "🚩 Starting cell click tests..."
1234
}
1335
// 🧪 3x3 grid tests
14-
function gridTests() {
15-
checkTable();
16-
checkRows();
17-
checkColumns();
36+
function testGrid(timeBetweenTests = 1000) {
37+
setTimeout(checkTable, timeBetweenTests * 1) ;
38+
setTimeout(checkRows, timeBetweenTests * 2);
39+
setTimeout(checkColumns, timeBetweenTests * 3);
1840
function checkTable() {
1941
testTable = document.querySelectorAll("table");
2042
if (testTable.length !== 1) {
@@ -66,4 +88,5 @@ function gridTests() {
6688
}
6789
}
6890
}
91+
return "🚩 Starting grid checks tests..."
6992
}

0 commit comments

Comments
 (0)