• Home
  • /
  • Memory Card Game HTML CSS JS

Memory Card Game with HTML, CSS and JS

HTML

				
					<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Memory Card Game | Learn with Arshyan</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: linear-gradient(135deg, #f5f7fa 0%, #e4e7eb 100%);
            min-height: 100vh;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .container {
            max-width: 900px;
            width: 100%;
            margin: 0 auto;
        }

        /* Header Styles */
        header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 25px;
            padding: 15px 25px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 16px;
            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.05);
            border: 1px solid rgba(0, 0, 0, 0.03);
        }

        .brand {
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .logo {
            width: 50px;
            height: 50px;
            background: linear-gradient(135deg, #3a8ffe 0%, #5e5df0 100%);
            border-radius: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 22px;
            font-weight: bold;
        }

        .brand-text h1 {
            font-size: 24px;
            color: #333;
            font-weight: 700;
            letter-spacing: -0.5px;
        }

        .brand-text p {
            font-size: 13px;
            color: #777;
            font-weight: 500;
        }

        /* Game Controls */
        .game-controls {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .btn {
            background: linear-gradient(to right, #5e5df0, #3a8ffe);
            color: white;
            border: none;
            padding: 10px 22px;
            border-radius: 12px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 4px 12px rgba(94, 93, 240, 0.2);
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 15px rgba(94, 93, 240, 0.3);
        }

        /* Game Board */
        .game-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 25px;
        }

        .game-info {
            display: flex;
            justify-content: space-between;
            width: 100%;
            max-width: 800px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 16px;
            padding: 18px;
            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.05);
            border: 1px solid rgba(0, 0, 0, 0.03);
        }

        .info-item {
            display: flex;
            flex-direction: column;
            align-items: center;
            color: #555;
        }

        .info-value {
            font-size: 24px;
            font-weight: 700;
            margin-top: 5px;
            color: #5e5df0;
        }

        .stars {
            display: flex;
            gap: 4px;
            color: #ffc107;
            font-size: 20px;
        }

        .memory-board {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 15px;
            max-width: 800px;
            width: 100%;
            perspective: 1000px;
        }

        @media (min-width: 768px) {
            .memory-board {
                grid-template-columns: repeat(6, 1fr);
            }
        }

        .card {
            height: 110px;
            position: relative;
            cursor: pointer;
            transform-style: preserve-3d;
            transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
            border-radius: 12px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
        }

        .card.flipped {
            transform: rotateY(180deg);
        }

        .card-face {
            position: absolute;
            width: 100%;
            height: 100%;
            backface-visibility: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            border-radius: 12px;
            overflow: hidden;
        }

        .card-front {
            background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
            transform: rotateY(180deg);
            font-size: 36px;
            color: #5e5df0;
            border: 1px solid rgba(0, 0, 0, 0.05);
        }

        .card-back {
            background: linear-gradient(135deg, #5e5df0 0%, #3a8ffe 100%);
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* Win Screen */
        .win-screen {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.85);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 100;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.4s ease;
        }

        .win-screen.active {
            opacity: 1;
            pointer-events: all;
        }

        .win-content {
            background: white;
            border-radius: 20px;
            padding: 40px;
            text-align: center;
            max-width: 500px;
            width: 90%;
            transform: scale(0.9);
            transition: transform 0.4s ease;
            box-shadow: 0 15px 40px rgba(0, 0, 0, 0.25);
        }

        .win-screen.active .win-content {
            transform: scale(1);
        }

        .win-content h2 {
            font-size: 32px;
            color: #5e5df0;
            margin-bottom: 15px;
            font-weight: 700;
        }

        .win-stats {
            display: flex;
            justify-content: space-around;
            margin: 25px 0;
        }

        .win-stat {
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .win-stat-value {
            font-size: 26px;
            font-weight: 700;
            color: #333;
        }

        /* Footer */
        footer {
            text-align: center;
            padding: 20px;
            color: #777;
            font-size: 14px;
            margin-top: 30px;
        }

        footer a {
            color: #5e5df0;
            text-decoration: none;
            font-weight: 600;
        }

        footer a:hover {
            text-decoration: underline;
        }

        /* Animations */
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }

        .pulse {
            animation: pulse 0.4s ease-in-out;
        }

        .match {
            animation: pulse 0.4s ease-in-out 2;
        }
        
        .instructions {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 16px;
            padding: 20px;
            margin-top: 20px;
            max-width: 800px;
            width: 100%;
            box-shadow: 0 6px 20px rgba(0, 0, 0, 0.05);
            border: 1px solid rgba(0, 0, 0, 0.03);
        }
        
        .instructions h3 {
            color: #5e5df0;
            margin-bottom: 12px;
            font-size: 18px;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        .instructions ul {
            padding-left: 22px;
        }
        
        .instructions li {
            margin: 8px 0;
            color: #555;
            font-size: 14px;
        }
        
        .progress-bar {
            height: 6px;
            background: rgba(94, 93, 240, 0.15);
            border-radius: 3px;
            margin-top: 15px;
            overflow: hidden;
        }
        
        .progress {
            height: 100%;
            background: linear-gradient(to right, #5e5df0, #3a8ffe);
            width: 0%;
            transition: width 0.3s ease;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <div class="brand">
                <div class="logo">LwA</div>
                <div class="brand-text">
                    <h1>Learn with Arshyan</h1>
                    <div class='code-block code-block-2' style='margin: 8px 0; clear: both;'>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2094722033678002"
     crossorigin="anonymous"></script>
<ins class="adsbygoogle"
     style="display:block; text-align:center;"
     data-ad-layout="in-article"
     data-ad-format="fluid"
     data-ad-client="ca-pub-2094722033678002"
     data-ad-slot="2248279416"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
<p>Project 3: Memory Card Game</p>
                </div>
            </div>
            <div class="game-controls">
                <button class="btn" id="restart-btn">
                    <i class="fas fa-sync-alt"></i> New Game
                </button>
            </div>
        </header>

        <main class="game-container">
            <div class="game-info">
                <div class="info-item">
                    <span>Moves</span>
                    <div class="info-value" id="moves">0</div>
                </div>
                <div class="info-item">
                    <span>Time</span>
                    <div class="info-value" id="timer">00:00</div>
                </div>
                <div class="info-item">
                    <span>Rating</span>
                    <div class="stars" id="stars">
                        <i class="fas fa-star"></i>
                        <i class="fas fa-star"></i>
                        <i class="fas fa-star"></i>
                    </div>
                </div>
            </div>

            <div class="progress-bar">
                <div class="progress" id="progress"></div>
            </div>

            <div class="memory-board" id="game-board">
                <!-- Cards will be generated by JavaScript -->
            </div>
            
            <div class="instructions">
                <h3><i class="fas fa-info-circle"></i> How to Play</h3>
                <ul>
                    <li>Click on cards to flip them and reveal symbols</li>
                    <li>Find matching pairs of cards</li>
                    <li>Try to complete the game with the fewest moves</li>
                    <li>Complete the game as quickly as possible</li>
                </ul>
            </div>
        </main>
        
        <div class="win-screen" id="win-screen">
            <div class="win-content">
                <h2>Well Done!</h2>
                <p>You've matched all the cards successfully</p>
                
                <div class="win-stats">
                    <div class="win-stat">
                        <span>Time</span>
                        <div class="win-stat-value" id="win-time">00:00</div>
                    </div>
                    <div class="win-stat">
                        <span>Moves</span>
                        <div class="win-stat-value" id="win-moves">0</div>
                    </div>
                    <div class="win-stat">
                        <span>Rating</span>
                        <div class="win-stat-value" id="win-rating">3/3</div>
                    </div>
                </div>
                
                <button class="btn" id="play-again-btn" style="margin-top: 20px;">
                    <i class="fas fa-play"></i> Play Again
                </button>
            </div>
        </div>

        <footer>
            <p>Created by <a href="#">Learn with Arshyan</a> | Memory Card Game Project | Source Code: learnwitharshyan.com/code | &copy; 2025</p>
        </footer>
    </div>

    <script>
        // DOM Elements
        const gameBoard = document.getElementById('game-board');
        const movesDisplay = document.getElementById('moves');
        const timerDisplay = document.getElementById('timer');
        const starsDisplay = document.getElementById('stars');
        const winScreen = document.getElementById('win-screen');
        const winTime = document.getElementById('win-time');
        const winMoves = document.getElementById('win-moves');
        const winRating = document.getElementById('win-rating');
        const restartBtn = document.getElementById('restart-btn');
        const playAgainBtn = document.getElementById('play-again-btn');
        const progressBar = document.getElementById('progress');

        // Game state
        let cards = [];
        let flippedCards = [];
        let matchedPairs = 0;
        let moves = 0;
        let timer = null;
        let seconds = 0;
        let starRating = 3;
        let gameStarted = false;

        // Card icons
        const cardIcons = [
            'fa-heart', 'fa-star', 'fa-moon', 'fa-sun',
            'fa-cloud', 'fa-bolt', 'fa-snowflake', 'fa-gem',
            'fa-key', 'fa-flag', 'fa-bell', 'fa-music'
        ];

        // Initialize game
        function initGame() {
            // Reset game state
            gameBoard.innerHTML = '';
            flippedCards = [];
            matchedPairs = 0;
            moves = 0;
            seconds = 0;
            starRating = 3;
            gameStarted = false;
            progressBar.style.width = '0%';
            
            // Reset displays
            movesDisplay.textContent = moves;
            timerDisplay.textContent = '00:00';
            starsDisplay.innerHTML = '<i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star"></i>';
            
            // Create card deck (duplicate and shuffle)
            let deck = [];
            cardIcons.slice(0, 6).forEach(icon => {
                deck.push(icon);
                deck.push(icon);
            });
            
            // Shuffle deck
            deck = shuffleArray(deck);
            
            // Create cards
            deck.forEach((icon, index) => {
                const card = document.createElement('div');
                card.className = 'card';
                card.dataset.icon = icon;
                card.dataset.index = index;
                
                card.innerHTML = `
                    <div class="card-face card-back"></div>
                    <div class="card-face card-front">
                        <i class="fas ${icon}"></i>
                    </div>
                `;
                
                card.addEventListener('click', flipCard);
                gameBoard.appendChild(card);
                cards.push(card);
            });
        }

        // Shuffle array (Fisher-Yates algorithm)
        function shuffleArray(array) {
            for (let i = array.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
            return array;
        }

        // Flip card function
        function flipCard() {
            if (!gameStarted) {
                startTimer();
                gameStarted = true;
            }
            
            // Prevent flipping matched cards or when 2 are already flipped
            if (this.classList.contains('flipped') || flippedCards.length === 2) {
                return;
            }
            
            // Flip the card
            this.classList.add('flipped');
            flippedCards.push(this);
            
            // When two cards are flipped
            if (flippedCards.length === 2) {
                moves++;
                movesDisplay.textContent = moves;
                
                // Update progress bar
                progressBar.style.width = `${(matchedPairs / 6) * 100}%`;
                
                // Update star rating
                updateRating();
                
                // Check for match
                const isMatch = flippedCards[0].dataset.icon === flippedCards[1].dataset.icon;
                
                if (isMatch) {
                    // Match found
                    flippedCards[0].classList.add('match');
                    flippedCards[1].classList.add('match');
                    flippedCards = [];
                    matchedPairs++;
                    
                    // Update progress bar
                    progressBar.style.width = `${(matchedPairs / 6) * 100}%`;
                    
                    // Check for win
                    if (matchedPairs === 6) {
                        endGame();
                    }
                } else {
                    // No match - flip back after delay
                    setTimeout(() => {
                        flippedCards[0].classList.remove('flipped');
                        flippedCards[1].classList.remove('flipped');
                        flippedCards = [];
                    }, 800);
                }
            }
        }

        // Start game timer
        function startTimer() {
            timer = setInterval(() => {
                seconds++;
                const minutes = Math.floor(seconds / 60).toString().padStart(2, '0');
                const secs = (seconds % 60).toString().padStart(2, '0');
                timerDisplay.textContent = `${minutes}:${secs}`;
            }, 1000);
        }

        // Update star rating based on moves
        function updateRating() {
            if (moves === 15) {
                starRating = 2;
                starsDisplay.innerHTML = '<i class="fas fa-star"></i><i class="fas fa-star"></i><i class="fas fa-star" style="opacity:0.3"></i>';
            } else if (moves === 25) {
                starRating = 1;
                starsDisplay.innerHTML = '<i class="fas fa-star"></i><i class="fas fa-star" style="opacity:0.3"></i><i class="fas fa-star" style="opacity:0.3"></i>';
            } else if (moves > 35) {
                starRating = 0;
                starsDisplay.innerHTML = '<i class="fas fa-star" style="opacity:0.3"></i><i class="fas fa-star" style="opacity:0.3"></i><i class="fas fa-star" style="opacity:0.3"></i>';
            }
        }

        // End game function
        function endGame() {
            clearInterval(timer);
            progressBar.style.width = '100%';
            
            // Set win screen values
            winTime.textContent = timerDisplay.textContent;
            winMoves.textContent = moves;
            winRating.textContent = `${starRating}/3`;
            
            // Show win screen
            winScreen.classList.add('active');
        }

        // Restart game
        function restartGame() {
            clearInterval(timer);
            winScreen.classList.remove('active');
            initGame();
        }

        // Event listeners
        restartBtn.addEventListener('click', restartGame);
        playAgainBtn.addEventListener('click', restartGame);

        // Initialize game on load
        document.addEventListener('DOMContentLoaded', initGame);
    </script>
</body>
</html>
				
			

Share this post

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top