JavaScript Memory Game Source Code

How To Create Memory Cards Game in JavaScript

How To Create Memory Cards Game in JavaScript




In this Javascript Tutorial we will see How to Create a memory card game using JavaScript with HTML and CSS.
Players flip cards to find matching pairs, racing against time across three increasingly challenging levels.

The Game Features:
- Progressive Difficulty: Three levels with increasing complexity (6, 8, and 10 pairs).
- Time Pressure: Each level has a specific time limit to add urgency.
- Move Tracking: Monitors player efficiency with a move counter.

What We Are Gonna Use In This Project:

- Javascript Programming Language.
- HTML and CSS.
- Visual Studio Editor.




if you want the source code click on the download button below




Project Source Code:


     - Card Flipping.


/**
* Handles flipping a card when clicked
* This function is called when a card is clicked
*/
function flipCard() {
// Check if this card can be flipped:
// - Less than 2 cards already flipped
// - This card is not already flipped
// - This card is not already matched
if (flippedCards.length < 2 && !this.classList.contains('flipped') &&
                        !this.classList.contains('matched')) {

// Add the 'flipped' class for styling
this.classList.add('flipped');
// Show the card's icon instead of the question mark
this.innerHTML = `<i class="fas ${this.dataset.icon}"></i>`;
// Add this card to the flipped cards array
flippedCards.push(this);

// If we now have 2 flipped cards, check if they match
if (flippedCards.length === 2) {
// Increment moves counter
moves++;
// Update the moves display
movesDisplay.textContent = moves;
// Wait half a second before checking if cards match
setTimeout(checkMatch, 500);
}

}
}




     - Randomization Algorithm.


/**
* Shuffles an array using the Fisher-Yates algorithm
* @param {Array} array - The array to shuffle
*/
function shuffleArray(array) {
// Loop through the array backwards
for (let i = array.length - 1; i > 0; i--) {
// Pick a random index from 0 to i
const j = Math.floor(Math.random() * (i + 1));
// Swap elements at indices i and j using array destructuring
[array[i], array[j]] = [array[j], array[i]];
}
}


    

     - Timer Implementation.


/**
* Updates the game timer
* Called every second by the timer interval
*/
function updateTime() {
// Increment the time elapsed in seconds
timeElapsed++;

// Format the time as MM:SS (with leading zeros)
const minutes = Math.floor(timeElapsed / 60).toString().padStart(2, '0');
const seconds = (timeElapsed % 60).toString().padStart(2, '0');

// Update the time display
timeDisplay.textContent = `${minutes}:${seconds}`;

// Check if time limit for the current level has been reached
if (timeElapsed >= difficulties[level].timeLimit) {
// Stop the timer
clearInterval(timerId);
// Show the time's up modal
showTimeUpModal();
}

}


    

     - Creates a card element with a hidden icon.


/**
* @param {string} icon - The Font Awesome icon class
* @returns {HTMLElement} - The created card element
*/
function createCard(icon) {

// Create a new div element for the card
const card = document.createElement('div');
// Add the 'card' class for styling
card.classList.add('card');
// Set the initial content to show a question mark
card.innerHTML = `<i class="fas fa-question"></i>`;
// Store the icon class in a data attribute for later use
card.dataset.icon = icon;
// Add click event listener to handle card flipping
card.addEventListener('click', flipCard);
// Return the created card element
return card;
}

    



      - Checks if two flipped cards match.


