home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
turbopas
/
maze.lbr
/
MAZEG.PZS
/
MAZEG.PAS
Wrap
Pascal/Delphi Source File
|
1987-08-19
|
14KB
|
414 lines
{ Kevin Smathers:1986 }
program maze;
{$C-}
{Generic version: Turbo Pascal}
{This uses routines built into Turbo Pascal for cursor positioning and other
screen functions. If you can disable your cursor, you may want to do so. Also,
the routines specific to the Superbrain memory mapped video, are included.
To use memory mapped video, examine the routine OUT and change ISSET to
return type BYTE (for memory) rather than CHAR.
}
const
ver:string[30]='OxWold presents Mazes (1.0G)';
hsize=15;
vsize=10;
cpoints=3;
points=4; {1+cpoints}
type
compass=0..cpoints;
mazetype=array[1..hsize,1..vsize] of byte;
linetype=0..18;
var
pw:string[20];
hint:integer;
ptr:integer;
x,y:integer;
gx,gy:integer;
c:char;
i:integer;
hmaze,maze:mazetype;
linesr,liness:set of linetype;
lstout:text;
cur:integer;
hdata:array[0..50] of string[6];
l:array [0..32] of string[50];
procedure help;
begin
gotoxy(1,vsize+3);
writeln('Rules of the Maze:');
lowvideo;
for i:=1 to 8 do begin
if hint=i then highvideo;
case i of
1:writeln('1. You don''t get out until you find the exit');
2:writeln('2. You move forward by typing "F"');
3:writeln('3. You turn right by typing "R"');
4:writeln('4. You turn left by typing "L"');
5:writeln('5. You turn about by typeing "B"');
6:writeln('6. You have one piece of chalk, and a great deal of floor space');
7:writeln('7. You mark on the floor by typing "M"');
8:writeln('8. When the maze is finished being created, you may continue by typing anything');
end; {case}
if hint=i then lowvideo;
end;
highvideo;
Hint:=(hint+1) mod 9;
end;
procedure mazeinit(var maze:mazetype);
var
i,j,k:integer;
begin
x:=random(hsize)+1; y:=random(vsize)+1;
gx:=random(hsize)+1; gy:=random(vsize)+1;
for i:=1 to hsize do
for j:=1 to vsize do
begin
maze[i,j]:=$FF;
hmaze[i,j]:=0;
end;
for i:=0 to 50 do hdata[i]:=' ';
end;
procedure move(ox,oy:integer; dir:compass; var x,y:integer);
begin
x:=ox; y:=oy;
case dir of
0:y:=y-1;
1:x:=x+1;
2:y:=y+1;
3:x:=x-1;
end; {case}
end; {move}
function bit(t:byte; tbit:byte):boolean;
begin
bit:=(t and (1 shl tbit))>0;
end;
procedure map(var maze:mazetype; var fil:text);
var i,j:integer;
begin
clrscr;
writeln(FIL,ver);
for j:=1 to hsize do write(fil,'__'); writeln(fil);
for i:=1 to vsize do
begin
for j:=1 to hsize do
begin
if bit(maze[j,i],3) then write(fil,'I') else write(fil,'_');
if bit(maze[j,i],2) then write(fil,'_') else write(fil,' ');
end;
writeln(fil,'I');
end;
end; {map}
function empty(x,y:integer; maze:mazetype):boolean;
var i,sum:integer;
begin
sum:=0;
if (x in [1..hsize]) and (y in [1..vsize]) then begin
empty:=(maze[x,y]=$ff);
end else empty:=false;
end;
procedure makedoor(var x,y:integer; dir:compass; var maze:mazetype);
begin
maze[x,y]:=maze[x,y] and ($ff xor (1 shl dir));
if dir=2 then begin gotoxy(x*2,y+2); write(' '); end;
if dir=1 then begin gotoxy(x*2+1,y+2); write('_'); end;
move(x,y,dir,x,y);
dir:=(dir+2) mod points;
maze[x,y]:=maze[x,y] and ($ff xor (1 shl dir));
if dir=2 then begin; gotoxy(x*2,y+2); write(' '); end;
if dir=1 then begin; gotoxy(x*2+1,y+2); write('_'); end;
end; {makedoor}
procedure mazefill(var maze:mazetype);
var
M,x,y,ox,oy:integer;
done:boolean;
d:compass;
filled:integer;
begin
filled:=1;
mazeinit(maze); map(maze,output);
writeln;
x:=random(hsize)+1;
y:=random(vsize)+1;
help;
repeat {fill}
ox:=x; oy:=y; {save x,y}
repeat {advance}
d:=random(cpoints);
done:=false;
for m:=0 to cpoints do
begin
move(ox,oy,(d+m) mod points,x,y);
if empty(x,y,maze) and not(done) then
begin
done:=true;
filled:=filled+1;
makedoor(ox,oy,(d+m) mod points,maze);
end
end;
until not done;
d:=0; x:=ox; y:=oy;
repeat {retreat}
done:=false;
for m:=3 to 7 do {find an opening}
if not bit(maze[x,y],(D+M) mod points) and not done then
begin
done:=true;
d:=(d+m) mod points;
move(x,y,d,x,y);
write(CHR(27),'=',CHR(33+y),CHR(31+x*2));
end;
if not done then write('error in retreat');
done:=false;
for m:=0 to 3 do {is there a free space near?}
begin
move(x,y,m,ox,oy);
if empty(ox,oy,maze) then done:=true;
end;
until done or (filled=hsize*vsize);
until filled=hsize*vsize;
for ox:=0 to (hsize+vsize) do begin
d:=random(points);
x:=random(hsize-2)+2;
y:=random(vsize-2)+2;
move(x,y,d,x,y);
if (x in [1..hsize]) and (y in [1..vsize]) then
makedoor(x,y,(d+2) mod points,maze);
end;
repeat
help;
delay(500);
until keypressed;
end; {mazefill}
Function ISSET(VAR SSET:BOOLEAN; C:CHAR):char;
BEGIN
IF SSET THEN ISSET:=(C) ELSE ISSET:=' ';
END;
procedure out(num:integer; sset:boolean);
var i,j:integer;
begin
for i:=1 to length(l[num]) do BEGIN
case l[num][i] of
#0..#31: begin
cur:=80*ord(l[num][i])+ord(l[num][i-1]);
end;
'J': cur:=cur+80;
'R': cur:=cur+78;
'=': begin
gotoxy(cur mod 80,cur div 80);
write(ISSET(sset,'+'));
end;
#100..#199:begin
gotoxy(cur mod 80, cur div 80);
for j:=1 to ord(l[num][i])-100 do begin
write(isset(sset,'-'));
cur:=cur+1;
end;
end;
#200..#299:
for j:=1 to ord(l[num][i])-200 do begin
gotoxy(cur mod 80, cur div 80);
write(isset(sset,'|'));
cur:=cur+80;
end;
else begin
gotoxy(cur mod 80,cur div 80);
write(isset(sset,l[num][i]));
cur:=cur+1;
end;
end;
END;
end;
{{{{{{{{{{{{{ This routine is Intertec Superbrain specific
procedure out(num:integer; sset:boolean);
{ Memory mapped video starts at $F800 and proceeds at 80 characters
per line. The screen must first be cleared and then written to each
line (to clear video blanking) The routing actually only used ~ 27
characters on each line.}
{{{{{{{{{{{{{
var i,j:integer;
begin
for i:=1 to length(l[num]) do BEGIN
case l[num][i] of
#0..#31: begin
cur:=$f800+80*ord(l[num][i])+ord(l[num][i-1]);
if (cur < $f800) or (cur > $f800+1920) then
end;
'J': cur:=cur+80;
'R': cur:=cur+78;
'=': mem[cur]:=ISSET(sset,'+');
#100..#199:
for j:=1 to ord(l[num][i])-100 do begin
mem[cur]:=isset(sset,'-');
cur:=cur+1;
end;
#200..#299:
for j:=1 to ord(l[num][i])-200 do begin
mem[cur]:=isset(sset,'|');
cur:=cur+80;
end;
else begin
mem[cur]:=isset(sset,l[num][i]);
cur:=cur+1;
end;
END;
end;
end;
End of Intertec Superbrain routine
{{{{{{{{{{{{{{{}
procedure outr(num:linetype);
begin
if num in liness then begin
liness:=liness-[num];
linesr:=linesr+[num];
out(num,false);
end;
end;
procedure outs(num:linetype);
begin
if num in linesr then begin
linesr:=linesr-[num];
liness:=liness+[num];
out(num,true);
end;
end;
procedure outset(k:boolean; l1,l2:linetype);
begin
if k then begin
outs(l1); outr(l2);
end else begin
outs(l2); outr(l1);
end;
end;
procedure mazeroom(var maze:mazetype; x,y:integer; d:compass);
var i,tx,ty:integer;
begin
outset(bit(maze[x,y],(d+3) mod points),1,0);
outset(bit(maze[x,y],(d+1) mod points),3,2);
outs(15);
if bit(maze[x,y],d) then begin
outs(12);
for i:=4 to 11 do outr(i);
for i:=13 to 14 do outr(i);
for i:=16 to 18 do outr(i);
end else begin
outr(12);
move(x,y,d,tx,ty);
if (tx=gx) and (ty=gy) then begin
gotoxy(14,21);
write('EXIT');
end else begin
gotoxy(14,21);
write(hdata[hmaze[tx,ty]]);
end;
outs(16);
outset(bit(maze[tx,ty],(d+3) mod points),5,4);
outset(bit(maze[tx,ty],(d+1) mod points),7,6);
if bit(maze[tx,ty],d) then begin
outs(13);
for i:=8 to 11 do outr(i);
outr(14); outr(17); outr(18);
end else begin
outr(13);
move(tx,ty,d,tx,ty);
outset(bit(maze[tx,ty],(d+3) mod points),9,8);
outset(bit(maze[tx,ty],(d+1) mod points),11,10);
outset(bit(maze[tx,ty],d),14,18);
outs(17);
end;
end;
end;
procedure mazewander(var maze:mazetype);
var
d:compass;
c:char;
begin
d:=random(points);
liness:=[]; linesr:=[0..18];
repeat
mazeroom(maze,x,y,d);
gotoxy(35,1);
clreol;
write(':');
read(kbd,c);
write(c);
gotoxy(35,2);
write(' ');
case c of
'L','l':d:=(d+3) mod points;
'F','f':if bit(maze[x,y],d) then begin
gotoxy(35,2);
write('OUCH!')
end else move(x,y,d,x,y);
'R','r':d:=(d+1) mod points;
'B','b':d:=(d+2) mod points;
'M','m':if ptr=50 then
write('You are all out of chalk')
else begin
ptr:=ptr+1;
write('Mark what? '^h^h^h^h^h^h);
readln(hdata[ptr]);
hdata[ptr]:=hdata[ptr]+' ';
hmaze[x,y]:=ptr;
end;
end; {case}
until ((x=gx) and (y=gy)) or (c=^^);
end; {maze wander}
procedure init;
begin
{ 0..33 goto (x,y) pair with next byte
J Line feed
R Line feed less two spaces
others 65..99 print as is or as space depending on set or reset
100..199 N-100 horizontal
200..255 N-200 vertical
}
l[00]:=#1#2'--'#1#22'--'; {Left immediate open}
l[01]:=#2#1'\'#2#23'/'; {Left immediate closed}
l[02]:=#27#2'--'#27#22'--'; {Right immediate open}
l[03]:=#27#1'/'#27#23'\'; {Right immediate closed}
l[04]:=#4#6'---'#4#18'---'; {Next left open}
l[05]:=#4#3'\J\J\'#6#19'/R/R/'; {Next left closed}
l[06]:=#23#6'---'#23#18'---'; {Next right open}
l[07]:=#25#3'/R/R/'#23#19'\J\J\'; {Next right closed}
L[08]:=#8#8'-'#8#16'-'; {Last left open}
L[09]:=#8#7'\'#8#17'/'; {Last left closed}
L[10]:=#21#8'-'#21#16'-'; {Last right open}
L[11]:=#21#7'/'#21#17'\'; {Last right closed}
L[12]:=#4#2#122#4#22#122; {Closed immediatly ahead}
L[13]:=#8#6#114#8#18#114; {Closed next ahead}
L[14]:=#10#8#110#10#16#110; {Closed last ahead}
l[15]:=#3#2'=J'#219'=J'#26#2'=J'#219'='; {end of immediate room}
l[16]:=#7#6'=J'#211'=J'#22#6'=J'#211'='; {end of next room}
l[17]:=#9#8'=J'#207'=J'#20#8'=J'#207'='; {end of last room}
l[18]:=#10#9'\'#10#15'/'#19#9'/'#19#15'\';{open all ahead}
ptr:=0;
hint:=0;
end;
begin {main}
init;
mazefill(maze);
read(kbd,c);
if c='P' then map(maze,lst);
clrscr;
for i:=1 to 23 do writeln(' ');
write(' '^h);
mazewander(maze);
clrscr;
writeln('Hurrah! You made it out!');
end. {main}