import { BOARD_SIZE, BoopGame, BoopPart, BoopState, PieceType, PlayerType, RegionType, WIN_LENGTH } from "@/samples/boop/data"; const DIRS = [ [0, 1], [1, 0], [1, 1], [-1, 1] ] type PT = [number, number]; type Line = PT[]; export function* getLineCandidates(){ for(const [dx, dy] of DIRS){ for(let x = 0; x < BOARD_SIZE; x ++) for(let y = 0; y < BOARD_SIZE; y ++){ if(!isInBounds(x + dx * (WIN_LENGTH-1), y + dy * (WIN_LENGTH-1))) continue; const line = []; for(let i = 0; i < WIN_LENGTH; i ++){ line.push([x + i * dx, y + i * dy]); } yield line as Line; } } } /** * 检查位置是否在棋盘范围内 */ export function isInBounds(x: number, y: number): boolean { return x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE; } export function isCellOccupied(game: BoopGame | BoopState, x: number, y: number): boolean { const id = `${x},${y}`; return getState(game).regions.board.partMap[id] !== undefined; } export function* getNeighborPositions(x: number = 0, y: number = 0){ for(let dx = -1; dx <= 1; dx ++) for(let dy = -1; dy <= 1; dy ++) if(dx !== 0 || dy !== 0) yield [x + dx, y + dy] as PT; } export function findPartInRegion(ctx: BoopGame | BoopState, regionId: keyof BoopGame['value']['regions'], type: PieceType, player?: PlayerType): BoopPart | null { const state = getState(ctx); if(!regionId){ return Object.values(state.pieces).find(part => match(regionId, part, type, player)) || null; } const id = state.regions[regionId].childIds.find(id => match(regionId, state.pieces[id], type, player)); return id ? state.pieces[id] || null : null; } function match(regionId: RegionType, part: BoopPart, type: PieceType, player?: PlayerType){ return regionId === part.regionId && part.type === type && (!player || part.player === player); } export function findPartAtPosition(ctx: BoopGame | BoopState, row: number, col: number): BoopPart | null { const state = getState(ctx); const id = state.regions.board.partMap[`${row},${col}`]; return id ? state.pieces[id] || null : null; } function getState(ctx: BoopGame | BoopState): BoopState { if('value' in ctx){ return ctx.value; } return ctx; }