var board; var score = 0; var rows = 4; var columns = 4; var gameOver = false; window.onload = function () { setGame(); document.getElementById("replayBtn").addEventListener("click", restartGame); }; function setGame() { board = [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], ]; score = 0; gameOver = false; document.getElementById("score").innerText = score; document.getElementById("board").innerHTML = ""; for (let r = 0; r < rows; r++) { for (let c = 0; c < columns; c++) { let tile = document.createElement("div"); tile.id = r.toString() + "-" + c.toString(); let num = board[r][c]; updateTile(tile, num); document.getElementById("board").append(tile); } } setTwo(); setTwo(); } function restartGame() { document.getElementById("gameOverOverlay").style.display = "none"; setGame(); } function updateTile(tile, num) { tile.innerText = ""; tile.classList.value = ""; tile.classList.add("tile"); if (num > 0) { tile.innerText = num.toString(); if (num <= 4096) { tile.classList.add("x" + num.toString()); } else { tile.classList.add("x8192"); } } } document.addEventListener("keyup", (e) => { if (gameOver) return; let moved = false; if (e.code == "ArrowLeft") { moved = slideLeft(); } else if (e.code == "ArrowRight") { moved = slideRight(); } else if (e.code == "ArrowUp") { moved = slideUp(); } else if (e.code == "ArrowDown") { moved = slideDown(); } // Only add new tile if board actually moved if (moved) { setTwo(); document.getElementById("score").innerText = score; } }); function filterZero(row) { return row.filter((num) => num != 0); } function slide(row) { row = filterZero(row); for (let i = 0; i < row.length - 1; i++) { if (row[i] == row[i + 1]) { row[i] *= 2; row[i + 1] = 0; score += row[i]; } } row = filterZero(row); while (row.length < columns) { row.push(0); } return row; } function slideLeft() { let moved = false; for (let r = 0; r < rows; r++) { let row = board[r]; let original = [...row]; row = slide(row); board[r] = row; // Check if board changed if (JSON.stringify(original) !== JSON.stringify(row)) { moved = true; } for (let c = 0; c < columns; c++) { let tile = document.getElementById(r.toString() + "-" + c.toString()); let num = board[r][c]; updateTile(tile, num); } } return moved; } function slideRight() { let moved = false; for (let r = 0; r < rows; r++) { let row = board[r]; let original = [...row]; row.reverse(); row = slide(row); board[r] = row.reverse(); // Check if board changed if (JSON.stringify(original) !== JSON.stringify(board[r])) { moved = true; } for (let c = 0; c < columns; c++) { let tile = document.getElementById(r.toString() + "-" + c.toString()); let num = board[r][c]; updateTile(tile, num); } } return moved; } function slideUp() { let moved = false; for (let c = 0; c < columns; c++) { let row = [board[0][c], board[1][c], board[2][c], board[3][c]]; let original = [...row]; row = slide(row); // Check if board changed if (JSON.stringify(original) !== JSON.stringify(row)) { moved = true; } for (let r = 0; r < rows; r++) { board[r][c] = row[r]; let tile = document.getElementById(r.toString() + "-" + c.toString()); let num = board[r][c]; updateTile(tile, num); } } return moved; } function slideDown() { let moved = false; for (let c = 0; c < columns; c++) { let row = [board[0][c], board[1][c], board[2][c], board[3][c]]; let original = [...row]; row.reverse(); row = slide(row); row.reverse(); // Check if board changed if (JSON.stringify(original) !== JSON.stringify(row)) { moved = true; } for (let r = 0; r < rows; r++) { board[r][c] = row[r]; let tile = document.getElementById(r.toString() + "-" + c.toString()); let num = board[r][c]; updateTile(tile, num); } } return moved; } function setTwo() { if (!hasEmptyTile()) { checkGameOver(); return; } let found = false; while (!found) { let r = Math.floor(Math.random() * rows); let c = Math.floor(Math.random() * columns); if (board[r][c] == 0) { board[r][c] = 2; let tile = document.getElementById(r.toString() + "-" + c.toString()); tile.innerText = "2"; tile.classList.add("x2"); found = true; } } } function hasEmptyTile() { for (let r = 0; r < rows; r++) { for (let c = 0; c < columns; c++) { if (board[r][c] == 0) { return true; } } } return false; } function checkGameOver() { // Check if any moves are possible for (let r = 0; r < rows; r++) { for (let c = 0; c < columns; c++) { // Check right if (c < columns - 1 && board[r][c] == board[r][c + 1]) { return; } // Check down if (r < rows - 1 && board[r][c] == board[r + 1][c]) { return; } } } // No moves available - game over gameOver = true; showGameOver(); } function showGameOver() { document.getElementById("finalScore").innerText = score; document.getElementById("gameOverOverlay").style.display = "flex"; }