Reference · Mazes, arrows and mixed boards
MazeDifficultytype
HOW HARD A MAZE IS TO PLAY, ON ONE SCALE FROM 0 TO 100 (difficultyOf). It is a second measure beside
measureMaze's effort: effort says how much there is to draw, which is mostly a question of size; this adds
what makes a maze of one size easy or tricky, so that two mazes of the same size can be told apart, and a list
can be ramped smoothly inside a size. docs/LEVELS.md explains the choices.
Six things are counted off the passages, none of which needs a person:
reach: the effort (cells drawn, wrong turns and forks included), on the log scaleratingOfuses.forks: the places on the way where the line could have gone another way (decisions).traps: forks where the straight guess is wrong. The straight guess is what a person does with no plan: at every fork, take the passage that points most nearly at the goal. A fork is a trap when that passage is not the right one. A maze with no traps is solved by pointing at the goal and walking, which is not a puzzle.waste: the cells the straight guess draws that are not on the way, walking in and out of dead ends in order of preference. The cost of being wrong, wheretrapsis how often.depth: the length of the longest wrong branch, the one that goes on looking right for longest.turns: bends on the way (a change of heading of more than 25 degrees), the thing that makes a corridor hard to follow with a thumb.
Each is turned into a share from 0 to 1 on a log scale against a ceiling (the biggest the lists reach, so a term only reaches 1 at the very top), and the score is their weighted sum: 40% reach, 15% each forks, traps and waste, 7.5% each depth and turns. Whole numbers counted off the passages and plain arithmetic, so the same maze scores the same in every engine and a list ordered by score stays ordered.
Then the score is multiplied by how much of the map the answer covers (coverageOf, src/coverage.ts): from half at an answer that stays in a corner
to the whole at one that crosses the map. The six terms count what is met on the way, and none of them can tell a long answer in a corner from one
across the whole map, which is the easier to play.
A way to play with keys is measured by the same terms: the detour to the keys is in the effort, and the trips to the keys are in the cover.
Import it
import type { MazeDifficulty } from "@johnmorrisdotca/meikyuu";
Definition
type MazeDifficulty = {
score: number;
exact: number;
base: number;
coverage: MazeCoverage;
terms: {
reach: number;
forks: number;
traps: number;
waste: number;
depth: number;
turns: number;
};
straight: boolean;
traps: number;
waste: number;
turns: number;
measure: MazeMeasure;
};
Members
| Name | Type | Description |
|---|---|---|
score | number | From 0 (a corridor) to 100 (the hardest maze in the lists), whole: the six terms' sum times the coverage factor, rounded once. |
exact | number | The same before it is rounded, so a list can be put in order finer than whole numbers. |
base | number | The six terms' weighted sum before the coverage factor, from 0 to 100: what the score was before 3.0.0. |
coverage | MazeCoverage | How much of the map the answer covers (see |
terms | { reach: number; forks: number; traps: number; waste: number; depth: number; turns: number; } | Each term as a share from 0 to 1, before it is weighted. |
straight | boolean | Whether the straight guess walks straight to the goal without ever entering a wrong branch. |
traps | number | Forks on the way where the straight guess takes the wrong passage. |
waste | number | Cells outside the way that the straight guess draws before it gets to the goal. |
turns | number | Bends on the way. |
measure | MazeMeasure | What |
Examples
import type { MazeDifficulty, MazeRecipe } from "@johnmorrisdotca/meikyuu";
import { buildMaze, difficultyOf } from "@johnmorrisdotca/meikyuu";
const recipe: MazeRecipe = {shape:"square",w:5,h:5,algorithm:"backtracker",mode:"to-goal",seed:42};
const maze = buildMaze(recipe);
const value: MazeDifficulty = difficultyOf(maze);
console.log(value);{
score: 21,
exact: 20.994659414140664,
base: 20.994659414140664,
coverage: { bbox: 1, zones: 1, cover: 1, factor: 1 },
terms: {
reach: 0.19333691220763283,
forks: 0.26850988815210197,
traps: 0.13640858525969024,
waste: 0.2129990229755436,
depth: 0.19792968021560536,
turns: 0.3343930504544367
},
straight: false,
traps: 1,
waste: 5,
turns: 10,
measure: {
cells: 25,
deadEnds: 7,
deadEndShare: 0.28,
junctions: 5,
river: 0.52,
solution: 16,
decisions: 4,
branches: 4,
longestBranch: 3,
wasted: 7,
detour: 0,
effort: 31
}
}What it prints (run when this page was built)