/**
* Checks if two flipped cards match
* Called after two cards are flipped
*/
function checkMatch() {

// Get the two flipped cards using array destructuring
const [card1, card2] = flippedCards;

// Check if the icons on both cards match
if (card1.dataset.icon === card2.dataset.icon) {
// If they match, increment the matched pairs counter
matchedPairs++;
// Add 'matched' class to both cards for styling
card1.classList.add('matched');
card2.classList.add('matched');

// Check if all pairs for this level are matched
if (matchedPairs === difficulties[level].pairs) {
// If all pairs are matched, stop the timer
clearInterval(timerId);
// Show the level complete modal after a brief delay
setTimeout(showLevelCompleteModal, 500);
}
} else{
setTimeout(() => {
// Remove the 'flipped' class
card1.classList.remove('flipped');
card2.classList.remove('flipped');
// Set the content back to the question mark
card1.innerHTML = `<i class="fas fa-question"></i>`;
card2.innerHTML = `<i class="fas fa-question"></i>`;
}, 1000);
}

// Reset the flipped cards array for the next turn
flippedCards = [];

}

    


     - Displays the time's up notification modal.

/**
* Shows a time's up modal when the time limit is reached
*/
function showTimeUpModal() {
// Display the time's up modal
timeUpModal.style.display = 'flex';
}




     - Displays level completion celebration with player statistics


/**
* Shows the level completion modal with stats
* Called when all pairs in a level are matched
*/
function showLevelCompleteModal() {
// Update level completion information
document.getElementById('completedLevel').textContent = level;
document.getElementById('completionTime').textContent = timeDisplay.textContent;
document.getElementById('completionMoves').textContent = moves;

// Display the level complete modal
levelCompleteModal.style.display = 'block';
}

    


     - Advances the game to the next difficulty level or completes the game.


/**
* Advances to the next level
* Called when the next level button is clicked
*/
function nextLevel() {
// Increment the level
level++;

// Check if this was the final level
if (level > 3) {
// If so, show game completed modal and reset to level 1
level = 1;
// Hide the level complete modal
levelCompleteModal.style.display = 'none';
// Show the game completed modal
showGameCompletedModal();
}
else{
// Start a new game with the updated level
startGame();
// Hide the level complete modal
levelCompleteModal.style.display = 'none';
}
}

    


     - Resets the entire game back to level 1 after completion.


/**
* Resets the game to level 1 after completing all levels
*/
function playAgain() {
// Reset to level 1
level = 1;
// Start a new game
startGame();
// Hide the game completed modal
gameCompletedModal.style.display = 'none';
}




     - Displays the final celebration modal.


/**
* Shows the game completed modal with animations
*/
function showGameCompletedModal() {
// Display the game completed modal
gameCompletedModal.style.display = 'flex';
}




     - Initializes or resets the game state and creates a new game board.

/**
* Starts or restarts the game
* Resets the game state and creates a new game board
*/
function startGame() {
// Reset game board and game state
gameBoard.innerHTML = ''; // Clear the game board
flippedCards = []; // Reset flipped cards array
matchedPairs = 0; // Reset matched pairs counter
moves = 0; // Reset moves counter
timeElapsed = 0; // Reset time elapsed

// Reset UI displays
movesDisplay.textContent = '0'; // Reset moves display
timeDisplay.textContent = '00:00'; // Reset time display
levelDisplay.textContent = level; // Update level display

// Hide any open modals
timeUpModal.style.display = 'none';
levelCompleteModal.style.display = 'none';
gameCompletedModal.style.display = 'none';

// Reset and start the game timer
clearInterval(timerId); // Clear any existing timer
timerId = setInterval(updateTime, 1000); // Start a new timer

// All possible icons for the cards
const allIcons = [
'fa-heart', 'fa-star', 'fa-smile', 'fa-sun', 'fa-moon', 'fa-tree',
'fa-bell', 'fa-gift', 'fa-leaf', 'fa-car', 'fa-home', 'fa-globe'
];

// Select the appropriate number of icons for the current level
icons = allIcons.slice(0, difficulties[level].pairs);
// Duplicate each icon to create pairs
icons = [...icons, ...icons];
// Shuffle the icons
shuffleArray(icons);

// Create a card for each icon and add it to the game board
icons.forEach(icon => {
const card = createCard(icon);
gameBoard.appendChild(card);
});
}




The Final Result:

JavaScript Memory Game Source Code

