feat: shape parsing

This commit is contained in:
hyper 2026-04-12 20:26:46 +08:00
parent d5f65fa6cd
commit 6dc85b443e
2 changed files with 109 additions and 2 deletions

View File

@ -25,9 +25,9 @@ Zone based Point Crawl:
3种牌攻击/防御/强化攻击克强化克防御克攻击强化比sts强化窄但效果更大
受伤时伤口先占格子再扣血,牌少的角色受掉血影响大但血更厚
洗牌堆时洗入两张《疲劳》1费/消耗)
背包物品指定相邻物品,对其所有卡牌生效
背包物品可能会引用相邻的物品、同一行的物品、同一列的物品等
部分物品带使用次数限制,药瓶喝完可以在篝火补

View File

@ -0,0 +1,107 @@
/**
* Parsed shape result containing the grid and sizing information.
*/
export interface ParsedShape {
/** 2D boolean grid representing filled cells */
grid: boolean[][];
/** Grid width (number of columns) */
width: number;
/** Grid height (number of rows) */
height: number;
/** Origin X coordinate within the grid */
originX: number;
/** Origin Y coordinate within the grid */
originY: number;
}
/**
* Parses a movement string into a 2D boolean grid.
* Rules:
* o: Fill current cell and set origin
* n, s, e, w: Move one step and fill the cell
* r: Return to the previous cell
*/
export function parseShapeString(input: string): ParsedShape {
let curX = 0;
let curY = 0;
let originX = 0;
let originY = 0;
let originSet = false;
// Track unique filled coordinates
const filledPoints = new Set<string>();
// Stack to track movement history for the 'r' command
const history: { x: number; y: number }[] = [];
const fill = (x: number, y: number) => {
filledPoints.add(`${x},${y}`);
history.push({ x, y });
};
for (const char of input.toLowerCase()) {
switch (char) {
case 'o':
if (!originSet) {
originX = curX;
originY = curY;
originSet = true;
}
fill(curX, curY);
break;
case 'n':
curY -= 1;
fill(curX, curY);
break;
case 's':
curY += 1;
fill(curX, curY);
break;
case 'e':
curX += 1;
fill(curX, curY);
break;
case 'w':
curX -= 1;
fill(curX, curY);
break;
case 'r':
if (history.length > 1) {
history.pop(); // Remove current position
const prev = history[history.length - 1];
curX = prev.x;
curY = prev.y;
}
break;
}
}
if (filledPoints.size === 0) {
return { grid: [[]], width: 0, height: 1, originX: 0, originY: 0 };
}
// Calculate bounding box to normalize the array
const coords = Array.from(filledPoints).map(p => p.split(',').map(Number));
const minX = Math.min(...coords.map(c => c[0]));
const maxX = Math.max(...coords.map(c => c[0]));
const minY = Math.min(...coords.map(c => c[1]));
const maxY = Math.max(...coords.map(c => c[1]));
const width = maxX - minX + 1;
const height = maxY - minY + 1;
// Initialize the grid
const grid: boolean[][] = Array.from({ length: height }, () =>
Array(width).fill(false)
);
// Map the points into the grid using offsets
for (const [x, y] of coords) {
grid[y - minY][x - minX] = true;
}
// Normalize origin coordinates relative to the grid
const normalizedOriginX = originX - minX;
const normalizedOriginY = originY - minY;
return { grid, width, height, originX: normalizedOriginX, originY: normalizedOriginY };
}