home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
MBUG
/
MBUG165.ARC
/
MAZE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1979-12-31
|
7KB
|
263 lines
program Maze;
{
This program origionally appeared in the book by: Paul A. Sand called
Advanced PASCAL Programming Techniques. It was entered and modified for
IBM PC version of Turbo Pascal 3.0 by: Felix M. Daske.
The code was modified for the Microbee by Alan Laughton on 5/5/91.
}
{$A-}
const
MazeCols = 65;
MazeRows = 22;
MaxCrtCol = 66;
MaxCrtRow = 23;
Xindent = 1;
Yindent = 1;
type
MazeSquare = (wall, path);
MazeArray = array [0..MazeRows, 0..MazeCols] of MazeSquare;
CrtCommand = (home, clear, eraseol, eraseos, up, down, left, right, beep);
Direction = up..right;
var
Maze: Mazearray;
Won : boolean;
ch : char;
procedure dispsquare(val: Integer; row, col: integer);
begin
gotoxy(col + Xindent, row + Yindent);
write(chr(val));
end;
procedure SetSquare(row, col : integer; val : MazeSquare);
begin
maze[row, col] := val;
case val of
path : dispsquare( 32, row, col);
wall : dispsquare(160, row, col);
end;
end;
function rnd (low, high: Integer): integer;
begin
rnd := low + random(high - low + 1);
end;
function randdir: direction;
begin
case rnd(1, 4) of
1 : randdir := up;
2 : randdir := down;
3 : randdir := left;
4 : randdir := right;
end;
end;
function legalpath(row, col: integer; dir: direction): boolean;
var
legal : boolean;
begin
legal := false;
case dir of
up : if row > 2 then
legal := (maze[row - 2, col] = wall);
down : if row < MazeRows - 2 then
legal := (maze[row + 2, col] = wall);
left : if col > 2 then
legal := (maze[row, col - 2] = wall);
right : if col < MazeCols - 2 then
legal := (maze[row, col + 2] = wall);
end;
legalpath := legal;
end;
procedure buildpath(row, col: integer; dir : direction);
var
unused: set of direction;
begin
case dir of
up : begin
setsquare(row - 1, col, path);
setsquare(row - 2, col, path);
row := row -2;
end;
down : begin
setsquare(row + 1, col, path);
setsquare(row + 2, col, path);
row := row + 2;
end;
left : begin
setsquare(row, col - 1, path);
setsquare(row, col - 2, path);
col := col - 2;
end;
right: begin
setsquare(row, col + 1, path);
setsquare(row, col + 2, path);
col := col + 2;
end;
end;
unused := [up..right];
repeat
dir := randdir;
if dir in unused then
begin
unused := unused - [dir];
if legalpath(row, col, dir) then
buildpath(row, col, dir);
end;
until unused = [];
end;
procedure createmaze(var maze: mazearray);
var
row, col : integer;
dir : direction;
begin
for row := 0 to MazeRows do
for col := 0 to MazeCols do
SetSquare(row, col, wall);
gotoxy(67,23); write(' ');
row := 2 * rnd(0,trunc(MazeRows / 2 - 1)) + 1;
col := 2 * rnd(0,trunc(MazeCols / 2 - 1)) + 1;
SetSquare(row, col, path);
repeat
dir := randdir;
until legalpath(row, col, dir);
buildpath(row, col, dir);
col := 2 * rnd(0,trunc(MazeCols / 2 - 1)) + 1;
SetSquare(0, col, path);
gotoxy(col+2,1); lowvideo; write('IN'); normvideo;
col := 2 * rnd(0,trunc(MazeCols / 2 - 1)) + 1;
SetSquare(MazeRows, col, path);
gotoxy(col+2,MazeRows+1); lowvideo; write('OUT'); normvideo;
end;
function solvemaze(var maze: mazearray) : boolean;
var
solved : boolean;
row, col : integer;
tried: array [0..mazerows, 0..mazecols] of boolean;
function try(row, col: integer; dir: direction) : boolean;
var
ok : boolean;
procedure showmove(row, col: integer; dir : direction);
begin
case dir of
up : dispsquare(111, row, col);
down : dispsquare(111, row, col);
right : dispsquare(111, row, col);
left : dispsquare(111, row, col);
end;
end;
procedure erasemove(row, col : integer);
begin
dispsquare(32, row, col);
end;
begin { try }
ok := (maze[row, col] = path);
if ok then
begin
tried[row, col] := true;
case dir of
up : row := row - 1;
down : row := row + 1;
left : col := col - 1;
right : col := col + 1;
end;
ok := (maze[row, col] = path) and not tried[row, col];
if ok then
begin
showmove(row, col, dir);
ok := (row <= 0) or (row >= mazerows) or
(col <= 0) or (col >= mazecols);
if not ok then
ok := try(row, col, left);
if not ok then
ok := try(row, col, down);
if not ok then
ok := try(row, col, right);
if not ok then
ok := try(row, col, up);
if not ok then { no solution from this point }
erasemove(row, col);
end;
end;
try := ok;
end;
begin { solvemaze }
for row := 0 to mazerows do
for col := 0 to mazecols do
tried[row, col] := false;
solved := false;
col := 0;
row := 1;
while not solved and (row < mazerows) do
begin
solved := try(row, col, right);
row := row + 1;
end;
col := mazecols;
row := 1;
while not solved and (row < mazerows) do
begin
solved := try(row, col, left);
row := row + 1;
end;
row := 0;
col := 1;
while not solved and (col < mazecols) do
begin
solved := try(row, col, down);
col := col + 1;
end;
row := mazerows;
col := 1;
while not solved and (col < mazecols) do
begin
solved := try(row, col, up);
col := col + 1;
end;
solvemaze := solved;
end;
begin
Clrscr;
Randomize;
repeat
createmaze(maze);
lowvideo;
gotoxy(68,1); write('Maze for');
gotoxy(68,2); write('Microbee');
normvideo;
gotoxy(68,4); write('Press any');
gotoxy(68,5); write('key for');
gotoxy(68,6); write('answer.');
gotoxy(1,26);
read(KBD,ch);
Won := solvemaze(maze);
gotoxy(68,8); write('Press <Q>');
gotoxy(68,9); write('to Quit or');
gotoxy(68,10); write('any key for');
gotoxy(68,11); write('another Maze');
gotoxy(1,26);
read(KBD,ch);
gotoxy(68,8); write(' ');
gotoxy(68,9); write(' ');
gotoxy(68,10); write(' ');
gotoxy(68,11); write(' ');
until ch in ['q','Q'];
clrscr;
end.