{"id":784,"date":"2026-04-22T16:03:05","date_gmt":"2026-04-22T16:03:05","guid":{"rendered":"https:\/\/museum.wiserighteous.org\/?page_id=784"},"modified":"2026-04-22T16:03:31","modified_gmt":"2026-04-22T16:03:31","slug":"righteous-animals-memory-match-game","status":"publish","type":"page","link":"https:\/\/museum.wiserighteous.org\/index.php\/righteous-animals-memory-match-game\/","title":{"rendered":"Righteous Animals Memory Match Game"},"content":{"rendered":"\n<pre class=\"wp-block-preformatted\">Test your memory! Flip the cards and match each righteous animal hero. Learn fun facts about animals who showed courage, loyalty, and kindness.<\/pre>\n\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">\n    <title>Righteous Museum | Match the Righteous Animals<\/title>\n    <style>\n        * {\n            box-sizing: border-box;\n            user-select: none;\n        }\n\n        body {\n            background: linear-gradient(135deg, #1a472a 0%, #0e2a1a 100%);\n            font-family: 'Comic Neue', 'Comic Sans MS', 'Chalkboard SE', 'Segoe UI Emoji', cursive, sans-serif;\n            min-height: 100vh;\n            margin: 0;\n            padding: 20px;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n        }\n\n        .game-container {\n            max-width: 900px;\n            width: 100%;\n            background: #FFF8E7;\n            border-radius: 60px;\n            padding: 20px 20px 30px;\n            box-shadow: 0 25px 40px rgba(0,0,0,0.3);\n            text-align: center;\n        }\n\n        h1 {\n            margin: 0;\n            font-size: 1.8rem;\n            background: linear-gradient(135deg, #c9a03d, #8b5e1f);\n            -webkit-background-clip: text;\n            background-clip: text;\n            color: transparent;\n            display: inline-block;\n            padding: 0 10px;\n        }\n\n        .subtitle {\n            font-size: 1rem;\n            color: #5a3e1b;\n            margin-top: 5px;\n            margin-bottom: 20px;\n        }\n\n        .stats {\n            display: flex;\n            justify-content: space-between;\n            background: #e6d5b3;\n            padding: 12px 25px;\n            border-radius: 50px;\n            margin-bottom: 25px;\n            font-weight: bold;\n            font-size: 1.3rem;\n        }\n\n        .stats span {\n            background: #2c5e3a;\n            padding: 5px 18px;\n            border-radius: 40px;\n            color: #FFD966;\n        }\n\n        .board {\n            display: grid;\n            grid-template-columns: repeat(4, 1fr);\n            gap: 12px;\n            margin-bottom: 25px;\n        }\n\n        .card {\n            aspect-ratio: 4 \/ 3;\n            background: #D2B48C;\n            border-radius: 20px;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 2.2rem;\n            font-weight: bold;\n            transition: all 0.2s ease;\n            box-shadow: 0 8px 0 #6b4c2c;\n            transform: translateY(-2px);\n            text-align: center;\n            flex-direction: column;\n            gap: 5px;\n            padding: 8px;\n        }\n\n        .card.flipped, .card.matched {\n            background: #FFE4A3;\n            box-shadow: 0 4px 0 #6b4c2c;\n            transform: translateY(2px);\n        }\n\n        .card.matched {\n            background: #90be6d;\n            cursor: default;\n            opacity: 0.7;\n            filter: grayscale(0.1);\n        }\n\n        .card:active {\n            transform: translateY(2px);\n            box-shadow: 0 4px 0 #6b4c2c;\n        }\n\n        .card-front {\n            display: none;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n            gap: 8px;\n        }\n\n        .card.flipped .card-front, .card.matched .card-front {\n            display: flex;\n        }\n\n        .card .card-back {\n            font-size: 3rem;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: center;\n        }\n\n        .card.flipped .card-back, .card.matched .card-back {\n            display: none;\n        }\n\n        .animal-icon {\n            font-size: 2.8rem;\n        }\n\n        .animal-name {\n            font-size: 0.7rem;\n            font-weight: bold;\n            background: #8b5e1f40;\n            padding: 4px 8px;\n            border-radius: 30px;\n            color: #3b2a1a;\n        }\n\n        .fact-bar {\n            background: #e0c48b;\n            padding: 12px;\n            border-radius: 50px;\n            margin: 15px 0;\n            font-size: 0.85rem;\n            color: #2d2b1f;\n            font-weight: bold;\n        }\n\n        button {\n            background: #c9a03d;\n            border: none;\n            padding: 12px 28px;\n            font-size: 1.2rem;\n            font-weight: bold;\n            border-radius: 50px;\n            color: #2c1e0a;\n            cursor: pointer;\n            transition: 0.1s linear;\n            box-shadow: 0 5px 0 #6b4c2c;\n            font-family: inherit;\n        }\n\n        button:active {\n            transform: translateY(2px);\n            box-shadow: 0 2px 0 #6b4c2c;\n        }\n\n        .victory-overlay {\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0,0,0,0.8);\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            z-index: 1000;\n            visibility: hidden;\n            backdrop-filter: blur(4px);\n        }\n\n        .victory-card {\n            background: #FFF8E7;\n            padding: 30px 20px;\n            border-radius: 60px;\n            text-align: center;\n            max-width: 350px;\n            width: 80%;\n        }\n\n        .victory-card h2 {\n            font-size: 2rem;\n            margin: 10px 0;\n        }\n\n        @media (max-width: 550px) {\n            .board {\n                gap: 8px;\n            }\n            .animal-icon {\n                font-size: 1.8rem;\n            }\n            .animal-name {\n                font-size: 0.55rem;\n            }\n            .stats span {\n                font-size: 1rem;\n                padding: 5px 12px;\n            }\n        }\n    <\/style>\n<\/head>\n<body>\n\n<div class=\"game-container\">\n    <h1>\ud83d\udc3e RIGHTEOUS MUSEUM \ud83d\udc3e<\/h1>\n    <div class=\"subtitle\">Match the Righteous Animals \u2014 Heroes with fur, feathers &#038; fins<\/div>\n\n    <div class=\"stats\">\n        <div>\u2b50 MATCHES: <span id=\"matchCount\">0<\/span> \/ <span id=\"totalPairs\">6<\/span><\/div>\n        <div>\u23f1\ufe0f TIME: <span id=\"timerDisplay\">00:00<\/span><\/div>\n    <\/div>\n\n    <div class=\"board\" id=\"gameBoard\"><\/div>\n\n    <div class=\"fact-bar\" id=\"factBar\">\n        \ud83d\udc3e Click a card to start! Match each animal hero.\n    <\/div>\n\n    <button id=\"resetButton\">\ud83d\udd04 PLAY AGAIN<\/button>\n<\/div>\n\n<div id=\"victoryOverlay\" class=\"victory-overlay\">\n    <div class=\"victory-card\">\n        <div>\ud83c\udf1f\ud83d\udc3e\ud83c\udf1f\ud83d\udc3e\ud83c\udf1f\ud83d\udc3e\ud83c\udf1f<\/div>\n        <h2>YOU ARE A RIGHTEOUS ANIMAL HERO!<\/h2>\n        <p>&#8220;Bravery has no species \u2014 only heart.&#8221;<\/p>\n        <button id=\"victoryResetBtn\">\ud83d\udc15 PLAY AGAIN \ud83d\udc15<\/button>\n    <\/div>\n<\/div>\n\n<script>\n    \/\/ ANIMAL DATA: icon + display name + fact\n    const animalsData = [\n        { icon: \"\ud83d\udc15\", name: \"Lifesaving Dog\", fact: \"\ud83d\udc15 Some dogs have received medals for saving people from drowning or fire!\" },\n        { icon: \"\ud83d\udc2c\", name: \"Protective Dolphin\", fact: \"\ud83d\udc2c Dolphins have been known to protect swimmers from sharks and guide lost boats!\" },\n        { icon: \"\ud83d\udd4a\ufe0f\", name: \"Messenger Pigeon\", fact: \"\ud83d\udd4a\ufe0f A carrier pigeon named Cher Ami saved 194 soldiers during World War I!\" },\n        { icon: \"\ud83d\udc18\", name: \"Grieving Elephant\", fact: \"\ud83d\udc18 Elephants mourn their loved ones and have rescued trapped herd members!\" },\n        { icon: \"\ud83d\udc0e\", name: \"Battle Horse\", fact: \"\ud83d\udc0e Horses in war have carried wounded soldiers miles to safety!\" },\n        { icon: \"\ud83d\udc2b\", name: \"Desert Camel\", fact: \"\ud83d\udc2b Camels have saved travelers by finding water and enduring extreme conditions!\" }\n    ];\n\n    let cards = [];\n    let flippedCards = [];\n    let matchedPairs = 0;\n    let lockBoard = false;\n    let timerSeconds = 0;\n    let timerInterval = null;\n    let gameActive = true;\n\n    const boardElement = document.getElementById('gameBoard');\n    const matchCountSpan = document.getElementById('matchCount');\n    const timerDisplaySpan = document.getElementById('timerDisplay');\n    const factBar = document.getElementById('factBar');\n    const resetButton = document.getElementById('resetButton');\n    const victoryOverlay = document.getElementById('victoryOverlay');\n    const victoryResetBtn = document.getElementById('victoryResetBtn');\n\n    function formatTime(sec) {\n        let mins = Math.floor(sec \/ 60);\n        let remainSec = sec % 60;\n        return `${mins.toString().padStart(2, '0')}:${remainSec.toString().padStart(2, '0')}`;\n    }\n\n    function updateTimerDisplay() {\n        timerDisplaySpan.textContent = formatTime(timerSeconds);\n    }\n\n    function startTimer() {\n        if (timerInterval) clearInterval(timerInterval);\n        timerInterval = setInterval(() => {\n            if (!gameActive) return;\n            if (lockBoard) return;\n            timerSeconds++;\n            updateTimerDisplay();\n        }, 1000);\n    }\n\n    function stopTimer() {\n        if (timerInterval) {\n            clearInterval(timerInterval);\n            timerInterval = null;\n        }\n    }\n\n    function resetTimer() {\n        stopTimer();\n        timerSeconds = 0;\n        updateTimerDisplay();\n        if (gameActive) startTimer();\n    }\n\n    function shuffleArray(arr) {\n        for (let i = arr.length - 1; i > 0; i--) {\n            const j = Math.floor(Math.random() * (i + 1));\n            [arr[i], arr[j]] = [arr[j], arr[i]];\n        }\n        return arr;\n    }\n\n    function initCards() {\n        let deck = [];\n        for (let i = 0; i < animalsData.length; i++) {\n            deck.push({ id: i, animalIndex: i, matched: false, flipped: false, element: null });\n            deck.push({ id: i + animalsData.length, animalIndex: i, matched: false, flipped: false, element: null });\n        }\n        return shuffleArray(deck);\n    }\n\n    function checkWin() {\n        if (matchedPairs === animalsData.length) {\n            gameActive = false;\n            stopTimer();\n            victoryOverlay.style.visibility = \"visible\";\n        }\n    }\n\n    function updateMatchCounter() {\n        matchCountSpan.textContent = matchedPairs;\n    }\n\n    function setFactMessage(animalIndex) {\n        factBar.innerHTML = `\ud83d\udcd6 ${animalsData[animalIndex].fact}`;\n    }\n\n    function resetGame() {\n        stopTimer();\n        gameActive = true;\n        matchedPairs = 0;\n        flippedCards = [];\n        lockBoard = false;\n        updateMatchCounter();\n        \n        \/\/ reset victory overlay visibility\n        victoryOverlay.style.visibility = \"hidden\";\n        \n        \/\/ reset timer\n        timerSeconds = 0;\n        updateTimerDisplay();\n        startTimer();\n        \n        \/\/ rebuild board\n        cards = initCards();\n        renderBoard();\n    }\n\n    function renderBoard() {\n        boardElement.innerHTML = '';\n        cards.forEach((card, idx) => {\n            const animal = animalsData[card.animalIndex];\n            const cardDiv = document.createElement('div');\n            cardDiv.className = 'card';\n            if (card.matched) cardDiv.classList.add('matched');\n            if (card.flipped) cardDiv.classList.add('flipped');\n            \n            \/\/ back side (question)\n            const backDiv = document.createElement('div');\n            backDiv.className = 'card-back';\n            backDiv.innerHTML = '\u2753';\n            \n            \/\/ front side (animal)\n            const frontDiv = document.createElement('div');\n            frontDiv.className = 'card-front';\n            frontDiv.innerHTML = `\n                <div class=\"animal-icon\">${animal.icon}<\/div>\n                <div class=\"animal-name\">${animal.name}<\/div>\n            `;\n            \n            cardDiv.appendChild(backDiv);\n            cardDiv.appendChild(frontDiv);\n            \n            cardDiv.addEventListener('click', (e) => {\n                e.stopPropagation();\n                if (lockBoard) return;\n                if (!gameActive) return;\n                if (card.matched) return;\n                if (card.flipped) return;\n                if (flippedCards.length === 2) return;\n                \n                \/\/ flip card\n                card.flipped = true;\n                renderBoard();\n                \n                flippedCards.push(card);\n                \n                if (flippedCards.length === 2) {\n                    lockBoard = true;\n                    const cardA = flippedCards[0];\n                    const cardB = flippedCards[1];\n                    \n                    if (cardA.animalIndex === cardB.animalIndex) {\n                        \/\/ MATCH!\n                        cardA.matched = true;\n                        cardB.matched = true;\n                        cardA.flipped = false;\n                        cardB.flipped = false;\n                        matchedPairs++;\n                        updateMatchCounter();\n                        setFactMessage(cardA.animalIndex);\n                        \n                        flippedCards = [];\n                        lockBoard = false;\n                        renderBoard();\n                        checkWin();\n                    } else {\n                        \/\/ NO MATCH - show red flash, then flip back\n                        setTimeout(() => {\n                            cardA.flipped = false;\n                            cardB.flipped = false;\n                            flippedCards = [];\n                            lockBoard = false;\n                            renderBoard();\n                        }, 800);\n                        \/\/ Visual feedback via class (we add a quick red effect)\n                        const elements = document.querySelectorAll('.card');\n                        elements.forEach(el => {\n                            if (el === cardA.elementRef || el === cardB.elementRef) {\n                                el.style.transition = '0.1s';\n                                el.style.backgroundColor = '#ffb3b3';\n                                setTimeout(() => {\n                                    if (el) el.style.backgroundColor = '';\n                                }, 300);\n                            }\n                        });\n                        renderBoard();\n                    }\n                }\n            });\n            \n            \/\/ store element reference for visual effect\n            card.elementRef = cardDiv;\n            boardElement.appendChild(cardDiv);\n        });\n    }\n\n    function startNewGame() {\n        stopTimer();\n        gameActive = true;\n        matchedPairs = 0;\n        flippedCards = [];\n        lockBoard = false;\n        updateMatchCounter();\n        victoryOverlay.style.visibility = \"hidden\";\n        timerSeconds = 0;\n        updateTimerDisplay();\n        cards = initCards();\n        renderBoard();\n        startTimer();\n        factBar.innerHTML = \"\ud83d\udc3e Match the pairs! Each righteous animal has a story.\";\n    }\n\n    resetButton.addEventListener('click', () => {\n        startNewGame();\n    });\n    \n    victoryResetBtn.addEventListener('click', () => {\n        startNewGame();\n    });\n\n    \/\/ start the game\n    startNewGame();\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Test your memory! Flip the cards and match each righteous animal hero. Learn fun facts about animals who showed courage, loyalty, and kindness. Righteous Museum | Match the Righteous Animals \ud83d\udc3e RIGHTEOUS MUSEUM \ud83d\udc3e Match the Righteous Animals \u2014 Heroes with fur, feathers &#038; fins \u2b50 MATCHES: 0 \/ 6 \u23f1\ufe0f TIME: 00:00 \ud83d\udc3e Click [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-784","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages\/784","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/comments?post=784"}],"version-history":[{"count":2,"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages\/784\/revisions"}],"predecessor-version":[{"id":786,"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages\/784\/revisions\/786"}],"wp:attachment":[{"href":"https:\/\/museum.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/media?parent=784"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}