Bootcamp
Search…
📅
Course Schedule
0: Language and Tooling Teaching Guide
1: Frontend Basics Teaching Guide
2: Backend Basics Teaching Guide
3: Backend Applications Teaching Guide
4: Backend Structure Teaching Guide
5: Full-Stack Applications Teaching Guide
6: Frontend Infrastructure Teaching Guide
7: React Teaching Guide
8: Advanced React Teaching Guide
9: Advanced Topics Teaching Guide
🧮
Algorithms Teaching Guide
💼
Interview Prep Teaching Guide
☺
User Experience Teaching Guide
1.6: Match Game

Introduction

Create a card-matching game called Match Game. In this game the user turns cards over one at a time to find matching pairs of cards.

Nested Array Coordinates

In this Match Game implementation we'll use an array of arrays data structure to represent the board and store card positions. We could implement Match Game with a different data structure, but since our layout will be grid-like an array of arrays is appropriate.
We can use the properties of an array nested inside another array to represent a coordinate grid.
1
const grid = [
2
['A', 'B'],
3
['Y', 'Z'],
4
];
5
​
6
const upperLeftPosition = grid[0][0]; // 'A'
7
const upperRightPosition = grid[0][1]; // 'B'
8
const lowerLeftPosition = grid[1][0]; // 'Y'
9
const lowerRightPosition = grid[1][1]; // 'Z'
Copied!

CSS

Paste this css into the style.css file.
1
.square {
2
padding: 10px;
3
margin: 10px;
4
background-color: white;
5
display: inline-block;
6
height: 10px;
7
width: 10px;
8
vertical-align: top;
9
}
Copied!

Global Variables

1
// boardSize has to be an even number
2
const boardSize = 4;
3
const board = [];
4
let firstCard = null;
5
let firstCardElement;
6
let deck;
Copied!

Gameplay Logic

1
const squareClick = (cardElement, column, row) => {
2
​
3
console.log(cardElement);
4
5
console.log('FIRST CARD DOM ELEMENT', firstCard);
6
7
console.log('BOARD CLICKED CARD', board[column][row]);
8
9
const clickedCard = board[column][row];
10
​
11
// the user already clicked on this square
12
if( cardElement.innerText !== '' ){
13
return;
14
}
15
​
16
// first turn
17
if (firstCard === null) {
18
console.log('first turn');
19
firstCard = clickedCard;
20
// turn this card over
21
cardElement.innerText = firstCard.name;
22
23
// hold onto this for later when it may not match
24
firstCardElement = cardElement;
25
​
26
// second turn
27
} else {
28
29
console.log('second turn');
30
if (
31
clickedCard.name === firstCard.name &&
32
clickedCard.suit === firstCard.suit
33
) {
34
console.log('match');
35
36
// turn this card over
37
cardElement.innerText = clickedCard.name;
38
} else {
39
console.log('NOT a match');
40
41
// turn this card back over
42
firstCardElement.innerText = '';
43
}
44
​
45
// reset the first card
46
firstCard = null;
47
}
48
};
Copied!

Game Initialisation Logic

1
// create all the board elements that will go on the screen
2
// return the built board
3
const buildBoardElements = (board) => {
4
// create the element that everything will go inside of
5
const boardElement = document.createElement('div');
6
​
7
// give it a class for CSS purposes
8
boardElement.classList.add('board');
9
​
10
// use the board data structure we passed in to create the correct size board
11
for (let i = 0; i < board.length; i += 1) {
12
// make a var for just this row of cards
13
const row = board[i];
14
​
15
// make an element for this row of cards
16
const rowElement = document.createElement('div');
17
rowElement.classList.add('row');
18
​
19
// make all the squares for this row
20
for (let j = 0; j < row.length; j += 1) {
21
// create the square element
22
const square = document.createElement('div');
23
​
24
// set a class for CSS purposes
25
square.classList.add('square');
26
​
27
// set the click event
28
// eslint-disable-next-line
29
square.addEventListener('click', (event) => {
30
// we will want to pass in the card element so
31
// that we can change how it looks on screen, i.e.,
32
// "turn the card over"
33
squareClick(event.currentTarget, i, j);
34
});
35
​
36
rowElement.appendChild(square);
37
}
38
boardElement.appendChild(rowElement);
39
}
40
​
41
return boardElement;
42
};
43
​
44
const initGame = () => {
45
// create this special deck by getting the doubled cards and
46
// making a smaller array that is ( boardSize squared ) number of cards
47
let doubleDeck = makeDeck();
48
let deckSubset = doubleDeck.slice(0, boardSize * boardSize);
49
deck = shuffleCards(deckSubset);
50
​
51
// deal the cards out to the board data structure
52
for (let i = 0; i < boardSize; i += 1) {
53
board.push([]);
54
for (let j = 0; j < boardSize; j += 1) {
55
board[i].push(deck.pop());
56
}
57
}
58
​
59
const boardEl = buildBoardElements(board);
60
​
61
document.body.appendChild(boardEl);
62
};
Copied!

New Make Deck

Add line 39 to makeDeck so that it outputs doubles of each card.
1
const makeDeck = (cardAmount) => {
2
// create the empty deck at the beginning
3
const newDeck = [];
4
const suits = ['hearts', 'diamonds', 'clubs', 'spades'];
5
​
6
for (let suitIndex = 0; suitIndex < suits.length; suitIndex += 1) {
7
// make a variable of the current suit
8
const currentSuit = suits[suitIndex];
9
console.log(`current suit: ${currentSuit}`);
10
​
11
// loop to create all cards in this suit
12
// rank 1-13
13
for (let rankCounter = 1; rankCounter <= 13; rankCounter += 1) {
14
// Convert rankCounter to string
15
let cardName = `${rankCounter}`;
16
​
17
// 1, 11, 12 ,13
18
if (cardName === '1') {
19
cardName = 'ace';
20
} else if (cardName === '11') {
21
cardName = 'jack';
22
} else if (cardName === '12') {
23
cardName = 'queen';
24
} else if (cardName === '13') {
25
cardName = 'king';
26
}
27
​
28
// make a single card object variable
29
const card = {
30
name: cardName,
31
suit: currentSuit,
32
rank: rankCounter,
33
};
34
​
35
console.log(`rank: ${rankCounter}`);
36
​
37
// add the card to the deck
38
newDeck.push(card); // add double the cards to the deck
39
newDeck.push(card);
40
}
41
}
42
​
43
return newDeck;
44
};
Copied!

Exercise

Fork and clone the Coding Bootcamp Match Game repo. Use code from the above implementation to build a working Match Game.
Last modified 2mo ago