feat(slay-the-spire-like): add map navigation logic

Implement `canMoveTo` and `moveToNode` for navigating the point
crawl map, and add `PointCrawlMapNavigator` type. Also reformat
map module files to use double quotes.
This commit is contained in:
hypercross 2026-04-20 11:59:52 +08:00
parent 88d31430a6
commit 423cc7c841
3 changed files with 102 additions and 51 deletions

View File

@ -1,5 +1,18 @@
export { MapNodeType, MapLayerType } from './types'; export { MapNodeType, MapLayerType } from "./types";
export type { MapNode, MapLayer, PointCrawlMap, MapGenerationConfig } from './types'; export type {
MapNode,
MapLayer,
PointCrawlMap,
MapGenerationConfig,
} from "./types";
export { generatePointCrawlMap } from './generator'; export { generatePointCrawlMap } from "./generator";
export { getNode, getChildren, getParents, hasPath, findAllPaths } from './generator'; export {
getNode,
getChildren,
getParents,
hasPath,
findAllPaths,
} from "./generator";
export { canMoveTo, moveToNode } from "./navigation";

View File

@ -0,0 +1,33 @@
import { getNode } from "./generator";
import { PointCrawlMap, PointCrawlMapNavigator } from "./types";
export function canMoveTo(
navigator: PointCrawlMapNavigator,
map: PointCrawlMap,
targetNodeId: string,
): boolean {
const currentNode = getNode(map, navigator.currentNodeId);
if (!currentNode) return false;
return currentNode.childIds.includes(targetNodeId);
}
export function moveToNode(
navigator: PointCrawlMapNavigator,
map: PointCrawlMap,
targetNodeId: string,
): boolean {
if (!canMoveTo(navigator, map, targetNodeId)) {
return false;
}
const targetNode = getNode(map, targetNodeId);
if (!targetNode) {
return false;
}
// Update current position
navigator.currentNodeId = targetNodeId;
navigator.visitedNodes.add(targetNodeId);
return true;
}

View File

@ -4,22 +4,22 @@ import {EncounterData} from "@/samples/slay-the-spire-like/system/types";
* Types of nodes that can appear on the point crawl map. * Types of nodes that can appear on the point crawl map.
*/ */
export enum MapNodeType { export enum MapNodeType {
Start = 'start', Start = "start",
End = 'end', End = "end",
Minion = 'minion', Minion = "minion",
Elite = 'elite', Elite = "elite",
Event = 'event', Event = "event",
Camp = 'camp', Camp = "camp",
Shop = 'shop', Shop = "shop",
Curio = 'curio', Curio = "curio",
} }
/** /**
* Semantic type of a layer. * Semantic type of a layer.
*/ */
export enum MapLayerType { export enum MapLayerType {
Wild = 'wild', Wild = "wild",
Settlement = 'settlement', Settlement = "settlement",
} }
/** /**
@ -47,7 +47,7 @@ export interface MapLayer {
/** Ordered IDs of nodes in this layer */ /** Ordered IDs of nodes in this layer */
nodeIds: string[]; nodeIds: string[];
/** Semantic type of the layer */ /** Semantic type of the layer */
layerType: MapLayerType | 'start' | 'end'; layerType: MapLayerType | "start" | "end";
/** Direct references to nodes in this layer (for performance) */ /** Direct references to nodes in this layer (for performance) */
nodes: MapNode[]; nodes: MapNode[];
} }
@ -64,6 +64,11 @@ export interface PointCrawlMap {
parentIndex?: Map<string, string[]>; parentIndex?: Map<string, string[]>;
} }
export interface PointCrawlMapNavigator {
currentNodeId: string;
visitedNodes: Set<string>;
}
/** /**
* Configuration for map generation. * Configuration for map generation.
*/ */