UNPKG

2048-cli-game

Version:

2048 game for terminal.

189 lines (188 loc) 7.47 kB
import { GRID_SIZE, MAX_VALUE } from './constants.js'; export const sumArray = (arr) => arr.reduce((a, b) => a + b, 0); // 收集所有空白位置 export const getEmptyCells = (nums) => { const emptyCells = []; for (let row = 0; row < nums.length; row++) { for (let col = 0; col < nums[row].length; col++) { if (nums[row][col] === 0) { emptyCells.push({ row, col }); } } } return emptyCells; }; export const getRandomCells = (emptyCells) => { if (emptyCells.length) { return emptyCells[Math.floor(Math.random() * emptyCells.length)]; } else { return; } }; // 移动并合并方块 export const moveTiles = (board, direction) => { const newBoard = JSON.parse(JSON.stringify(board)); let moved = false; let score = 0; // 根据方向处理移动 switch (direction) { case 'up': for (let col = 0; col < GRID_SIZE; col++) { for (let row = 1; row < GRID_SIZE; row++) { if (newBoard[row][col] !== 0) { let currentRow = row; while (currentRow > 0 && newBoard[currentRow - 1][col] === 0) { // 向上移动 newBoard[currentRow - 1][col] = newBoard[currentRow][col]; newBoard[currentRow][col] = 0; currentRow--; moved = true; } // 检查合并 if (currentRow > 0 && newBoard[currentRow - 1][col] === newBoard[currentRow][col]) { // 合并方块 newBoard[currentRow - 1][col] *= 2; score += newBoard[currentRow - 1][col]; newBoard[currentRow][col] = 0; moved = true; } } } } break; case 'down': for (let col = 0; col < GRID_SIZE; col++) { for (let row = GRID_SIZE - 2; row >= 0; row--) { if (newBoard[row][col] !== 0) { let currentRow = row; while (currentRow < GRID_SIZE - 1 && newBoard[currentRow + 1][col] === 0) { // 向下移动 newBoard[currentRow + 1][col] = newBoard[currentRow][col]; newBoard[currentRow][col] = 0; currentRow++; moved = true; } // 检查合并 if (currentRow < GRID_SIZE - 1 && newBoard[currentRow + 1][col] === newBoard[currentRow][col]) { // 合并方块 newBoard[currentRow + 1][col] *= 2; score += newBoard[currentRow + 1][col]; newBoard[currentRow][col] = 0; moved = true; } } } } break; case 'left': for (let row = 0; row < GRID_SIZE; row++) { for (let col = 1; col < GRID_SIZE; col++) { if (newBoard[row][col] !== 0) { let currentCol = col; while (currentCol > 0 && newBoard[row][currentCol - 1] === 0) { // 向左移动 newBoard[row][currentCol - 1] = newBoard[row][currentCol]; newBoard[row][currentCol] = 0; currentCol--; moved = true; } // 检查合并 if (currentCol > 0 && newBoard[row][currentCol - 1] === newBoard[row][currentCol]) { // 合并方块 newBoard[row][currentCol - 1] *= 2; score += newBoard[row][currentCol - 1]; newBoard[row][currentCol] = 0; moved = true; } } } } break; case 'right': for (let row = 0; row < GRID_SIZE; row++) { for (let col = GRID_SIZE - 2; col >= 0; col--) { if (newBoard[row][col] !== 0) { let currentCol = col; while (currentCol < GRID_SIZE - 1 && newBoard[row][currentCol + 1] === 0) { // 向右移动 newBoard[row][currentCol + 1] = newBoard[row][currentCol]; newBoard[row][currentCol] = 0; currentCol++; moved = true; } // 检查合并 if (currentCol < GRID_SIZE - 1 && newBoard[row][currentCol + 1] === newBoard[row][currentCol]) { // 合并方块 newBoard[row][currentCol + 1] *= 2; score += newBoard[row][currentCol + 1]; newBoard[row][currentCol] = 0; moved = true; } } } } break; } return { board: newBoard, moved, score }; }; export function countDigits(num) { // 处理负号和小数点 const numStr = String(num).replace(/[-.]/g, ''); return numStr.length; } export const randomGenerateNum = (board) => { const emptyCells = getEmptyCells(board); const cells = getRandomCells(emptyCells); if (cells) { // 90% 概率生成2,10%概率生成4 board[cells.row][cells.col] = Math.random() < 0.9 ? 2 : 4; } return JSON.parse(JSON.stringify(board)); }; export const isGameOver = (nums) => { // 检查是否有空白位置 for (let row = 0; row < GRID_SIZE; row++) { for (let col = 0; col < GRID_SIZE; col++) { if (nums[row][col] === 0) return false; } } // 检查是否有相邻的相同方块 for (let row = 0; row < GRID_SIZE; row++) { for (let col = 0; col < GRID_SIZE; col++) { const value = nums[row][col]; // 检查右侧方块 if (col < GRID_SIZE - 1 && nums[row][col + 1] === value) return false; // 检查下方方块 if (row < GRID_SIZE - 1 && nums[row + 1][col] === value) return false; } } return true; }; export const hasMaxValue = (board) => { for (let row = 0; row < GRID_SIZE; row++) { for (let col = 0; col < GRID_SIZE; col++) { if (board[row][col] === MAX_VALUE) { board[row][col] = 0; return true; } } } return false; }; // 生成初始游戏板 export const initializeBoard = () => { const board = Array(GRID_SIZE) .fill(0) .map(() => Array(GRID_SIZE).fill(0)); return board; };