A Simple Board Game with Javascript, HTML and CSS

abdulsalam bufarhan
5 min readFeb 25, 2023

--

a really simple game with plain javascript including some functions to make learning as easy as possible :)

Github link

a preview of the image

Hello Javascript lovers :)

In my way of learning things, the simplest approach is learning by samples. So I tried to initialize this game with a few lines of code in three files and here is the explanation:

Index.HTML:

First of all I added an HTML file to manage the UI and added these lines:

To display a title in the game window:

<title>Matching Game</title>

To link the JS codes:

<script src="app.js"></script>

To import the font file:

<link rel="preconnect" href="https://fonts.gstatic.com">

Our main element of the game is the board to host the clickable color cells:

<div class="board"></div>

We’ll get access to this element through its class name which is “board”.

Then to display the timer and the score, I added two elements and gave their IDs a proper name to get access them via javascript and update their text content:

<span class="">Timer:<b id="timer"></b></span>
<span class="">Score:<b id="score">0</b></span>

To link our styles file(CSS) to the elements:

<link rel="stylesheet" href="styles.css" />

Styles.CSS

This file contains our styling codes such as the colors of the cell, font name of the texts and the styles of other elements:

To insert the cells in a right place into the board, I preferred to use grid with following class:

.board {
margin: 0 auto;
display: grid;
padding: 2px;
grid-template-columns: 20% 20% 20% 20% 20%;
grid-template-rows: 20% 20% 20% 20% 20%;
max-width: 500px;
border: 3px solid rgb(12, 0, 0);
border-radius: 5px;
background-color:rgb(90, 90, 90);
}

To shape the cells, I limited their min sizes by setting min-height and min-width :


.cell {
min-width: 90px;
min-height: 60px;
border-top: 1px solid rgb(50, 50, 50);
border-right: 1px solid rgb(50, 50, 50);
border-bottom: 3px solid silver;
border-left: 3px solid silver;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
margin: 2px;
}

To color the cells with different colors, I created several classes with specific color names for the background color. e.g. red cell’s class is:

.red-cell {
background-color: red;
}

To highlight the selected cell, I added this class so that when a cell is selected by the user, it is assigned to the selected cell(s):

.marked-cell {
border: 3px solid black;
border-radius: 5px;
}

In the class above, we set the border color to black and a bit thicker than the other cells.

App.JS

This is the main file of the game, where we write the code of our brain for the game. Let us dive into the exciting part:

In the very first lines, I added the public variables to be accessible from all our functions.

We need to have the color classes in an array to access them by the index of the array element, rather than using the names of the classes:

const COLORS = ['lime-cell', 'purple-cell', 'red-cell', 'blue-cell', 'yellow-cell', 'green-cell', 'pink-cell', 'browen-cell', 'orange-cell', 'cyan-cell']

And some variables to keep the number of rows of the board, the number of columns of the board, the score and the timer of the game:

const ROWS = 5
const COLS = 5
let SCORE = 0;
let TIMER= 0;

I’ve used the keyword “const” to define constant variables that are read-only, and “let” to define mutable variables.

For easy access to the elements (tags) of the timer, reset button and game state, these lines have been added:

    const resetButton = document.getElementById('reset')
const timerDisplay = document.getElementById('timer')
const scoreDisplay = document.getElementById('score')

To draw (create) the cells dynamically and place them in the Div:

function init() {
let board = document.getElementsByClassName('board')[0];
for (let row = 1; row <= ROWS; row++) {
for (let col = 1; col <= COLS; col++) {

//generate the cells
let cell = document.createElement('div')
cell.id = `C_${row}_${col}`

//set click event
cell.addEventListener('click', () => cellClick(cell))

//set random style
let color = COLORS[Math.floor(Math.random() * COLORS.length)]

cell.className = `cell ${color}`;
//add the cell to the board
board.appendChild(cell);
}
}
resetButton.addEventListener('click', reset);

}

Here is waht will happen if user clicks on the cells:

async function cellClick(cell) {
if (cell.className == 'disabled-cell') return;
if (lastMarkedCells.indexOf(cell.id) > -1) {
unmark(cell)
return;
}
markCell(cell)
if (lastMarkedCells.length == 2)
await checkIfMatching()
}

We have to check if there are three cells of the same color next to each other every time we move a cell:

function checkRightMove(cell) {
let cell_color = cell.classList[1];
let row = Number(cell.id.split('_')[1]);
let col = Number(cell.id.split('_')[2]);

//check row possiblity
let row_case1 = isSameColorWith(cell_color, row + 1, col) && isSameColorWith(cell_color, row + 2, col)
let row_case2 = isSameColorWith(cell_color, row - 1, col) && isSameColorWith(cell_color, row - 2, col)
let row_case3 = isSameColorWith(cell_color, row - 1, col) && isSameColorWith(cell_color, row + 1, col)

//check column possiblity
let col_case1 = isSameColorWith(cell_color, row, col + 1) && isSameColorWith(cell_color, row, col + 2)
let col_case2 = isSameColorWith(cell_color, row, col - 1) && isSameColorWith(cell_color, row, col - 2)
let col_case3 = isSameColorWith(cell_color, row, col - 1) && isSameColorWith(cell_color, row, col + 1)
if (row_case1) resetMatchingCellsInColumn(cell_color, col, row, row + 1, row + 2)
if (row_case2) resetMatchingCellsInColumn(cell_color, col, row, row - 1, row - 2)
if (row_case3) resetMatchingCellsInColumn(cell_color, col, row, row - 1, row + 1)

if (col_case1) resetMatchingCellsInRow(cell_color, row, col, col + 1, col + 2)
if (col_case2) resetMatchingCellsInRow(cell_color, row, col, col - 1, col - 2)
if (col_case3) resetMatchingCellsInRow(cell_color, row, col, col - 1, col + 1)
//increment the score
if (col_case1 || col_case2 || col_case3 || row_case1 || row_case2 || row_case3)
incrementScore()

}

And finally, if there was a match, we reset the colors of the matching cells by removing their current color and creating a new random color and then increasing the score:

 function resetCellColor(color, row, col) {
let cell1 = document.getElementById(`C_${row}_${col}`)
cell1.classList.remove(color)
let new_color = COLORS[Math.floor(Math.random() * COLORS.length)]

cell1.classList.add(new_color)
}
 function incrementScore() {

SCORE++
scoreDisplay.textContent = SCORE

}

And this code to handle the reset button to reset the game by setting the score and timer to 0 and display on UI:

function reset() {
SCORE = 0;
TIMER = 0;
timerDisplay.textContent = 0;
scoreDisplay.textContent = 0;
}

--

--