During 2021 I was learning to code but I left it because I didn't have enough time and energy. Today I started my come back to coding so I created a simple tic-tac-toe game.
I didn't use objects, classes and related stuff because my main goal was to write something simple and completeable in 1 to 2 hours. I had to google some syntax that i forgot but I don't think it is a big thing. Didn't search for advice about the game itself ("how to do this", etc.).
So, it will be great to have some general advice, pointers, next steps and so on.
Game can be played here
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="main.js"></script>
<link rel="stylesheet" href="styles/normalize.css">
<link rel="stylesheet" href="styles/styles.css">
<title>Tic-Tac-Toe vanilla JS</title>
</head>
<body>
<div id="container">
<div class="cell" id="cell-1"></div>
<div class="cell" id="cell-2"></div>
<div class="cell" id="cell-3"></div>
<div class="cell" id="cell-4"></div>
<div class="cell" id="cell-5"></div>
<div class="cell" id="cell-6"></div>
<div class="cell" id="cell-7"></div>
<div class="cell" id="cell-8"></div>
<div class="cell" id="cell-9"></div>
</div>
</body>
</html>
main.js
// WAIT FOR THE DOM
window.addEventListener('DOMContentLoaded', (event) => {
console.log('DOM fully loaded and parsed');
main();
});
// STATE
const p1Class = 'player1' // Defined in styles.css
const p2Class = 'player2' // Defined in styles.css
let turnFlag = true // true: player1, false: player2
let playerClass = p1Class;
let cells = null
let cell = null
let moves = 0
// MAIN FUNCTION
function main() {
// GET CELLS FROM DOM
cells = document.querySelectorAll(".cell")
cells.forEach( cell => cell.addEventListener('click', turn) )
function turn() {
console.log(`Now playing: ${playerClass}`)
cell = this; // currently clicked cell
if (!cell.hasAttribute('data-disabled')) {
paintCell();
if (checkWinner() || checkDraw()) {
restartGame ()
}
else {
changeTurn();
}
}
};
};
// FUNCTIONS
function changeTurn() {
turnFlag = !turnFlag
//if (turnFlag == true) {playerClass = p1Class}
//else {playerClass = p2Class}
playerClass = turnFlag ? p1Class : p2Class
}
function paintCell() {
console.log('cell clicked: ' + cell.id)
cell.classList.add(playerClass)
cell.setAttribute('data-disabled', 'true')
moves += 1
}
function checkWinner() {
function containsPlayerClass(cell) {
return cell.classList.contains(playerClass)
}
// CHECK COMPLETION FOR ROWS, COLUMNS AND DIAGS
function checkRows() {
if ( containsPlayerClass(cells[0]) && containsPlayerClass(cells[1]) && containsPlayerClass(cells[2]) ) {
return true
}
else if ( containsPlayerClass(cells[3]) && containsPlayerClass(cells[4]) && containsPlayerClass(cells[5]) ) {
return true
}
else if ( containsPlayerClass(cells[6]) && containsPlayerClass(cells[7]) && containsPlayerClass(cells[8]) ) {
return true
}
else {
return false
}
// if (cells[3].classList.contains(playerClass) && cells[4].classList.contains(playerClass) && cells[5].classList.contains(playerClass)) {
// rowsFlag[1] = true
// }
// if (cells[6].classList.contains(playerClass) && cells[7].classList.contains(playerClass) && cells[8].classList.contains(playerClass)) {
// rowsFlag[2] = true
// }
}
function checkColumns() {
if ( containsPlayerClass(cells[0]) && containsPlayerClass(cells[3]) && containsPlayerClass(cells[6]) ) {
return true
}
else if ( containsPlayerClass(cells[1]) && containsPlayerClass(cells[4]) && containsPlayerClass(cells[7]) ) {
return rowsFlag = true
}
else if ( containsPlayerClass(cells[2]) && containsPlayerClass(cells[5]) && containsPlayerClass(cells[8]) ) {
return rowsFlag = true
}
else {
return rowsFlag = false
}
}
function checkDiags() {
if ( containsPlayerClass(cells[0]) && containsPlayerClass(cells[4]) && containsPlayerClass(cells[8]) ) {
return true
}
else if ( containsPlayerClass(cells[2]) && containsPlayerClass(cells[4]) && containsPlayerClass(cells[6]) ) {
return true
}
else {
return false
}
}
// EVALUATE IF WE HAVE A WINNER
if ( checkRows() || checkColumns() || checkDiags() ) {
alert(`YOU WON ${playerClass}`);
return true
}
else {
return false
}
}
function checkDraw() {
if (moves == 9) {
alert(`DRAW`);
return true;
}
else {
return false
}
}
function restartGame() {
turnFlag = true
playerClass = p1Class;
cells.forEach( cell => cell.classList.remove('player1') )
cells.forEach( cell => cell.classList.remove('player2') )
cells.forEach( cell => cell.removeAttribute('data-disabled') )
moves = 0
console.clear()
console.log('GAME RESTARTED')
}
styles.css
.player1 {
background-color: turquoise;
}
.player2 {
background-color: brown;
}
Thanks in advance.