64 lines
2.1 KiB
TypeScript
64 lines
2.1 KiB
TypeScript
|
|
import {BOARD_SIZE, BoopGame, BoopPart, BoopState, PieceType, 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): BoopPart | null {
|
|||
|
|
const state = getState(ctx);
|
|||
|
|
if(!regionId){
|
|||
|
|
return Object.values(state.pieces).find(part => part.type === type && !part.regionId) || null;
|
|||
|
|
}
|
|||
|
|
const id = state.regions[regionId].childIds.find(id => state.pieces[id].type === type);
|
|||
|
|
return id ? state.pieces[id] || null : null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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;
|
|||
|
|
}
|