Kacemath's picture
Simple deployment: Grid Search Pathfinding with frontend and backend
e067c2d
raw
history blame
5.05 kB
import { create } from 'zustand';
import type {
GridState,
SearchResult,
PlanResult,
ComparisonResult,
Algorithm,
SearchStep,
GridConfig,
} from '../types';
import { generateGrid, createPlan, compareAlgorithms, findPath } from '../api/client';
interface GridStore {
// Grid state
grid: GridState | null;
initialState: string;
traffic: string;
// Search state
searchResult: SearchResult | null;
planResult: PlanResult | null;
comparisonResults: ComparisonResult[] | null;
// Visualization state
currentStep: number;
steps: SearchStep[];
isPlaying: boolean;
playbackSpeed: number; // ms per step
// UI state
selectedAlgorithm: Algorithm;
isLoading: boolean;
error: string | null;
// Actions
setGrid: (grid: GridState, initialState: string, traffic: string) => void;
generateNewGrid: (config?: GridConfig) => Promise<void>;
runSearch: (start: { x: number; y: number }, goal: { x: number; y: number }) => Promise<void>;
runPlan: (visualize?: boolean) => Promise<void>;
runComparison: () => Promise<void>;
setAlgorithm: (algorithm: Algorithm) => void;
setCurrentStep: (step: number) => void;
play: () => void;
pause: () => void;
setSpeed: (speed: number) => void;
reset: () => void;
nextStep: () => void;
prevStep: () => void;
}
export const useGridStore = create<GridStore>((set, get) => ({
// Initial state
grid: null,
initialState: '',
traffic: '',
searchResult: null,
planResult: null,
comparisonResults: null,
currentStep: 0,
steps: [],
isPlaying: false,
playbackSpeed: 100,
selectedAlgorithm: 'BF',
isLoading: false,
error: null,
// Actions
setGrid: (grid, initialState, traffic) => {
set({
grid,
initialState,
traffic,
searchResult: null,
planResult: null,
comparisonResults: null,
currentStep: 0,
steps: [],
isPlaying: false,
error: null,
});
},
generateNewGrid: async (config = {}) => {
set({ isLoading: true, error: null });
try {
const result = await generateGrid(config);
set({
grid: result.parsed,
initialState: result.initialState,
traffic: result.traffic,
searchResult: null,
planResult: null,
comparisonResults: null,
currentStep: 0,
steps: [],
isPlaying: false,
isLoading: false,
});
} catch (error) {
set({
error: error instanceof Error ? error.message : 'Failed to generate grid',
isLoading: false,
});
}
},
runSearch: async (start, goal) => {
const { grid, selectedAlgorithm } = get();
if (!grid) return;
set({ isLoading: true, error: null });
try {
const result = await findPath(
grid.width,
grid.height,
start,
goal,
grid.segments,
grid.tunnels,
selectedAlgorithm
);
set({
searchResult: result,
steps: result.steps || [],
currentStep: 0,
isPlaying: false,
isLoading: false,
});
} catch (error) {
set({
error: error instanceof Error ? error.message : 'Search failed',
isLoading: false,
});
}
},
runPlan: async (visualize = false) => {
const { initialState, traffic, selectedAlgorithm } = get();
if (!initialState) return;
set({ isLoading: true, error: null });
try {
const result = await createPlan(initialState, traffic, selectedAlgorithm, visualize);
set({
planResult: result,
isLoading: false,
});
} catch (error) {
set({
error: error instanceof Error ? error.message : 'Planning failed',
isLoading: false,
});
}
},
runComparison: async () => {
const { initialState, traffic } = get();
if (!initialState) return;
set({ isLoading: true, error: null });
try {
const result = await compareAlgorithms(initialState, traffic);
set({
comparisonResults: result.comparisons,
isLoading: false,
});
} catch (error) {
set({
error: error instanceof Error ? error.message : 'Comparison failed',
isLoading: false,
});
}
},
setAlgorithm: (algorithm) => {
set({ selectedAlgorithm: algorithm });
},
setCurrentStep: (step) => {
const { steps } = get();
set({ currentStep: Math.max(0, Math.min(step, steps.length - 1)) });
},
play: () => {
set({ isPlaying: true });
},
pause: () => {
set({ isPlaying: false });
},
setSpeed: (speed) => {
set({ playbackSpeed: speed });
},
reset: () => {
set({
currentStep: 0,
isPlaying: false,
});
},
nextStep: () => {
const { currentStep, steps } = get();
if (currentStep < steps.length - 1) {
set({ currentStep: currentStep + 1 });
} else {
set({ isPlaying: false });
}
},
prevStep: () => {
const { currentStep } = get();
if (currentStep > 0) {
set({ currentStep: currentStep - 1 });
}
},
}));