JavaScript Memory Cards Game Source Code

Time's Up Modal

JavaScript Memory Cards Game

Level Complete Modal

Memory Cards Game In JavaScript

Memory Cards Game In JavaScript, HTML And Css

Congratulations Message




if you want the full source code click on the download button below




disclaimer: you will get the source code, and to make it work in your machine is your responsibility and to debug any error/exception is your responsibility this project is for the students who want to see an example and read the code not to get and run.








Python Wooden Chess Board

How To Create a Wooden Chessboard in Python Using Tkinter

How To Create a Wooden Chessboard in Python Using Tkinter


In this Python Tutorial we will see How to Create a wooden chess board using Python's built-in Tkinter library.

What We Are Gonna Use In This Project:

- Python Programming Language.
- Tkinter (GUI).
- VS Editor.






Project Source Code:




import tkinter as tk
import random
import math

class WoodenChessboard:
def __init__(self, root):
"""
Initialize the chess board application
Parameters:
root: The main Tkinter window
"""
self.root = root
self.root.title("Modern Chess Board")
# Colors for the board
self.light_square_color = "#F0D9B5" # Light cream color
self.dark_square_color = "#B58863" # Medium brown
self.border_color = "#3E2723" # Dark chocolate brown
self.text_color = "#FFFFFF" # White text for better visibility
# Board dimensions
self.square_size = 70 # Size of each square in pixels
self.board_size = 8 * self.square_size # Total board size (8x8 squares)
self.padding = 30 # Border width around the board
# Set up the canvas with padding for borders
# Canvas is the drawing area where we'll create our chess board
self.canvas = tk.Canvas(
root,
width=self.board_size + 2 * self.padding,
height=self.board_size + 2 * self.padding,
bg=self.border_color
)
self.canvas.pack(padx=10, pady=10)
# Draw the border with wood texture
self.draw_wooden_border()
# Draw the chess board squares and coordinates
self.draw_board()
def draw_wooden_border(self):
"""
Draw a wooden border with grain texture around the chess board
"""
# Calculate total width and height including border
outer_width = self.board_size + 2 * self.padding
outer_height = self.board_size + 2 * self.padding
# Draw border background
self.canvas.create_rectangle(
0, 0, outer_width, outer_height,
fill=self.border_color, outline=""
)
# Create wood grain effect with different shades of brown
grain_colors = ["#3E2723", "#4E342E", "#5D4037"]
# Draw horizontal grain lines for top and bottom borders
for y in range(0, self.padding):
# Choose a random color variation for each line
color = random.choice(grain_colors)
# Add random waviness to make the grain look natural
waviness = random.randint(0, 3)
thickness = random.randint(1, 2)

# Top border grain
y_pos = y
pts = []
# Create wavy points for the line
for x in range(0, outer_width, 5):
wave = math.sin(x/20) * waviness
pts.extend([x, y_pos + wave])
if pts:
self.canvas.create_line(pts, fill=color, width=thickness, smooth=True)
# Bottom border grain (mirror of top)
y_pos = outer_height - y
pts = []
for x in range(0, outer_width, 5):
wave = math.sin(x/20) * waviness
pts.extend([x, y_pos + wave])
if pts:
self.canvas.create_line(pts, fill=color, width=thickness, smooth=True)
# Draw vertical grain lines for left and right borders
for x in range(0, self.padding):
color = random.choice(grain_colors)
waviness = random.randint(0, 3)
thickness = random.randint(1, 2)
# Left border grain
x_pos = x
pts = []
for y in range(0, outer_height, 5):
wave = math.sin(y/20) * waviness
pts.extend([x_pos + wave, y])
if pts:
self.canvas.create_line(pts, fill=color, width=thickness, smooth=True)
# Right border grain (mirror of left)
x_pos = outer_width - x
pts = []
for y in range(0, outer_height, 5):
wave = math.sin(y/20) * waviness
pts.extend([x_pos + wave, y])
if pts:
self.canvas.create_line(pts, fill=color, width=thickness, smooth=True)
def draw_board(self):
"""
Draw the chess board with squares and coordinate labels
"""
# Draw file labels (columns: a-h)
for i in range(8):
file_label = chr(97 + i) # ASCII: 'a' is 97, so we get 'a' through 'h'
# Bottom row labels
self.canvas.create_text(
self.padding + i * self.square_size + self.square_size // 2,
self.padding + self.board_size + 15,
text=file_label,
fill=self.text_color,
font=("Arial", 12, "bold")
)

