{"id":306,"date":"2025-07-26T01:04:19","date_gmt":"2025-07-26T01:04:19","guid":{"rendered":"https:\/\/insaatsirketleri.com.tr\/en\/?p=306"},"modified":"2025-07-26T01:04:19","modified_gmt":"2025-07-26T01:04:19","slug":"play-2048","status":"publish","type":"post","link":"https:\/\/insaatsirketleri.com.tr\/en\/play-2048\/","title":{"rendered":"Play 2048"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n   <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <!-- Google Fonts - Inter -->\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;700&#038;display=swap\" rel=\"stylesheet\">\n    <style>\n        \/* General style settings *\/\n        body {\n            font-family: 'Inter', sans-serif;\n            background-color: #f7fafc;\n            display: flex;\n            flex-direction: column; \/* Changed to column to stack header, game, and controls *\/\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            margin: 0;\n            overflow: hidden; \/* Prevent horizontal scroll *\/\n        }\n\n        \/* Game container style settings *\/\n        .game-container {\n            background-color: #bbada0;\n            border-radius: 12px;\n            padding: 16px;\n            display: grid;\n            grid-template-columns: repeat(4, 1fr);\n            grid-template-rows: repeat(4, 1fr);\n            gap: 12px;\n            box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);\n            max-width: 500px;\n            width: 90vw; \/* Responsive width *\/\n            aspect-ratio: 1 \/ 1; \/* Maintain square aspect ratio *\/\n            position: relative;\n            margin-top: 20px; \/* Added margin for spacing *\/\n        }\n\n        \/* Game header and score section *\/\n        .game-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            width: 90vw;\n            max-width: 500px;\n            margin-bottom: 20px;\n        }\n\n        .game-title {\n            font-size: 3rem;\n            font-weight: 700;\n            color: #776e65;\n        }\n\n        .score-container {\n            background-color: #bbada0;\n            padding: 8px 16px;\n            border-radius: 8px;\n            text-align: center;\n            color: #eee4da;\n            font-weight: 700;\n            font-size: 1.5rem;\n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n        }\n\n        \/* Buttons styling *\/\n        .action-button {\n            background-color: #8f7a66;\n            color: #f9f6f2;\n            padding: 10px 20px;\n            border-radius: 8px;\n            font-weight: 700;\n            cursor: pointer;\n            transition: background-color 0.3s ease;\n            border: none; \/* Remove default button border *\/\n            margin: 5px; \/* Spacing between buttons *\/\n            min-width: 44px; \/* Ensure sufficient touch target size for mobile *\/\n            min-height: 44px; \/* Ensure sufficient touch target size for mobile *\/\n        }\n\n        .action-button:hover {\n            background-color: #6d5b4d;\n        }\n\n        \/* Empty cells styling *\/\n        .grid-cell {\n            width: 100%;\n            height: 100%;\n            background-color: rgba(238, 228, 218, 0.35);\n            border-radius: 8px;\n        }\n\n        \/* Game tiles styling *\/\n        .tile {\n            position: absolute;\n            \/* Calculate tile width and height dynamically based on container size and gap *\/\n            width: calc((100% - 3 * 12px) \/ 4);\n            height: calc((100% - 3 * 12px) \/ 4);\n            background-color: #eee4da;\n            border-radius: 8px;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            font-size: 2.5rem;\n            font-weight: 700;\n            color: #776e65;\n            transition: transform 0.1s ease-in-out, background-color 0.1s ease-in-out, color 0.1s ease-in-out;\n            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n            animation: appear 0.2s ease-out;\n        }\n\n        \/* Specific tile values styling *\/\n        .tile-2 { background-color: #eee4da; color: #776e65; }\n        .tile-4 { background-color: #ede0c8; color: #776e65; }\n        .tile-8 { background-color: #f2b179; color: #f9f6f2; }\n        .tile-16 { background-color: #f59563; color: #f9f6f2; }\n        .tile-32 { background-color: #f67c5f; color: #f9f6f2; }\n        .tile-64 { background-color: #f65e3b; color: #f9f6f2; }\n        .tile-128 { background-color: #edcf72; color: #f9f6f2; font-size: 2rem; }\n        .tile-256 { background-color: #edcc61; color: #f9f9f2; font-size: 2rem; }\n        .tile-512 { background-color: #edc850; color: #f9f9f2; font-size: 2rem; }\n        .tile-1024 { background-color: #edc53f; color: #f9f9f2; font-size: 1.5rem; }\n        .tile-2048 { background-color: #edc22e; color: #f9f9f2; font-size: 1.5rem; }\n\n        \/* Game message overlays *\/\n        .game-message {\n            position: absolute;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background-color: rgba(255, 255, 255, 0.8);\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            align-items: center;\n            border-radius: 12px;\n            font-size: 2.5rem;\n            font-weight: 700;\n            color: #776e65;\n            z-index: 10;\n            text-align: center;\n            opacity: 0;\n            visibility: hidden;\n            transition: opacity 0.3s ease, visibility 0.3s ease;\n        }\n\n        .game-message.active {\n            opacity: 1;\n            visibility: visible;\n        }\n\n        .message-text {\n            margin-bottom: 20px;\n        }\n\n        \/* Generic modal for messages *\/\n        .modal-overlay {\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background-color: rgba(0, 0, 0, 0.5);\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            z-index: 100;\n            opacity: 0;\n            visibility: hidden;\n            transition: opacity 0.3s ease, visibility 0.3s ease;\n        }\n\n        .modal-overlay.active {\n            opacity: 1;\n            visibility: visible;\n        }\n\n        .modal-content {\n            background-color: #fff;\n            padding: 30px;\n            border-radius: 12px;\n            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);\n            text-align: center;\n            max-width: 400px;\n            width: 90%;\n            color: #776e65;\n            font-size: 1.2rem;\n            font-weight: 600;\n        }\n\n        .modal-content h3 {\n            font-size: 1.8rem;\n            margin-bottom: 15px;\n            color: #555;\n        }\n\n        .modal-content p {\n            margin-bottom: 20px;\n            line-height: 1.5;\n        }\n\n        .modal-close-button {\n            background-color: #8f7a66;\n            color: #f9f6f2;\n            padding: 10px 20px;\n            border-radius: 8px;\n            font-weight: 700;\n            cursor: pointer;\n            transition: background-color 0.3s ease;\n            border: none;\n        }\n\n        .modal-close-button:hover {\n            background-color: #6d5b4d;\n        }\n\n        \/* Animations *\/\n        @keyframes appear {\n            0% {\n                opacity: 0;\n                transform: scale(0);\n            }\n            100% {\n                opacity: 1;\n                transform: scale(1);\n            }\n        }\n\n        @keyframes pop {\n            0% { transform: scale(0.8); }\n            50% { transform: scale(1.1); }\n            100% { transform: scale(1); }\n        }\n\n        .tile.pop {\n            animation: pop 0.2s ease-out;\n        }\n    <\/style>\n<\/head>\n<body class=\"bg-gray-100 flex flex-col items-center justify-center min-h-screen\">\n    <div class=\"game-header\">\n        <h1 class=\"game-title\">2048<\/h1>\n        <div class=\"score-container\">\n            <span id=\"score-label\">Score<\/span>: <span id=\"score\">0<\/span>\n        <\/div>\n        <button id=\"restart-button\" class=\"action-button\" aria-label=\"Restart Game\"><\/button>\n    <\/div>\n\n    <div id=\"game-board\" class=\"game-container\">\n        <!-- Grid cells will be populated by JavaScript -->\n    <\/div>\n\n    <div class=\"flex flex-wrap justify-center mt-4\">\n        <button id=\"share-game-button\" class=\"action-button\" aria-label=\"Share Game\"><\/button>\n        <button id=\"share-result-button\" class=\"action-button\" aria-label=\"Share Result\"><\/button>\n        <button id=\"add-to-favorites-button\" class=\"action-button\" aria-label=\"Add to Favorites\"><\/button>\n    <\/div>\n\n    <div id=\"game-over-message\" class=\"game-message hidden\">\n        <div id=\"game-over-text\" class=\"message-text\"><\/div>\n        <button class=\"action-button\" onclick=\"initGame()\" id=\"game-over-restart-button\" aria-label=\"Restart Game\"><\/button>\n    <\/div>\n\n    <div id=\"game-win-message\" class=\"game-message hidden\">\n        <div id=\"game-win-text\" class=\"message-text\"><\/div>\n        <button class=\"action-button\" onclick=\"initGame()\" id=\"game-win-restart-button\" aria-label=\"Restart Game\"><\/button>\n    <\/div>\n\n    <!-- Generic Modal for messages (e.g., Add to Favorites instructions) -->\n    <div id=\"generic-modal-overlay\" class=\"modal-overlay\">\n        <div class=\"modal-content\">\n            <h3 id=\"modal-title\"><\/h3>\n            <p id=\"modal-message\"><\/p>\n            <button id=\"modal-close-button\" class=\"modal-close-button\" aria-label=\"Close\"><\/button>\n        <\/div>\n    <\/div>\n\n    <script defer>\n        \/\/ JavaScript Code\n        \/\/ Defines the size of the game board (4x4)\n        const boardSize = 4;\n        let board = []; \/\/ Represents the 2D array of the game board\n        let score = 0; \/\/ Current score\n        let gameWon = false; \/\/ Tracks if the game has been won\n        let gameOver = false; \/\/ Tracks if the game is over\n\n        \/\/ Get references to HTML elements\n        const gameBoardElement = document.getElementById('game-board');\n        const scoreElement = document.getElementById('score');\n        const restartButton = document.getElementById('restart-button');\n        const shareGameButton = document.getElementById('share-game-button');\n        const shareResultButton = document.getElementById('share-result-button');\n        const addToFavoritesButton = document.getElementById('add-to-favorites-button');\n\n        const gameOverMessage = document.getElementById('game-over-message');\n        const gameWinMessage = document.getElementById('game-win-message');\n        const genericModalOverlay = document.getElementById('generic-modal-overlay');\n        const modalTitleElement = document.getElementById('modal-title');\n        const modalMessageElement = document.getElementById('modal-message');\n        const modalCloseButton = document.getElementById('modal-close-button');\n\n        \/\/ Language translations for various UI elements\n        const translations = {\n            en: {\n                pageTitle: \"2048 Game\",\n                gameTitle: \"2048\",\n                scoreLabel: \"Score\",\n                restartButton: \"Restart Game\",\n                shareGameButton: \"Share Game\",\n                shareResultButton: \"Share Result\",\n                addToFavoritesButton: \"Add to Favorites\",\n                gameOverText: \"Game Over!\",\n                gameWinText: \"You Won!\",\n                modalTitleFavorites: \"Add to Favorites\",\n                modalMessageFavorites: \"To bookmark this page, press Ctrl+D (Windows\/Linux) or Cmd+D (Mac) in your browser.\",\n                modalClose: \"Close\",\n                shareGameTitle: \"Play 2048!\",\n                shareGameText: \"Come and play this fun 2048 game!\",\n                shareResultTitle: \"My 2048 Score!\",\n                shareResultText: (score) => `I scored ${score} in 2048! Can you beat my score?`,\n            },\n            tr: {\n                pageTitle: \"2048 Oyunu\",\n                gameTitle: \"2048\",\n                scoreLabel: \"Skor\",\n                restartButton: \"Yeniden Ba\u015flat\",\n                shareGameButton: \"Oyunu Payla\u015f\",\n                shareResultButton: \"Sonucu Payla\u015f\",\n                addToFavoritesButton: \"S\u0131k Kullan\u0131lanlara Ekle\",\n                gameOverText: \"Oyun Bitti!\",\n                gameWinText: \"Kazand\u0131n!\",\n                modalTitleFavorites: \"S\u0131k Kullan\u0131lanlara Ekle\",\n                modalMessageFavorites: \"Bu sayfay\u0131 s\u0131k kullan\u0131lanlara eklemek i\u00e7in taray\u0131c\u0131n\u0131zda Ctrl+D (Windows\/Linux) veya Cmd+D (Mac) tu\u015flar\u0131na bas\u0131n.\",\n                modalClose: \"Kapat\",\n                shareGameTitle: \"2048 Oyna!\",\n                shareGameText: \"Gel ve bu e\u011flenceli 2048 oyununu oyna!\",\n                shareResultTitle: \"2048 Skorum!\",\n                shareResultText: (score) => `2048'de ${score} puan ald\u0131m! Benim skorumu ge\u00e7ebilir misin?`,\n            }\n        };\n\n        let currentLang = 'en'; \/\/ Default language\n\n        \/**\n         * Sets the UI language based on the provided language code.\n         * @param {string} lang - The language code (e.g., 'en', 'tr').\n         *\/\n        function setLanguage(lang) {\n            currentLang = lang;\n            const t = translations[currentLang];\n\n            \/\/ Update text content and aria-labels for accessibility\n            document.getElementById('page-title').textContent = t.pageTitle;\n            document.querySelector('.game-title').textContent = t.gameTitle;\n            document.getElementById('score-label').textContent = t.scoreLabel;\n            restartButton.textContent = t.restartButton;\n            restartButton.setAttribute('aria-label', t.restartButton);\n            shareGameButton.textContent = t.shareGameButton;\n            shareGameButton.setAttribute('aria-label', t.shareGameButton);\n            shareResultButton.textContent = t.shareResultButton;\n            shareResultButton.setAttribute('aria-label', t.shareResultButton);\n            addToFavoritesButton.textContent = t.addToFavoritesButton;\n            addToFavoritesButton.setAttribute('aria-label', t.addToFavoritesButton);\n            document.getElementById('game-over-text').textContent = t.gameOverText;\n            document.getElementById('game-over-restart-button').textContent = t.restartButton;\n            document.getElementById('game-over-restart-button').setAttribute('aria-label', t.restartButton);\n            document.getElementById('game-win-text').textContent = t.gameWinText;\n            document.getElementById('game-win-restart-button').textContent = t.restartButton;\n            document.getElementById('game-win-restart-button').setAttribute('aria-label', t.restartButton);\n            modalCloseButton.textContent = t.modalClose;\n            modalCloseButton.setAttribute('aria-label', t.modalClose);\n        }\n\n        \/**\n         * Detects the user's browser language and sets the UI language accordingly.\n         * Falls back to English if the browser language is not supported.\n         *\/\n        function detectAndSetLanguage() {\n            const browserLang = navigator.language.split('-')[0]; \/\/ e.g., \"en-US\" -> \"en\"\n            if (translations[browserLang]) {\n                setLanguage(browserLang);\n            } else {\n                setLanguage('en'); \/\/ Fallback to English\n            }\n        }\n\n        \/**\n         * Initializes the game state, resets score, and draws the initial board.\n         *\/\n        function initGame() {\n            board = Array(boardSize).fill(0).map(() => Array(boardSize).fill(0)); \/\/ Initialize board with zeros\n            score = 0; \/\/ Reset score\n            gameWon = false; \/\/ Reset game won status\n            gameOver = false; \/\/ Reset game over status\n            updateScore(); \/\/ Update score display\n            hideMessages(); \/\/ Hide any active game messages\n            addRandomTile(); \/\/ Add two initial random tiles\n            addRandomTile();\n            drawBoard(); \/\/ Draw the board to the HTML\n        }\n\n        \/**\n         * Draws the current state of the game board to the HTML.\n         *\/\n        function drawBoard() {\n            gameBoardElement.innerHTML = ''; \/\/ Clear existing tiles\n\n            \/\/ Create empty grid cells as background for visual structure\n            for (let r = 0; r < boardSize; r++) {\n                for (let c = 0; c < boardSize; c++) {\n                    const gridCell = document.createElement('div');\n                    gridCell.classList.add('grid-cell');\n                    gameBoardElement.appendChild(gridCell);\n                }\n            }\n\n            \/\/ Create and position actual tiles based on board array\n            for (let r = 0; r < boardSize; r++) {\n                for (let c = 0; c < boardSize; c++) {\n                    const tileValue = board[r][c];\n                    if (tileValue !== 0) {\n                        const tileElement = document.createElement('div');\n                        \/\/ Add 'tile' class and specific class for value-based styling\n                        tileElement.classList.add('tile', `tile-${tileValue}`);\n                        tileElement.textContent = tileValue; \/\/ Display tile value\n                        \n                        \/\/ Calculate tile position dynamically for responsiveness\n                        const containerWidth = gameBoardElement.offsetWidth;\n                        const gap = 12; \/\/ Gap defined in CSS\n                        const tileWidth = (containerWidth - (boardSize + 1) * gap) \/ boardSize;\n\n                        const left = c * (tileWidth + gap) + gap;\n                        const top = r * (tileWidth + gap) + gap;\n\n                        tileElement.style.left = `${left}px`;\n                        tileElement.style.top = `${top}px`;\n\n                        gameBoardElement.appendChild(tileElement);\n                    }\n                }\n            }\n        }\n\n        \/**\n         * Adds a new tile (either 2 or 4) to a random empty cell on the board.\n         * @returns {void}\n         *\/\n        function addRandomTile() {\n            if (isBoardFull()) {\n                return; \/\/ Do nothing if the board is full\n            }\n\n            let emptyCells = [];\n            \/\/ Find all empty cells\n            for (let r = 0; r < boardSize; r++) {\n                for (let c = 0; c < boardSize; c++) {\n                    if (board[r][c] === 0) {\n                        emptyCells.push({ r, c });\n                    }\n                }\n            }\n\n            if (emptyCells.length > 0) {\n                \/\/ Select a random empty cell\n                const randomIndex = Math.floor(Math.random() * emptyCells.length);\n                const { r, c } = emptyCells[randomIndex];\n                \/\/ Place a new tile (90% chance of 2, 10% chance of 4)\n                board[r][c] = Math.random() < 0.9 ? 2 : 4;\n            }\n        }\n\n        \/**\n         * Checks if the game board is completely full.\n         * @returns {boolean} - True if the board is full, false otherwise.\n         *\/\n        function isBoardFull() {\n            for (let r = 0; r < boardSize; r++) {\n                for (let c = 0; c < boardSize; c++) {\n                    if (board[r][c] === 0) {\n                        return false;\n                    }\n                }\n            }\n            return true;\n        }\n\n        \/**\n         * Updates the displayed score on the HTML page.\n         *\/\n        function updateScore() {\n            scoreElement.textContent = score;\n        }\n\n        \/**\n         * Hides all game over, game win, and generic modal messages.\n         *\/\n        function hideMessages() {\n            gameOverMessage.classList.add('hidden');\n            gameOverMessage.classList.remove('active');\n            gameWinMessage.classList.add('hidden');\n            gameWinMessage.classList.remove('active');\n            hideModal(); \/\/ Also hide generic modal\n        }\n\n        \/**\n         * Displays the \"Game Over\" message.\n         *\/\n        function showGameOver() {\n            gameOverMessage.classList.remove('hidden');\n            gameOverMessage.classList.add('active');\n        }\n\n        \/**\n         * Displays the \"You Won\" message.\n         *\/\n        function showGameWin() {\n            gameWinMessage.classList.remove('hidden');\n            gameWinMessage.classList.add('active');\n        }\n\n        \/**\n         * Displays a generic modal with a given title and message.\n         * @param {string} title - The title of the modal.\n         * @param {string} message - The message content of the modal.\n         *\/\n        function showModal(title, message) {\n            modalTitleElement.textContent = title;\n            modalMessageElement.textContent = message;\n            genericModalOverlay.classList.add('active');\n            genericModalOverlay.classList.remove('hidden'); \/\/ Ensure it's not hidden by display: none\n        }\n\n        \/**\n         * Hides the generic modal.\n         *\/\n        function hideModal() {\n            genericModalOverlay.classList.remove('active');\n            genericModalOverlay.classList.add('hidden');\n        }\n\n        \/**\n         * Slides and merges tiles in the specified direction.\n         * @param {string} direction - The direction to slide ('left', 'right', 'up', 'down').\n         * @returns {boolean} - True if any tiles moved or merged, false otherwise.\n         *\/\n        function slideAndMerge(direction) {\n            let moved = false;\n            \/\/ Keep track of merged tiles to prevent multiple merges in one move\n            let merged = Array(boardSize).fill(0).map(() => Array(boardSize).fill(false));\n\n            if (direction === 'left') {\n                for (let r = 0; r < boardSize; r++) {\n                    let newRow = board[r].filter(val => val !== 0); \/\/ Remove zeros\n                    while (newRow.length < boardSize) newRow.push(0); \/\/ Add zeros to the end\n\n                    for (let c = 0; c < boardSize - 1; c++) {\n                        \/\/ Merge if adjacent tiles are same and not already merged\n                        if (newRow[c] !== 0 &#038;&#038; newRow[c] === newRow[c + 1] &#038;&#038; !merged[r][c] &#038;&#038; !merged[r][c+1]) {\n                            newRow[c] *= 2; \/\/ Double the tile value\n                            score += newRow[c]; \/\/ Add to score\n                            newRow[c + 1] = 0; \/\/ Clear the merged tile\n                            merged[r][c] = true; \/\/ Mark as merged\n                            moved = true;\n                            if (newRow[c] === 2048) gameWon = true; \/\/ Check for win condition\n                        }\n                    }\n\n                    newRow = newRow.filter(val => val !== 0); \/\/ Remove new zeros after merge\n                    while (newRow.length < boardSize) newRow.push(0); \/\/ Add zeros to the end again\n\n                    \/\/ Check if the row actually changed\n                    if (JSON.stringify(board[r]) !== JSON.stringify(newRow)) {\n                        moved = true;\n                    }\n                    board[r] = newRow; \/\/ Update the board row\n                }\n            } else if (direction === 'right') {\n                for (let r = 0; r < boardSize; r++) {\n                    let newRow = board[r].filter(val => val !== 0);\n                    while (newRow.length < boardSize) newRow.unshift(0); \/\/ Add zeros to the beginning\n\n                    for (let c = boardSize - 1; c > 0; c--) {\n                        if (newRow[c] !== 0 && newRow[c] === newRow[c - 1] && !merged[r][c] && !merged[r][c-1]) {\n                            newRow[c] *= 2;\n                            score += newRow[c];\n                            newRow[c - 1] = 0;\n                            merged[r][c] = true;\n                            moved = true;\n                            if (newRow[c] === 2048) gameWon = true;\n                        }\n                    }\n\n                    newRow = newRow.filter(val => val !== 0);\n                    while (newRow.length < boardSize) newRow.unshift(0);\n\n                    if (JSON.stringify(board[r]) !== JSON.stringify(newRow)) {\n                        moved = true;\n                    }\n                    board[r] = newRow;\n                }\n            } else if (direction === 'up') {\n                for (let c = 0; c < boardSize; c++) {\n                    let col = [];\n                    for (let r = 0; r < boardSize; r++) col.push(board[r][c]); \/\/ Extract column\n\n                    let newCol = col.filter(val => val !== 0);\n                    while (newCol.length < boardSize) newCol.push(0);\n\n                    for (let r = 0; r < boardSize - 1; r++) {\n                        if (newCol[r] !== 0 &#038;&#038; newCol[r] === newCol[r + 1] &#038;&#038; !merged[r][c] &#038;&#038; !merged[r+1][c]) {\n                            newCol[r] *= 2;\n                            score += newCol[r];\n                            newCol[r + 1] = 0;\n                            merged[r][c] = true;\n                            moved = true;\n                            if (newCol[r] === 2048) gameWon = true;\n                        }\n                    }\n\n                    newCol = newCol.filter(val => val !== 0);\n                    while (newCol.length < boardSize) newCol.push(0);\n\n                    \/\/ Update the board column\n                    for (let r = 0; r < boardSize; r++) {\n                        if (board[r][c] !== newCol[r]) moved = true;\n                        board[r][c] = newCol[r];\n                    }\n                }\n            } else if (direction === 'down') {\n                for (let c = 0; c < boardSize; c++) {\n                    let col = [];\n                    for (let r = 0; r < boardSize; r++) col.push(board[r][c]);\n\n                    let newCol = col.filter(val => val !== 0);\n                    while (newCol.length < boardSize) newCol.unshift(0);\n\n                    for (let r = boardSize - 1; r > 0; r--) {\n                        if (newCol[r] !== 0 && newCol[r] === newCol[r - 1] && !merged[r][c] && !merged[r-1][c]) {\n                            newCol[r] *= 2;\n                            score += newCol[r];\n                            newCol[r - 1] = 0;\n                            merged[r][c] = true;\n                            moved = true;\n                            if (newCol[r] === 2048) gameWon = true;\n                        }\n                    }\n\n                    newCol = newCol.filter(val => val !== 0);\n                    while (newCol.length < boardSize) newCol.unshift(0);\n\n                    for (let r = 0; r < boardSize; r++) {\n                        if (board[r][c] !== newCol[r]) moved = true;\n                        board[r][c] = newCol[r];\n                    }\n                }\n            }\n\n            return moved;\n        }\n\n        \/**\n         * Checks if the game is over (either won or no more moves possible).\n         * @returns {boolean} - True if the game is over, false otherwise.\n         *\/\n        function checkGameOver() {\n            if (gameWon) {\n                showGameWin();\n                return true;\n            }\n\n            if (!isBoardFull()) {\n                return false; \/\/ Game is not over if there are empty cells\n            }\n\n            \/\/ Check if any moves are possible (adjacent tiles with same value)\n            for (let r = 0; r < boardSize; r++) {\n                for (let c = 0; c < boardSize; c++) {\n                    const val = board[r][c];\n                    \/\/ Check right or down neighbors for same value\n                    if (c < boardSize - 1 &#038;&#038; val === board[r][c + 1]) return false;\n                    if (r < boardSize - 1 &#038;&#038; val === board[r + 1][c]) return false;\n                }\n            }\n            return true; \/\/ No moves possible, game is over\n        }\n\n        \/\/ Event listener for keyboard input (Arrow keys for movement)\n        document.addEventListener('keydown', (e) => {\n            if (gameWon || gameOver) return; \/\/ Ignore input if game is won or over\n\n            let moved = false;\n            switch (e.key) {\n                case 'ArrowLeft':\n                    moved = slideAndMerge('left');\n                    break;\n                case 'ArrowRight':\n                    moved = slideAndMerge('right');\n                    break;\n                case 'ArrowUp':\n                    moved = slideAndMerge('up');\n                    break;\n                case 'ArrowDown':\n                    moved = slideAndMerge('down');\n                    break;\n            }\n\n            if (moved) {\n                addRandomTile(); \/\/ Add a new tile if a move occurred\n                updateScore(); \/\/ Update the score\n                drawBoard(); \/\/ Redraw the board\n                if (checkGameOver()) {\n                    gameOver = true;\n                    showGameOver();\n                }\n            }\n        });\n\n        \/\/ Event listener for restart button click\n        restartButton.addEventListener('click', initGame);\n\n        \/\/ Touch event listeners for mobile compatibility (swipe gestures)\n        let touchStartX = 0;\n        let touchStartY = 0;\n        let touchEndX = 0;\n        let touchEndY = 0;\n\n        \/\/ Record touch start coordinates\n        gameBoardElement.addEventListener('touchstart', (e) => {\n            touchStartX = e.touches[0].clientX;\n            touchStartY = e.touches[0].clientY;\n            e.preventDefault(); \/\/ Prevent default scrolling behavior\n        });\n\n        \/\/ Prevent scrolling during touch move to ensure swipe detection\n        gameBoardElement.addEventListener('touchmove', (e) => {\n            e.preventDefault();\n        });\n\n        \/\/ Determine swipe direction and trigger game logic on touch end\n        gameBoardElement.addEventListener('touchend', (e) => {\n            if (gameWon || gameOver) return; \/\/ Ignore input if game is won or over\n\n            touchEndX = e.changedTouches[0].clientX;\n            touchEndY = e.changedTouches[0].clientY;\n\n            const dx = touchEndX - touchStartX;\n            const dy = touchEndY - touchStartY;\n\n            const sensitivity = 50; \/\/ Minimum distance for a swipe to be registered\n\n            let moved = false;\n\n            \/\/ Determine if horizontal or vertical swipe and trigger corresponding move\n            if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > sensitivity) {\n                if (dx > 0) {\n                    moved = slideAndMerge('right');\n                } else {\n                    moved = slideAndMerge('left');\n                }\n            } else if (Math.abs(dy) > Math.abs(dx) && Math.abs(dy) > sensitivity) {\n                if (dy > 0) {\n                    moved = slideAndMerge('down');\n                } else {\n                    moved = slideAndMerge('up');\n                }\n            }\n\n            if (moved) {\n                addRandomTile();\n                updateScore();\n                drawBoard();\n                if (checkGameOver()) {\n                    gameOver = true;\n                    showGameOver();\n                }\n            }\n        });\n\n        \/**\n         * Shares the game URL using the Web Share API or a fallback modal.\n         *\/\n        function shareGame() {\n            const t = translations[currentLang];\n            if (navigator.share) {\n                navigator.share({\n                    title: t.shareGameTitle,\n                    text: t.shareGameText,\n                    url: window.location.href\n                }).then(() => {\n                    console.log('Game shared successfully!');\n                }).catch((error) => {\n                    console.error('Error sharing game:', error);\n                    showModal(\"Share Error\", \"Could not share the game. Please try again or copy the URL manually.\");\n                });\n            } else {\n                \/\/ Fallback for browsers that don't support Web Share API\n                showModal(\"Share Game\", \"Your browser does not support sharing directly. Please copy the URL to share: \" + window.location.href);\n            }\n        }\n\n        \/**\n         * Shares the current game result using the Web Share API or a fallback modal.\n         *\/\n        function shareResult() {\n            const t = translations[currentLang];\n            const resultText = t.shareResultText(score);\n            if (navigator.share) {\n                navigator.share({\n                    title: t.shareResultTitle,\n                    text: resultText,\n                    url: window.location.href\n                }).then(() => {\n                    console.log('Result shared successfully!');\n                }).catch((error) => {\n                    console.error('Error sharing result:', error);\n                    showModal(\"Share Error\", \"Could not share the result. Please try again or copy the URL manually.\");\n                });\n            } else {\n                \/\/ Fallback for browsers that don't support Web Share API\n                showModal(\"Share Result\", `Your browser does not support sharing directly. Your score is ${score}. Please copy the URL to share: ` + window.location.href);\n            }\n        }\n\n        \/**\n         * Displays instructions on how to add the page to favorites\/bookmarks.\n         *\/\n        function addToFavorites() {\n            const t = translations[currentLang];\n            showModal(t.modalTitleFavorites, t.modalMessageFavorites);\n        }\n\n        \/\/ Attach event listeners for new buttons\n        shareGameButton.addEventListener('click', shareGame);\n        shareResultButton.addEventListener('click', shareResult);\n        addToFavoritesButton.addEventListener('click', addToFavorites);\n        modalCloseButton.addEventListener('click', hideModal); \/\/ Close generic modal\n\n        \/\/ Initialize game and set language on window load\n        window.onload = () => {\n            detectAndSetLanguage();\n            initGame();\n        };\n    <\/script>\n","protected":false},"excerpt":{"rendered":"<p>2048 Score: 0<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-306","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts\/306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/comments?post=306"}],"version-history":[{"count":1,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts\/306\/revisions"}],"predecessor-version":[{"id":307,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/posts\/306\/revisions\/307"}],"wp:attachment":[{"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/media?parent=306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/categories?post=306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/insaatsirketleri.com.tr\/en\/wp-json\/wp\/v2\/tags?post=306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}