How to resolve the algorithm Maze solving step by step in the Prolog programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Maze solving step by step in the Prolog programming language

Table of Contents

Problem Statement

For a maze generated by this task, write a function that finds (and displays) the shortest path between two cells.

Note that because these mazes are generated by the Depth-first search algorithm, they contain no circular paths, and a simple depth-first tree search can be used.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Maze solving step by step in the Prolog programming language

Source code in the prolog programming language

:- dynamic cell/2.
:- dynamic maze/3.
:- dynamic path/1.

maze_solve(Lig,Col) :-
	retractall(cell(_,_)),
	retractall(maze(_,_,_)),
	retractall(path(_)),

	% initialisation of the neighbours of the cells
	forall(between(0, Lig, I),
	       (   forall(between(0, Col, J), assert(maze(I, J, []))))),

	% creation of the window of the maze
	new(D, window('Maze')),
	forall(between(0,Lig, I),
	       (XL is  50, YL is I * 30 + 50,
		XR is Col * 30 + 50,
		new(L, line(XL, YL, XR, YL)),
		send(D, display, L))),

	forall(between(0,Col, I),
	       (XT is  50 + I * 30, YT is 50,
		YB is Lig * 30 + 50,
		new(L, line(XT, YT, XT, YB)),
		send(D, display, L))),

	SX is Col * 30 + 100,
	SY is Lig * 30 + 100,
	send(D, size, new(_, size(SX, SY))),
	L0 is random(Lig),
	C0 is random(Col),
	assert(cell(L0, C0)),
	\+search(D, Lig, Col, L0, C0),
	send(D, open),

	% we look for a path from cell(0, 0) to cell(Lig-1, Col-1)
	% creation of the entrance
	erase_line(D, -1, 0, 0, 0),

	% creation of the exit
	Lig1 is Lig-1,
	Col1 is Col-1,
	erase_line(D, Lig1, Col1, Lig, Col1),

	% seraching the path
	assert(path([[0, 0], [-1, 0]])),
	walk(Lig, Col),
	path(P),
	display_path(D, P).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
walk(Lig, Col) :-
	path([[L, C] | _R]),
	L is Lig - 1,
	C is Col - 1,
	retract(path(P)),
	assert(path([[Lig, C]|P])).

walk(Lig, Col) :-
	retract(path([[L, C] | R])),
	maze(L, C, Edge),
	member([L1, C1], Edge),
	\+member([L1, C1], R),
	assert(path([[L1,C1], [L, C] | R])),
	walk(Lig, Col).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
display_path(_, []).

display_path(D, [[L, C] | R]):-
	new(B, box(10,10)),
	send(B, fill_pattern, new(_, colour(@default, 0,0,0))),
	X is C * 30 + 60,
	Y is L * 30 + 60,
	send(D, display, B, point(X,Y)),
	display_path(D, R).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
search(D, Lig, Col, L, C) :-
	Dir is random(4),
	nextcell(Dir, Lig, Col, L, C, L1, C1),
	assert(cell(L1,C1)),
	assert(cur(L1,C1)),

	retract(maze(L, C, Edge)),
	assert(maze(L, C, [[L1, C1] | Edge])),
	retract(maze(L1, C1, Edge1)),
	assert(maze(L1, C1, [[L, C] | Edge1])),

	erase_line(D, L, C, L1, C1),
	search(D, Lig, Col, L1, C1).



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
erase_line(D, L, C, L, C1) :-
	(   C < C1 -> C2 = C1; C2 = C),
	XT is C2  * 30 + 50,
	YT is L * 30 + 51, YR is (L+1) * 30 + 50,
	new(Line, line(XT, YT, XT, YR)),
	send(Line, colour, white),
	send(D, display, Line).

erase_line(D, L, C, L1, C) :-
	XT is  51 + C * 30, XR is 50 + (C + 1) * 30,
	(   L < L1 -> L2 is L1; L2 is L),
	YT is L2 * 30 + 50,
	new(Line, line(XT, YT, XR, YT)),
	send(Line, colour, white),
	send(D, display, Line).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nextcell(Dir, Lig, Col, L, C, L1, C1) :-
	next(Dir, Lig, Col, L, C, L1, C1);
	(   Dir1 is (Dir+3) mod 4,
	    next(Dir1, Lig, Col, L, C, L1, C1));
	(   Dir2 is (Dir+1) mod 4,
	    next(Dir2, Lig, Col, L, C, L1, C1));
	(   Dir3 is (Dir+2) mod 4,
	    next(Dir3, Lig, Col, L, C, L1, C1)).

% 0 => northward
next(0, _Lig, _Col, L, C, L1, C) :-
	L > 0,
	L1 is L - 1,
	\+cell(L1, C).

% 1 => rightward
next(1, _Lig, Col, L, C, L, C1) :-
	C < Col - 1,
	C1 is C + 1,
	\+cell(L, C1).

% 2 => southward
next(2, Lig, _Col, L, C, L1, C) :-
	L < Lig - 1,
	L1 is L + 1,
	\+cell(L1, C).

% 3 => leftward
next(2, _Lig, _Col, L, C, L, C1) :-
	C > 0,
	C1 is C - 1,
	\+cell(L, C1).


  

You may also check:How to resolve the algorithm Quine step by step in the Applesoft BASIC programming language
You may also check:How to resolve the algorithm Primality by trial division step by step in the Oforth programming language
You may also check:How to resolve the algorithm Variable size/Get step by step in the Vala programming language
You may also check:How to resolve the algorithm Averages/Root mean square step by step in the Nemerle programming language
You may also check:How to resolve the algorithm Sum of a series step by step in the Joy programming language