85 lines
2.9 KiB
TypeScript
85 lines
2.9 KiB
TypeScript
import {MazeCell} from "./model/maze.ts";
|
|
import Coordinates from "./model/coordinates.ts";
|
|
import {Action, actionClickedCell} from "./state/action.ts";
|
|
import styles from "./cell.module.scss";
|
|
import "./cell.scss";
|
|
import {State} from "./state/state.ts";
|
|
import {ActionDispatch} from "react";
|
|
|
|
function getMarkedDirections(coords: Coordinates, marked: Coordinates[]): Direction[] {
|
|
const cellIndex: number = marked.findIndex(e => e.x === coords.x && e.y === coords.y);
|
|
if (cellIndex === -1) {
|
|
return [];
|
|
}
|
|
if (marked.length === 1) {
|
|
return [Direction.SELF];
|
|
}
|
|
if (cellIndex === 0) {
|
|
const next: Coordinates = marked[1];
|
|
return [Direction.SELF, getDirectionTo(coords, next)];
|
|
} else {
|
|
const previous = marked[cellIndex - 1];
|
|
if (cellIndex === marked.length - 1) {
|
|
return [Direction.SELF, getDirectionTo(coords, previous)];
|
|
}
|
|
const next: Coordinates = marked[cellIndex + 1];
|
|
return [Direction.SELF, getDirectionTo(coords, previous), getDirectionTo(coords, next)];
|
|
}
|
|
}
|
|
|
|
function getDirectionTo(me: Coordinates, other: Coordinates): Direction {
|
|
const xDiff = me.x - other.x;
|
|
switch (xDiff) {
|
|
case -1:
|
|
return Direction.RIGHT;
|
|
case 1:
|
|
return Direction.LEFT;
|
|
default:
|
|
const yDiff = me.y - other.y;
|
|
if (yDiff === -1) {
|
|
return Direction.DOWN;
|
|
}
|
|
return Direction.UP;
|
|
}
|
|
}
|
|
|
|
export default function Cell({x, y, state, dispatch}:
|
|
{
|
|
x: number,
|
|
y: number,
|
|
state: State,
|
|
dispatch: ActionDispatch<[Action]>
|
|
}) {
|
|
const cell: MazeCell = state.maze!.grid[y][x];
|
|
let classes = " r" + y + " c" + x;
|
|
if (cell.top) classes += " top";
|
|
if (cell.right) classes += " right";
|
|
if (cell.bottom) classes += " bottom";
|
|
if (cell.left) classes += " left";
|
|
if (cell.solution && state.showSolution) classes += " solution";
|
|
const markedDirections = getMarkedDirections({x, y}, state.userPath);
|
|
for (let i = 0; i < markedDirections.length; i++) {
|
|
classes += ` user${Direction[markedDirections[i]]}`;
|
|
}
|
|
return (
|
|
<div className={styles.cell + classes}
|
|
onMouseEnter={(e) => {
|
|
const leftPressed = e.buttons & 0x1;
|
|
if (leftPressed) {
|
|
dispatch(actionClickedCell(x, y));
|
|
}
|
|
}}
|
|
onClick={() => {
|
|
dispatch(actionClickedCell(x, y));
|
|
}}>
|
|
<div className={"marker UP"}></div>
|
|
<div className={"marker RIGHT"}></div>
|
|
<div className={"marker DOWN"}></div>
|
|
<div className={"marker LEFT"}></div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
enum Direction {
|
|
UP, RIGHT, DOWN, LEFT, SELF
|
|
}
|