Add map state module with createMap, advanceMap, getCurrentNode
This commit is contained in:
parent
4f91396e3a
commit
a7c5cbc56a
2 changed files with 116 additions and 0 deletions
35
src/map.js
Normal file
35
src/map.js
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
const ACT1_LAYOUT = [
|
||||
"encounter",
|
||||
"encounter",
|
||||
"campfire",
|
||||
"encounter",
|
||||
"elite",
|
||||
"encounter",
|
||||
"campfire",
|
||||
"encounter",
|
||||
"elite",
|
||||
"boss",
|
||||
];
|
||||
|
||||
export function createMap() {
|
||||
return {
|
||||
nodes: ACT1_LAYOUT.map((type, id) => ({ id, type, cleared: false })),
|
||||
currentNode: 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function advanceMap(map) {
|
||||
const last = map.nodes.length - 1;
|
||||
const nodes = map.nodes.map((n, i) =>
|
||||
i === map.currentNode ? { ...n, cleared: true } : n,
|
||||
);
|
||||
return {
|
||||
...map,
|
||||
nodes,
|
||||
currentNode: Math.min(map.currentNode + 1, last),
|
||||
};
|
||||
}
|
||||
|
||||
export function getCurrentNode(map) {
|
||||
return map.nodes[map.currentNode];
|
||||
}
|
||||
81
src/map.test.js
Normal file
81
src/map.test.js
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { advanceMap, createMap, getCurrentNode } from "./map.js";
|
||||
|
||||
describe("createMap", () => {
|
||||
test("returns 10 nodes", () => {
|
||||
const map = createMap();
|
||||
expect(map.nodes).toHaveLength(10);
|
||||
});
|
||||
|
||||
test("first node is encounter, last node is boss", () => {
|
||||
const map = createMap();
|
||||
expect(map.nodes[0].type).toBe("encounter");
|
||||
expect(map.nodes[9].type).toBe("boss");
|
||||
});
|
||||
|
||||
test("contains expected node type counts", () => {
|
||||
const map = createMap();
|
||||
const types = map.nodes.map((n) => n.type);
|
||||
expect(types.filter((t) => t === "encounter")).toHaveLength(5);
|
||||
expect(types.filter((t) => t === "campfire")).toHaveLength(2);
|
||||
expect(types.filter((t) => t === "elite")).toHaveLength(2);
|
||||
expect(types.filter((t) => t === "boss")).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("all nodes start cleared: false", () => {
|
||||
const map = createMap();
|
||||
expect(map.nodes.every((n) => n.cleared === false)).toBe(true);
|
||||
});
|
||||
|
||||
test("each node has sequential id 0-9", () => {
|
||||
const map = createMap();
|
||||
map.nodes.forEach((n, i) => {
|
||||
expect(n.id).toBe(i);
|
||||
});
|
||||
});
|
||||
|
||||
test("currentNode starts at 0", () => {
|
||||
const map = createMap();
|
||||
expect(map.currentNode).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("advanceMap", () => {
|
||||
test("marks current node cleared and increments currentNode", () => {
|
||||
const map = createMap();
|
||||
const next = advanceMap(map);
|
||||
expect(next.nodes[0].cleared).toBe(true);
|
||||
expect(next.currentNode).toBe(1);
|
||||
});
|
||||
|
||||
test("does not mutate the input map", () => {
|
||||
const map = createMap();
|
||||
advanceMap(map);
|
||||
expect(map.nodes[0].cleared).toBe(false);
|
||||
expect(map.currentNode).toBe(0);
|
||||
});
|
||||
|
||||
test("does not go past last node (index 9)", () => {
|
||||
let map = createMap();
|
||||
for (let i = 0; i < 10; i++) {
|
||||
map = advanceMap(map);
|
||||
}
|
||||
expect(map.currentNode).toBe(9);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getCurrentNode", () => {
|
||||
test("returns the node at currentNode index", () => {
|
||||
const map = createMap();
|
||||
const node = getCurrentNode(map);
|
||||
expect(node).toBe(map.nodes[map.currentNode]);
|
||||
expect(node.id).toBe(0);
|
||||
expect(node.type).toBe("encounter");
|
||||
});
|
||||
|
||||
test("returns correct node after advancing", () => {
|
||||
const map = advanceMap(createMap());
|
||||
const node = getCurrentNode(map);
|
||||
expect(node.id).toBe(1);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue