From b84319830c452174e09059a51e1979a880db605f Mon Sep 17 00:00:00 2001 From: liztanyl Date: Wed, 12 Jan 2022 17:40:43 +0800 Subject: [PATCH 1/7] create working game --- index.html | 18 ++--- script.js | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++- styles.css | 12 +++- 3 files changed, 227 insertions(+), 11 deletions(-) diff --git a/index.html b/index.html index 25a06fd..63a6442 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,13 @@ - - SWE101 - - + + Liz's Card Match Game + + - -

SWE101! 🚀

- - - + +

Liz's Card Match Game

+ + + diff --git a/script.js b/script.js index e2d0297..7beabaa 100644 --- a/script.js +++ b/script.js @@ -1 +1,207 @@ -// Please implement exercise logic here +// ----- GLOBAL VARIABLES ----------------------- +const boardSize = 4; +const board = []; +let firstCard = null; +let firstCardElement; +let deck; + +// ----- HELPER FUNCTIONS ----------------------- +// Get a random index ranging from 0 (inclusive) to max (exclusive). +const getRandomIndex = (max) => Math.floor(Math.random() * max); + +// Create deck +const makeDeck = () => { + const newDeck = []; + const suits = ['hearts', 'diamonds', 'clubs', 'spades']; + const suitSymbols = ['♥️', '♦️', '♣️', '♠️']; + const cardName = [ + 'A', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + 'J', + 'Q', + 'K', + ]; + const cardRank = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + + // Loop over the suits array + for (let suitIndex = 0; suitIndex < suits.length; suitIndex += 1) { + // Store the current suit in a variable + const currentSuit = suits[suitIndex]; + + for (let i = 0; i < 13; i += 1) { + // Set suit color + let suitColor = 'black'; + if (currentSuit === 'hearts' || currentSuit === 'diamonds') { + suitColor = 'red'; + } + + // Create a new card with the current name, suit, and rank + const card = { + name: cardName[i], + suit: currentSuit, + symbol: suitSymbols[suitIndex], + color: suitColor, + rank: cardRank[i], + }; + + // Add the new card to the deck + newDeck.push(card); + newDeck.push(card); + } + } + + // Return the completed card deck + return newDeck; +}; + +// Shuffle cards +const shuffleCards = (cards) => { + // Loop over the card deck array once + for (let currentIndex = 0; currentIndex < cards.length; currentIndex += 1) { + // Select a random index in the deck + const randomIndex = getRandomIndex(cards.length); + // Select the card that corresponds to randomIndex + const randomCard = cards[randomIndex]; + // Select the card that corresponds to currentIndex + const currentCard = cards[currentIndex]; + // Swap positions of randomCard and currentCard in the deck + cards[currentIndex] = randomCard; + cards[randomIndex] = currentCard; + } + // Return the shuffled deck + return cards; +}; + +// ----- GAMEPLAY LOGIC ------------------------- + +// What happens when user clicks on a square +const squareClick = (cardElement, row, column) => { + console.log(cardElement); + console.log('FIRST CARD DOM ELEMENT', firstCard); + console.log('BOARD CLICKED CARD', board[row][column]); + + // Store the clicked card + const clickedCard = board[row][column]; + + // If user has already clicked this square + if (cardElement.innerText !== '') { + return; + } + + // First turn + if (firstCard === null) { + console.log('First card'); + // Set the firstCard to the card that was clicked + firstCard = clickedCard; + // "Turn the card over" by showing the card name in the square + cardElement.innerText = firstCard.name; + + // Hold on to this first in case second card doesn't match + firstCardElement = cardElement; + } + + // Second turn + else { + console.log('Second card'); + + // If it's a match + if ( + clickedCard.name === firstCard.name + // include suit later + ) { + console.log('MATCH'); + + // "Turn the card over" by showing the card name in the square + cardElement.innerText = clickedCard.name; + } + + // If it's not a match + else { + console.log('NOT A MATCH'); + + // "Turn first card over" by removing card name in square + firstCardElement.innerText = ``; + } + + // Reset the first card + firstCard = null; + } +}; + +// ----- GAME INITIALISATION -------------------- + +// Create container for board elements +const createBoardContainer = (board) => { + // Create main container + const boardContainer = document.createElement('div'); + boardContainer.classList.add('board'); + + // Create the board grid with 2 loops ------ + // First for row and second for column + for (let i = 0; i < board.length; i += 1) { + // Create variable to hold cards in this row + const row = board[i]; + + // Create div for the row + const rowDiv = document.createElement('div'); + rowDiv.classList.add('row'); + + // Start second loop -------- + // to create the columns (cards / squares) in the row + for (let j = 0; j < row.length; j += 1) { + // Create the square (card) + const square = document.createElement('div'); + square.classList.add('square'); + + // Add event listener to the square + square.addEventListener('click', (e) => { + squareClick(e.currentTarget, i, j); + }); + + // Append the square to the row + rowDiv.appendChild(square); + } + + // Append row to the board + boardContainer.appendChild(rowDiv); + } + + return boardContainer; +}; + +// Game initialisation +const initGame = () => { + // Prepare the deck ---------- + // Create a deck with twice the number of cards + let doubleDeck = makeDeck(); + + // Select enough to make a smaller deck + let deckSubset = doubleDeck.slice(0, boardSize * boardSize); + + // Shuffle the cards + deck = shuffleCards(deckSubset); + + // Deal cards to the board data structure (nested array) ----- + for (let i = 0; i < boardSize; i += 1) { + // Create the array for each row + board.push([]); + + // Deal the cards per row + for (let j = 0; j < boardSize; j += 1) { + board[i].push(deck.pop()); + } + } +}; + +initGame(); + +const boardDiv = createBoardContainer(board); +document.body.appendChild(boardDiv); diff --git a/styles.css b/styles.css index 04e7110..0d4b85b 100644 --- a/styles.css +++ b/styles.css @@ -1,3 +1,13 @@ body { - background-color: pink; + background-color: pink; +} + +.square { + padding: 10px; + margin: 10px; + background-color: white; + display: inline-block; + height: 10px; + width: 10px; + vertical-align: top; } From 4d4d544ac0ad49c8027763241743ce8a643f3be2 Mon Sep 17 00:00:00 2001 From: liztanyl Date: Wed, 12 Jan 2022 17:42:03 +0800 Subject: [PATCH 2/7] add charset meta tag --- index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 63a6442..46b1104 100644 --- a/index.html +++ b/index.html @@ -1,8 +1,9 @@ - Liz's Card Match Game + + Liz's Card Match Game From 17124d746b75f80aaafebb039fd20d366c40f22a Mon Sep 17 00:00:00 2001 From: liztanyl Date: Wed, 12 Jan 2022 19:23:31 +0800 Subject: [PATCH 3/7] include suit comparison in addition to name --- script.js | 15 +++++++-------- styles.css | 5 +++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/script.js b/script.js index 7beabaa..032ac46 100644 --- a/script.js +++ b/script.js @@ -84,8 +84,7 @@ const shuffleCards = (cards) => { // What happens when user clicks on a square const squareClick = (cardElement, row, column) => { - console.log(cardElement); - console.log('FIRST CARD DOM ELEMENT', firstCard); + console.log('CURRENT FIRST CARD', firstCard); console.log('BOARD CLICKED CARD', board[row][column]); // Store the clicked card @@ -98,11 +97,11 @@ const squareClick = (cardElement, row, column) => { // First turn if (firstCard === null) { - console.log('First card'); + console.log('First card picked'); // Set the firstCard to the card that was clicked firstCard = clickedCard; // "Turn the card over" by showing the card name in the square - cardElement.innerText = firstCard.name; + cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; // Hold on to this first in case second card doesn't match firstCardElement = cardElement; @@ -110,17 +109,17 @@ const squareClick = (cardElement, row, column) => { // Second turn else { - console.log('Second card'); + console.log('Second card picked...'); // If it's a match if ( - clickedCard.name === firstCard.name - // include suit later + clickedCard.name === firstCard.name && + clickedCard.suit === firstCard.suit ) { console.log('MATCH'); // "Turn the card over" by showing the card name in the square - cardElement.innerText = clickedCard.name; + cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; } // If it's not a match diff --git a/styles.css b/styles.css index 0d4b85b..2ebf331 100644 --- a/styles.css +++ b/styles.css @@ -7,7 +7,8 @@ body { margin: 10px; background-color: white; display: inline-block; - height: 10px; - width: 10px; + height: 15px; + width: 15px; vertical-align: top; + text-align: center; } From 6e33626870bd1ff14e5920954efe40264a228e62 Mon Sep 17 00:00:00 2001 From: liztanyl Date: Thu, 13 Jan 2022 16:01:28 +0800 Subject: [PATCH 4/7] add gameinfo container, setTimeout for unmatching cards and styles --- script.js | 135 +++++++++++++++++++++++++++++++++++++---------------- styles.css | 31 +++++++++++- 2 files changed, 123 insertions(+), 43 deletions(-) diff --git a/script.js b/script.js index 032ac46..02f664f 100644 --- a/script.js +++ b/script.js @@ -4,6 +4,11 @@ const board = []; let firstCard = null; let firstCardElement; let deck; +let canClick = true; + +// For game information +const gameInfoContainer = document.createElement('div'); +const gameInfo = document.createElement('div'); // ----- HELPER FUNCTIONS ----------------------- // Get a random index ranging from 0 (inclusive) to max (exclusive). @@ -83,65 +88,114 @@ const shuffleCards = (cards) => { // ----- GAMEPLAY LOGIC ------------------------- // What happens when user clicks on a square -const squareClick = (cardElement, row, column) => { - console.log('CURRENT FIRST CARD', firstCard); - console.log('BOARD CLICKED CARD', board[row][column]); - +const openCard = (cardElement, row, column) => { // Store the clicked card const clickedCard = board[row][column]; - // If user has already clicked this square + // If this card is already open (user has already clicked this square) if (cardElement.innerText !== '') { return; } - // First turn - if (firstCard === null) { - console.log('First card picked'); - // Set the firstCard to the card that was clicked - firstCard = clickedCard; - // "Turn the card over" by showing the card name in the square - cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; - - // Hold on to this first in case second card doesn't match - firstCardElement = cardElement; - } - - // Second turn - else { - console.log('Second card picked...'); - - // If it's a match - if ( - clickedCard.name === firstCard.name && - clickedCard.suit === firstCard.suit - ) { - console.log('MATCH'); + if (canClick === true) { + // First turn + if (firstCard === null) { + console.log('First card picked'); + // Set the firstCard to the card that was clicked + firstCard = clickedCard; + console.log(firstCard); // "Turn the card over" by showing the card name in the square cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; + cardElement.classList.add('open-card'); + + // Hold on to this first in case second card doesn't match + firstCardElement = cardElement; + + // Update game info + updateGameInfo(`Great, click another card to match`); } - // If it's not a match + // Second turn else { - console.log('NOT A MATCH'); + console.log('Second card picked...'); + canClick = false; - // "Turn first card over" by removing card name in square - firstCardElement.innerText = ``; - } + // If it's a match + if ( + clickedCard.name === firstCard.name && + clickedCard.suit === firstCard.suit + ) { + console.log(clickedCard); + + // "Turn the card over" by showing the card name in the square + cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; + cardElement.classList.add('open-card'); + + updateGameInfo(`It's a match!`); + + // Update game info + setTimeout(() => { + updateGameInfo(`Click a card`); + }, 2000); + + canClick = true; + } + + // If it's not a match + else { + console.log(clickedCard); + + // "Turn the card over" by showing the card name in the square + cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; + cardElement.classList.add('open-card'); - // Reset the first card - firstCard = null; + setTimeout(() => { + // "Turn cards over" by removing card name in square + cardElement.innerText = ``; + firstCardElement.innerText = ``; + + cardElement.classList.remove('open-card'); + firstCardElement.classList.remove('open-card'); + + updateGameInfo(`Click a card`); + canClick = true; + }, 2000); + + // Update game info + updateGameInfo(`Sorry, try again`); + } + + // Reset the cards + firstCard = null; + console.log(firstCard); + } } }; // ----- GAME INITIALISATION -------------------- +// Create container for game info +const createGameInfoContainer = () => { + gameInfoContainer.classList.add('game-info-container'); + gameInfo.classList.add('game-info'); + + gameInfo.innerHTML = `Click on the squares to match cards.`; + + gameInfoContainer.appendChild(gameInfo); + document.body.appendChild(gameInfoContainer); +}; + +const updateGameInfo = (msgText) => { + gameInfo.innerHTML = msgText; + gameInfoContainer.appendChild(gameInfo); +}; + // Create container for board elements const createBoardContainer = (board) => { // Create main container const boardContainer = document.createElement('div'); - boardContainer.classList.add('board'); + boardContainer.classList.add('board-container'); // Create the board grid with 2 loops ------ // First for row and second for column @@ -162,7 +216,7 @@ const createBoardContainer = (board) => { // Add event listener to the square square.addEventListener('click', (e) => { - squareClick(e.currentTarget, i, j); + openCard(e.currentTarget, i, j); }); // Append the square to the row @@ -172,8 +226,7 @@ const createBoardContainer = (board) => { // Append row to the board boardContainer.appendChild(rowDiv); } - - return boardContainer; + document.body.appendChild(boardContainer); }; // Game initialisation @@ -198,9 +251,9 @@ const initGame = () => { board[i].push(deck.pop()); } } + + createGameInfoContainer(); + createBoardContainer(board); }; initGame(); - -const boardDiv = createBoardContainer(board); -document.body.appendChild(boardDiv); diff --git a/styles.css b/styles.css index 2ebf331..1465527 100644 --- a/styles.css +++ b/styles.css @@ -1,14 +1,41 @@ body { - background-color: pink; + background-color: lavenderblush; + font-family: monospace; + text-align: center; +} + +h1 { + color: darkmagenta; +} + +.game-info-container { + color: darkmagenta; + font-size: 1.3em; + background-color: plum; + border: 2px solid mediumorchid; + width: 50vw; + padding: 1em; + margin: 2em auto; } +.board-container { + background-color: plum; + border: 2px solid mediumorchid; + width: 50vw; + padding: 1em; + margin: 2em auto; +} .square { padding: 10px; margin: 10px; - background-color: white; + background-color: darkmagenta; display: inline-block; height: 15px; width: 15px; vertical-align: top; text-align: center; } + +.open-card { + background-color: white; +} From 9c490ae9aa8fa6f76581c0e871dc0862200101c9 Mon Sep 17 00:00:00 2001 From: liztanyl Date: Thu, 13 Jan 2022 17:47:49 +0800 Subject: [PATCH 5/7] add countdown timer --- script.js | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/script.js b/script.js index 02f664f..11510b9 100644 --- a/script.js +++ b/script.js @@ -5,10 +5,18 @@ let firstCard = null; let firstCardElement; let deck; let canClick = true; +let timerStarted = false; + +// 1 min = 60 000 ms +// 3 mins = 180 000ms +let milliseconds = 180000; // 3 minutes +const delayInMilliseconds = 100; // 0.1 second // For game information const gameInfoContainer = document.createElement('div'); const gameInfo = document.createElement('div'); +const timerContainer = document.createElement('div'); +const timer = document.createElement('div'); // ----- HELPER FUNCTIONS ----------------------- // Get a random index ranging from 0 (inclusive) to max (exclusive). @@ -85,10 +93,34 @@ const shuffleCards = (cards) => { return cards; }; +// Format timer +const formatTimer = (ms) => { + // Show min:sec + // calculate minutes + let min = Math.floor((ms / 1000 / 60) % 60); + // calculate seconds + let sec = Math.floor((ms / 1000) % 60); + + // add leading 0 + if (min < 10) { + min = '0' + min; + } + if (sec < 10) { + sec = '0' + sec; + } + return `${min}:${sec}`; +}; + // ----- GAMEPLAY LOGIC ------------------------- // What happens when user clicks on a square const openCard = (cardElement, row, column) => { + // Start timer on first ever card clicked + if (timerStarted === false) { + startTimer(); + timerStarted = true; + } + // Store the clicked card const clickedCard = board[row][column]; @@ -132,11 +164,13 @@ const openCard = (cardElement, row, column) => { cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; cardElement.classList.add('open-card'); - updateGameInfo(`It's a match!`); + updateGameInfo(`Noice, it's a match!`); // Update game info setTimeout(() => { - updateGameInfo(`Click a card`); + updateGameInfo( + `Click a card to continue, or refresh the page to restart` + ); }, 2000); canClick = true; @@ -173,8 +207,32 @@ const openCard = (cardElement, row, column) => { } }; +const startTimer = () => { + const ref = setInterval(() => { + if (milliseconds <= 0) { + clearInterval(ref); + updateGameInfo(`Time's up!`); + canClick = false; + } + + timer.innerHTML = formatTimer(milliseconds); + milliseconds -= delayInMilliseconds; + }, delayInMilliseconds); +}; + // ----- GAME INITIALISATION -------------------- +// Create container for timer +const createTimerContainer = () => { + timerContainer.classList.add('timer-container'); + timerContainer.innerHTML = `You have 1 minute to match all card pairs.
The time will start when you open your first card.`; + document.body.appendChild(timerContainer); + + timer.classList.add('timer'); + timer.innerHTML = formatTimer(milliseconds); + timerContainer.appendChild(timer); +}; + // Create container for game info const createGameInfoContainer = () => { gameInfoContainer.classList.add('game-info-container'); @@ -252,6 +310,7 @@ const initGame = () => { } } + createTimerContainer(); createGameInfoContainer(); createBoardContainer(board); }; From 53ee64684980e6f459c2e1a9c408cebe1b076e59 Mon Sep 17 00:00:00 2001 From: liztanyl Date: Thu, 13 Jan 2022 17:59:13 +0800 Subject: [PATCH 6/7] change styles --- script.js | 2 +- styles.css | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/script.js b/script.js index 11510b9..3a753b8 100644 --- a/script.js +++ b/script.js @@ -225,7 +225,7 @@ const startTimer = () => { // Create container for timer const createTimerContainer = () => { timerContainer.classList.add('timer-container'); - timerContainer.innerHTML = `You have 1 minute to match all card pairs.
The time will start when you open your first card.`; + timerContainer.innerHTML = `

