Skip to content

Commit

Permalink
Grid drawing fixes & labyrinth fix
Browse files Browse the repository at this point in the history
  • Loading branch information
sadanandpai committed Mar 28, 2024
1 parent 21dab51 commit 235c6e7
Show file tree
Hide file tree
Showing 13 changed files with 289 additions and 249 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const mazeGeneratorsFns = [
mazeGenerators.get('wilson')!.fn,
mazeGenerators.get('binary')!.fn,
mazeGenerators.get('sideWinder')!.fn,
mazeGenerators.get('labyrinth')!.fn,
];

const updateCells = vi.fn(async (grid, cells, cellType = CellType.clear) => {
Expand All @@ -28,7 +29,7 @@ describe('Maze generator functions', () => {

it('generate maze with entry & exit on clear slots', async () => {
const rows = 9;
const cols = 15;
const cols = 17;
const updateGrid = vi.fn();

for await (const mazeFn of mazeGeneratorsFns) {
Expand Down Expand Up @@ -74,7 +75,7 @@ describe('Maze generator functions', () => {
});

it('generate maze with entry & exit on walls slots', async () => {
const rows = 7;
const rows = 9;
const cols = 21;
const updateGrid = vi.fn();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
drawHorizontalWall,
drawVerticalWall,
getRandomEvenNumber,
getRandomOddNumber,
} from '@pathFinder/algorithms/maze-generator/recursive-division';
import { Cell, CellType } from '@pathFinder/models/interfaces';

Expand All @@ -21,28 +19,6 @@ describe('Recursive Division maze helpers', () => {
updateCells.mockClear();
});

it('getRandomEvenNumber', () => {
for (let i = 0; i < 100; i++) {
const min = Math.floor(Math.random() * 20);
const max = min + Math.floor(Math.random() * 20) + 1;
const number = getRandomEvenNumber(min, max);
expect(number).toBeGreaterThanOrEqual(min);
expect(number).toBeLessThanOrEqual(max);
expect(number % 2).toBe(0);
}
});

it('getRadomOddNumber', () => {
for (let i = 0; i < 100; i++) {
const min = Math.floor(Math.random() * 20);
const max = min + Math.floor(Math.random() * 20) + 1;
const number = getRandomOddNumber(min, max);
expect(number).toBeGreaterThanOrEqual(min);
expect(number).toBeLessThanOrEqual(max);
expect(number % 2).toBe(1);
}
});

it('drawHorizontalWall', async () => {
const rows = 9;
const cols = 15;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {
filterByCellType,
filterValidCells,
getNeighbors,
getRandomEvenNumber,
getRandomOddNumber,
} from '@/apps/path-finder/helpers/maze.helper';
import { CellType } from '@pathFinder/models/interfaces';

Expand Down Expand Up @@ -219,4 +221,26 @@ describe('Maze helpers', () => {
const filteredWalls = filterByCellType([], grid, wall);
expect(filteredWalls).toMatchInlineSnapshot(`[]`);
});

it('getRandomEvenNumber', () => {
for (let i = 0; i < 100; i++) {
const min = Math.floor(Math.random() * 20);
const max = min + Math.floor(Math.random() * 20) + 1;
const number = getRandomEvenNumber(min, max);
expect(number).toBeGreaterThanOrEqual(min);
expect(number).toBeLessThanOrEqual(max);
expect(number % 2).toBe(0);
}
});

it('getRadomOddNumber', () => {
for (let i = 0; i < 100; i++) {
const min = Math.floor(Math.random() * 20);
const max = min + Math.floor(Math.random() * 20) + 1;
const number = getRandomOddNumber(min, max);
expect(number).toBeGreaterThanOrEqual(min);
expect(number).toBeLessThanOrEqual(max);
expect(number % 2).toBe(1);
}
});
});
194 changes: 133 additions & 61 deletions src/apps/path-finder/algorithms/maze-generator/labyrinth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { generateGrid } from '@/apps/path-finder/helpers/grid.helper';
import { CellType, MazeAlgoProps } from '@pathFinder/models/interfaces';
import { getRandomOddNumber } from '../../helpers/maze.helper';

interface Direction {
top: number;
Expand All @@ -8,17 +9,7 @@ interface Direction {
left: number;
}

export function getRandomEvenNumber(min: number, max: number) {
const random = Math.floor(Math.random() * (max - min)) + min;
return random % 2 === 0 ? random : random + 1;
}

export function getRandomOddNumber(min: number, max: number) {
const random = Math.floor(Math.random() * (max - min)) + min;
return random % 2 === 1 ? random : random + 1;
}

export async function addWalls(
export async function addStages(
grid: CellType[][],
updateCells: MazeAlgoProps['updateCells']
) {
Expand Down Expand Up @@ -73,7 +64,7 @@ export async function addVerticalBlocks(
return { top, bottom };
}

async function addHorizontalBlocks(
export async function addHorizontalBlocks(
grid: CellType[][],
updateCells: MazeAlgoProps['updateCells'],
stage: number
Expand All @@ -94,63 +85,145 @@ async function addHorizontalBlocks(
return { left, right };
}

export async function addGaps(
grid: CellType[][],
updateCells: MazeAlgoProps['updateCells'],
stage: number,
{ top, right, bottom, left }: Direction
) {
const rows = grid.length;
const cols = grid[0].length;
let random;

// get cells between top and right
export function getTopRightCells({
cols,
stage,
top,
right,
}: {
cols: number;
stage: number;
top: number;
right: number;
}) {
const cells = [];
for (let i = top + 1; i < cols - stage - 1; i += 2) {
cells.push({ row: stage + 1, col: i });
if (top !== 0) {
for (let i = top + 1; i < cols - stage - 1; i += 2) {
cells.push({ row: stage + 1, col: i });
}
}
for (let i = stage + 2; i < right; i += 2) {
cells.push({ row: i, col: cols - stage - 2 });
if (right !== 0) {
for (let i = stage + 2; i < right; i += 2) {
cells.push({ row: i, col: cols - stage - 2 });
}
}

random = Math.floor(Math.random() * cells.length);
await updateCells(grid, cells[random]);
return cells;
}

// get cells between right and bottom
cells.length = 0;
for (let i = right + 1; i < rows - stage - 1; i += 2) {
cells.push({ row: i, col: cols - stage - 2 });
export function getRightBottomCells({
rows,
cols,
stage,
right,
bottom,
}: {
rows: number;
cols: number;
stage: number;
right: number;
bottom: number;
}) {
const cells = [];
if (right !== 0) {
for (let i = right + 1; i < rows - stage - 1; i += 2) {
cells.push({ row: i, col: cols - stage - 2 });
}
}
for (let i = cols - stage - 3; i > bottom; i -= 2) {
cells.push({ row: rows - stage - 2, col: i });
if (bottom !== 0) {
for (let i = cols - stage - 3; i > bottom; i -= 2) {
cells.push({ row: rows - stage - 2, col: i });
}
}
return cells;
}

random = Math.floor(Math.random() * cells.length);
await updateCells(grid, cells[random]);

// get cells between bottom and left
cells.length = 0;
for (let i = bottom - 1; i > stage; i -= 2) {
cells.push({ row: rows - stage - 2, col: i });
export function getBottomLeftCells({
rows,
stage,
bottom,
left,
}: {
rows: number;
stage: number;
bottom: number;
left: number;
}) {
const cells = [];
if (bottom !== 0) {
for (let i = bottom - 1; i > stage; i -= 2) {
cells.push({ row: rows - stage - 2, col: i });
}
}
for (let i = rows - stage - 3; i > left; i -= 2) {
cells.push({ row: i, col: stage + 1 });
if (left !== 0) {
for (let i = rows - stage - 3; i > left; i -= 2) {
cells.push({ row: i, col: stage + 1 });
}
}
return cells;
}

random = Math.floor(Math.random() * cells.length);
await updateCells(grid, cells[random]);

// // get cells between left and top
cells.length = 0;
for (let i = left - 1; i > stage + 1; i -= 2) {
cells.push({ row: i, col: stage + 1 });
export function getLeftTopCells({
stage,
top,
left,
}: {
stage: number;
top: number;
left: number;
}) {
const cells = [];
if (left !== 0) {
for (let i = left - 1; i > stage + 1; i -= 2) {
cells.push({ row: i, col: stage + 1 });
}
}
for (let i = stage + 2; i < top; i += 2) {
cells.push({ row: stage + 1, col: i });
if (top !== 0) {
for (let i = stage + 2; i < top; i += 2) {
cells.push({ row: stage + 1, col: i });
}
}
return cells;
}

random = Math.floor(Math.random() * cells.length);
await updateCells(grid, cells[random]);
export async function addGaps(
grid: CellType[][],
updateCells: MazeAlgoProps['updateCells'],
stage: number,
{ top, right, bottom, left }: Direction
) {
const rows = grid.length;
const cols = grid[0].length;

const topRightCells = getTopRightCells({ cols, stage, top, right });
const rightBottomCells = getRightBottomCells({
rows,
cols,
stage,
right,
bottom,
});
const bottomLeftCells = getBottomLeftCells({ rows, stage, bottom, left });
const leftTopCells = getLeftTopCells({ stage, top, left });

const topRightRandom = Math.floor(Math.random() * topRightCells.length);
const rightBottomRandom = Math.floor(Math.random() * rightBottomCells.length);
const bottomLeftRandom = Math.floor(Math.random() * bottomLeftCells.length);
const leftTopRandom = Math.floor(Math.random() * leftTopCells.length);

if (top === 0 || right === 0) {
await updateCells(grid, [
topRightCells[topRightRandom],
bottomLeftCells[bottomLeftRandom],
]);
} else {
await updateCells(grid, [
topRightCells[topRightRandom],
rightBottomCells[rightBottomRandom],
bottomLeftCells[bottomLeftRandom],
leftTopCells[leftTopRandom],
]);
}
}

export async function generateLabyrinth({
Expand All @@ -163,14 +236,14 @@ export async function generateLabyrinth({
}: MazeAlgoProps) {
const grid = generateGrid(rows, cols, CellType.clear);
updateGrid(grid);
await addWalls(grid, updateCells);
await addStages(grid, updateCells);

const maxStage = Math.min(rows, cols) / 2 - 2;
for (let i = 0; i < maxStage; i += 2) {
let left = 1,
right = 1,
top = 1,
bottom = 1;
let left = 0,
right = 0,
top = 0,
bottom = 0;
if (rows - 2 * i > 5) {
({ left, right } = await addHorizontalBlocks(grid, updateCells, i));
}
Expand All @@ -182,7 +255,6 @@ export async function generateLabyrinth({
if (rows - 2 * i > 5 || cols - 2 * i > 5) {
await addGaps(grid, updateCells, i, { top, right, bottom, left });
}
// await addGaps(grid, updateCells, i, { top, right, bottom, left });
}

const centerPos = Math.floor(rows / 2);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { generateGrid } from '@/apps/path-finder/helpers/grid.helper';
import { CellType, MazeAlgoProps } from '@pathFinder/models/interfaces';
import {
getRandomEvenNumber,
getRandomOddNumber,
} from '../../helpers/maze.helper';

interface DrawWallConfig {
updateCells: MazeAlgoProps['updateCells'];
Expand All @@ -9,16 +13,6 @@ interface DrawWallConfig {
end: number;
}

export function getRandomEvenNumber(min: number, max: number) {
const random = Math.floor(Math.random() * (max - min)) + min;
return random % 2 === 0 ? random : random + 1;
}

export function getRandomOddNumber(min: number, max: number) {
const random = Math.floor(Math.random() * (max - min)) + min;
return random % 2 === 1 ? random : random + 1;
}

export async function drawHorizontalWall(
grid: CellType[][],
{ updateCells, divisionPoint, passagePoint, start, end }: DrawWallConfig
Expand Down
File renamed without changes.
Loading

0 comments on commit 235c6e7

Please sign in to comment.