feat: shape parsing
This commit is contained in:
parent
d5f65fa6cd
commit
6dc85b443e
|
|
@ -25,9 +25,9 @@ Zone based Point Crawl:
|
|||
|
||||
3种牌(攻击/防御/强化)攻击克强化克防御克攻击,强化比sts强化窄但效果更大
|
||||
|
||||
受伤时伤口先占格子再扣血,牌少的角色受掉血影响大但血更厚
|
||||
洗牌堆时洗入两张《疲劳》(1费/消耗)
|
||||
|
||||
背包物品指定相邻物品,对其所有卡牌生效
|
||||
背包物品可能会引用相邻的物品、同一行的物品、同一列的物品等
|
||||
|
||||
部分物品带使用次数限制,药瓶喝完可以在篝火补
|
||||
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
}
|
||||
Loading…
Reference in New Issue