You have 3 minutes to match all card pairs, starting from when you open your first card.

`; document.body.appendChild(timerContainer); timer.classList.add('timer'); diff --git a/styles.css b/styles.css index 1465527..6e8cea8 100644 --- a/styles.css +++ b/styles.css @@ -8,11 +8,30 @@ h1 { color: darkmagenta; } +.timer-container { + color: darkmagenta; + font-size: 1.2em; + background-color: plum; + border: 2px solid mediumorchid; + width: 50vw; + padding: 1em; + margin: 2em auto; +} + +.timer-container p { + margin-top: 0.5em; +} + +.timer { + font-size: 1.5em; +} + .game-info-container { color: darkmagenta; - font-size: 1.3em; + font-size: 1.2em; background-color: plum; border: 2px solid mediumorchid; + height: 2.5em; width: 50vw; padding: 1em; margin: 2em auto; @@ -25,9 +44,11 @@ h1 { padding: 1em; margin: 2em auto; } + .square { padding: 10px; margin: 10px; + color: crimson; background-color: darkmagenta; display: inline-block; height: 15px; @@ -37,5 +58,5 @@ h1 { } .open-card { - background-color: white; + background-color: lavenderblush; } From 3685a3f69161b7a035aa8ab15889e417c1a8853a Mon Sep 17 00:00:00 2001 From: liztanyl Date: Fri, 14 Jan 2022 16:17:26 +0800 Subject: [PATCH 7/7] stop timer when all cards match, end game when timer runs out, refactor code --- script.js | 171 +++++++++++++++++++++++++++++++---------------------- styles.css | 8 ++- 2 files changed, 106 insertions(+), 73 deletions(-) diff --git a/script.js b/script.js index 3a753b8..6e280f8 100644 --- a/script.js +++ b/script.js @@ -1,16 +1,20 @@ // ----- GLOBAL VARIABLES ----------------------- const boardSize = 4; const board = []; + +let deck; let firstCard = null; let firstCardElement; -let deck; + +// For gameplay let canClick = true; -let timerStarted = false; +let gameCompleted = false; -// 1 min = 60 000 ms -// 3 mins = 180 000ms -let milliseconds = 180000; // 3 minutes +// For timer +let milliseconds = 180000; // 3 minutes (1 min = 60 000ms) const delayInMilliseconds = 100; // 0.1 second +let timerStarted = false; +let timerRef; // For game information const gameInfoContainer = document.createElement('div'); @@ -93,6 +97,15 @@ const shuffleCards = (cards) => { return cards; }; +// Format open cards +const formatOpenCard = (cardDiv, card) => { + cardDiv.innerText = `${card.name}${card.symbol}`; + if (card.symbol === '♥️' || card.symbol === '♦️') { + cardDiv.classList.add('red'); + } + cardDiv.classList.add('open-card'); +}; + // Format timer const formatTimer = (ms) => { // Show min:sec @@ -111,6 +124,35 @@ const formatTimer = (ms) => { return `${min}:${sec}`; }; +const startTimer = () => { + timerRef = setInterval(() => { + if (milliseconds <= 0) { + clearInterval(timerRef); + updateGameInfo(`Time's up! You lose.`); + canClick = false; + } + + timer.innerHTML = formatTimer(milliseconds); + milliseconds -= delayInMilliseconds; + }, delayInMilliseconds); +}; + +const stopTimer = () => { + clearInterval(timerRef); + updateGameInfo( + `Congrats, you matched all the cards!
Refresh the page to play again.` + ); + canClick = false; +}; + +const areAllCardsOpen = () => { + const numOfOpenCards = document.querySelectorAll('.open-card'); + if (numOfOpenCards.length === 16) { + return true; + } + return false; +}; + // ----- GAMEPLAY LOGIC ------------------------- // What happens when user clicks on a square @@ -125,99 +167,84 @@ const openCard = (cardElement, row, column) => { const clickedCard = board[row][column]; // If this card is already open (user has already clicked this square) - if (cardElement.innerText !== '') { + // Or setTimeout is running + if (cardElement.innerText !== '' || canClick === false) { return; } - if (canClick === true) { - // First turn - if (firstCard === null) { - console.log('First card picked'); - // Set the firstCard to the card that was clicked - firstCard = clickedCard; - console.log(firstCard); + // First turn + if (firstCard === null) { + // Set the firstCard to the card that was clicked + firstCard = clickedCard; - // "Turn the card over" by showing the card name in the square - cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; - cardElement.classList.add('open-card'); + // "Turn the card over" by showing the card name in the square + formatOpenCard(cardElement, clickedCard); - // Hold on to this first in case second card doesn't match - firstCardElement = cardElement; + // Hold on to this first in case second card doesn't match + firstCardElement = cardElement; - // Update game info - updateGameInfo(`Great, click another card to match`); - } + // Update game info + updateGameInfo(`Great, now find its match!`); + } - // Second turn - else { - console.log('Second card picked...'); - canClick = false; + // Second turn + else { + canClick = false; - // If it's a match - if ( - clickedCard.name === firstCard.name && - clickedCard.suit === firstCard.suit - ) { - console.log(clickedCard); + // If it's a match + if ( + clickedCard.name === firstCard.name && + clickedCard.suit === firstCard.suit + ) { + // "Turn the card over" by showing the card name in the square - // "Turn the card over" by showing the card name in the square - cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; - cardElement.classList.add('open-card'); + formatOpenCard(cardElement, clickedCard); - updateGameInfo(`Noice, it's a match!`); + // Check if all cards are open + if (areAllCardsOpen() === true) { + stopTimer(); + return; + } - // Update game info + // If not all cards have been open, update game info + else { + updateGameInfo(`Noice, it's a match!`); setTimeout(() => { updateGameInfo( - `Click a card to continue, or refresh the page to restart` + `Click a card to continue, or refresh the page to restart.` ); }, 2000); canClick = true; } + } - // If it's not a match - else { - console.log(clickedCard); + // If it's not a match + else { + // "Open cards" by showing the card name in the square and adding the relevant classes - // "Turn the card over" by showing the card name in the square - cardElement.innerText = `${clickedCard.name}${clickedCard.symbol}`; - cardElement.classList.add('open-card'); + formatOpenCard(cardElement, clickedCard); - setTimeout(() => { - // "Turn cards over" by removing card name in square - cardElement.innerText = ``; - firstCardElement.innerText = ``; + // "Turn cards over" after a set time + setTimeout(() => { + // "Turn cards over" by removing card name in square + cardElement.innerText = ``; + firstCardElement.innerText = ``; - cardElement.classList.remove('open-card'); - firstCardElement.classList.remove('open-card'); + cardElement.classList.remove('open-card', 'red', 'black'); + firstCardElement.classList.remove('open-card', 'red', 'black'); - updateGameInfo(`Click a card`); - canClick = true; - }, 2000); - - // Update game info - updateGameInfo(`Sorry, try again`); - } - - // Reset the cards - firstCard = null; - console.log(firstCard); - } - } -}; + updateGameInfo(`Click to open a card.`); + canClick = true; + }, 1500); -const startTimer = () => { - const ref = setInterval(() => { - if (milliseconds <= 0) { - clearInterval(ref); - updateGameInfo(`Time's up!`); - canClick = false; + // Update game info + updateGameInfo(`Sorry, those didn't match. Try again!`); } - timer.innerHTML = formatTimer(milliseconds); - milliseconds -= delayInMilliseconds; - }, delayInMilliseconds); + // Reset the cards + firstCard = null; + } }; // ----- GAME INITIALISATION -------------------- diff --git a/styles.css b/styles.css index 6e8cea8..836ddf3 100644 --- a/styles.css +++ b/styles.css @@ -48,7 +48,6 @@ h1 { .square { padding: 10px; margin: 10px; - color: crimson; background-color: darkmagenta; display: inline-block; height: 15px; @@ -60,3 +59,10 @@ h1 { .open-card { background-color: lavenderblush; } + +.red { + color: crimson; +} +.black { + color: darkslategrey; +}