flip-grid/utils/gameLogic.ts

70 lines
1.9 KiB
TypeScript

import { GridState, CellCoords } from '../types';
// Create a board with all false (uniform state)
export const createEmptyBoard = (size: number): GridState => {
return Array(size).fill(null).map(() => Array(size).fill(false));
};
// Toggle a single cell and its neighbors
export const toggleCell = (board: GridState, r: number, c: number): GridState => {
const size = board.length;
const newBoard = board.map(row => [...row]); // Deep copy for immutability
// Directions: Center, Up, Down, Left, Right
const dirs = [
{ dr: 0, dc: 0 },
{ dr: -1, dc: 0 },
{ dr: 1, dc: 0 },
{ dr: 0, dc: -1 },
{ dr: 0, dc: 1 }
];
for (const { dr, dc } of dirs) {
const nr = r + dr;
const nc = c + dc;
if (nr >= 0 && nr < size && nc >= 0 && nc < size) {
newBoard[nr][nc] = !newBoard[nr][nc];
}
}
return newBoard;
};
// Generate a puzzle by starting solved and applying random moves.
// This guarantees the puzzle is solvable.
export const generatePuzzle = (size: number, moves: number): GridState => {
let board = createEmptyBoard(size);
let previousCoords: CellCoords | null = null;
for (let i = 0; i < moves; i++) {
let r, c;
// Simple heuristic to avoid immediately undoing the last move
do {
r = Math.floor(Math.random() * size);
c = Math.floor(Math.random() * size);
} while (previousCoords && r === previousCoords.r && c === previousCoords.c);
board = toggleCell(board, r, c);
previousCoords = { r, c };
}
return board;
};
// Check if all cells are the same value (all true or all false)
export const checkWin = (board: GridState): boolean => {
if (board.length === 0) return true;
const size = board.length;
const firstValue = board[0][0];
for (let r = 0; r < size; r++) {
for (let c = 0; c < size; c++) {
if (board[r][c] !== firstValue) {
return false;
}
}
}
return true;
};