You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.7 KiB
90 lines
2.7 KiB
import { describe, expect, it } from "vitest";
|
|
import {
|
|
axialNeighbors,
|
|
isConnected,
|
|
shortestPath,
|
|
shortestPathLength,
|
|
} from "../../src/stages/games/chase/logic/hexGraph";
|
|
import type { GameGraph } from "../../src/stages/games/chase/logic/types";
|
|
|
|
function buildGraph(nodes: GameGraph["nodes"]): GameGraph {
|
|
return {
|
|
nodes,
|
|
edgeList: [],
|
|
};
|
|
}
|
|
|
|
describe("hex graph utilities", () => {
|
|
it("returns 6 axial neighbors", () => {
|
|
const neighbors = axialNeighbors(0, 0);
|
|
expect(neighbors).toEqual([
|
|
[1, 0],
|
|
[1, -1],
|
|
[0, -1],
|
|
[-1, 0],
|
|
[-1, 1],
|
|
[0, 1],
|
|
]);
|
|
});
|
|
|
|
it("finds bfs shortest path length", () => {
|
|
const graph = buildGraph({
|
|
A: { id: "A", q: 0, r: 0, neighbors: ["B"] },
|
|
B: { id: "B", q: 1, r: 0, neighbors: ["A", "C"] },
|
|
C: { id: "C", q: 2, r: 0, neighbors: ["B", "D"] },
|
|
D: { id: "D", q: 3, r: 0, neighbors: ["C"] },
|
|
});
|
|
|
|
expect(shortestPathLength(graph, "A", "D")).toBe(3);
|
|
expect(shortestPathLength(graph, "A", "A")).toBe(0);
|
|
expect(shortestPath(graph, "A", "D")).toEqual(["A", "B", "C", "D"]);
|
|
});
|
|
|
|
it("returns Infinity when target is unreachable", () => {
|
|
const graph = buildGraph({
|
|
A: { id: "A", q: 0, r: 0, neighbors: ["B"] },
|
|
B: { id: "B", q: 1, r: 0, neighbors: ["A"] },
|
|
C: { id: "C", q: 5, r: 5, neighbors: [] },
|
|
});
|
|
|
|
expect(shortestPathLength(graph, "A", "C")).toBe(Infinity);
|
|
});
|
|
|
|
it("returns Infinity for invalid from/to nodes", () => {
|
|
const graph = buildGraph({
|
|
A: { id: "A", q: 0, r: 0, neighbors: ["B"] },
|
|
B: { id: "B", q: 1, r: 0, neighbors: ["A"] },
|
|
});
|
|
|
|
expect(shortestPathLength(graph, "X", "X")).toBe(Infinity);
|
|
expect(shortestPathLength(graph, "X", "A")).toBe(Infinity);
|
|
expect(shortestPathLength(graph, "A", "X")).toBe(Infinity);
|
|
});
|
|
|
|
it("checks graph connectivity", () => {
|
|
const connectedGraph = buildGraph({
|
|
A: { id: "A", q: 0, r: 0, neighbors: ["B"] },
|
|
B: { id: "B", q: 1, r: 0, neighbors: ["A", "C"] },
|
|
C: { id: "C", q: 2, r: 0, neighbors: ["B"] },
|
|
});
|
|
|
|
const disconnectedGraph = buildGraph({
|
|
A: { id: "A", q: 0, r: 0, neighbors: ["B"] },
|
|
B: { id: "B", q: 1, r: 0, neighbors: ["A"] },
|
|
C: { id: "C", q: 5, r: 5, neighbors: [] },
|
|
});
|
|
|
|
expect(isConnected(connectedGraph)).toBe(true);
|
|
expect(isConnected(disconnectedGraph)).toBe(false);
|
|
});
|
|
|
|
it("treats empty and single-node graph as connected", () => {
|
|
const emptyGraph = buildGraph({});
|
|
const singleNodeGraph = buildGraph({
|
|
A: { id: "A", q: 0, r: 0, neighbors: [] },
|
|
});
|
|
|
|
expect(isConnected(emptyGraph)).toBe(true);
|
|
expect(isConnected(singleNodeGraph)).toBe(true);
|
|
});
|
|
});
|
|
|