# Top row labels
self.canvas.create_text(
self.padding + i * self.square_size + self.square_size // 2,
self.padding - 15,
text=file_label,
fill=self.text_color,
font=("Arial", 12, "bold")
)
# Draw rank labels (rows: 1-8)
for i in range(8):
rank_label = str(8 - i) # Count down from 8 to 1 (chess notation)
# Left side labels
self.canvas.create_text(
self.padding - 15,
self.padding + i * self.square_size + self.square_size // 2,
text=rank_label,
fill=self.text_color,
font=("Arial", 12, "bold")
)
# Right side labels
self.canvas.create_text(
self.padding + self.board_size + 15,
self.padding + i * self.square_size + self.square_size // 2,
text=rank_label,
fill=self.text_color,
font=("Arial", 12, "bold")
)
# Draw all 64 squares of the chess board
for row in range(8):
for col in range(8):
# Determine if this is a light or dark square
# If row+col is even, it's a light square; if odd, it's dark
is_light = (row + col) % 2 == 0
base_color = self.light_square_color if is_light else self.dark_square_color
# Calculate the position of the square on the canvas
x1 = self.padding + col * self.square_size
y1 = self.padding + row * self.square_size
x2 = x1 + self.square_size
y2 = y1 + self.square_size
# Create the square
square_id = self.canvas.create_rectangle(
x1, y1, x2, y2,
fill=base_color,
outline="", # No outline for a cleaner look
tags=f"square_{row}_{col}" # Tag to identify the square later if needed
)
# Add subtle wood grain texture to each square
self.add_wood_grain(x1, y1, x2, y2, is_light)
def add_wood_grain(self, x1, y1, x2, y2, is_light):
"""
Add subtle wood grain texture to a square
Parameters:
x1, y1: Top-left corner coordinates
x2, y2: Bottom-right corner coordinates
is_light: Boolean indicating if it's a light square
"""
if is_light:
# Light square grain (vertical lines with slight variation)
grain_color = "#E5C99E" # Slightly darker than the light square
grain_spacing = 4 # Space between grain lines

for i in range(int(x1) + 2, int(x2), grain_spacing):
# Add randomness to make grain look natural
waviness = random.randint(0, 2)
thickness = random.choice([1, 1, 2]) # Mostly thin lines

# Create a wavy line for the grain effect
points = []
for y in range(int(y1), int(y2), 5):
wave = math.sin(y/10) * waviness
points.extend([i + wave, y])

if points:
self.canvas.create_line(
points,
fill=grain_color,
width=thickness,
smooth=True
)
else:
# Dark square grain (more subtle)
grain_color = "#A07855" # Slightly lighter than the dark square
grain_spacing = 6

for i in range(int(x1) + 3, int(x2), grain_spacing):
waviness = random.randint(0, 1)
# Create subtle grain lines
points = []
for y in range(int(y1), int(y2), 10):
wave = math.sin(y/15) * waviness
points.extend([i + wave, y])

if points:
self.canvas.create_line(
points,
fill=grain_color,
width=1,
smooth=True
)



# Run the application
if __name__ == "__main__":
root = tk.Tk()
# Configure the window
root.configure(bg="#2C2C2C") # Dark background for modern look
# Create the chess board
app = WoodenChessboard(root)
# Start the application
root.mainloop()



The Final Result: