home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
mbug
/
mbug165.arc
/
MAZEEDIT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1979-12-31
|
14KB
|
419 lines
program mazesolver;
{.PL65}
{$C-,I-}
const
Xmax = 39;
Ymax = 23;
downwall : byte = 2;
leftwall : byte = 4;
exit : boolean = false;
wallgraphics : array [0..95] of byte
= (0,0,0,0,0,0,0,0,0,0,$FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$FF,0,0,0,0,
0,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$FF,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,$FF,0,0,0,0,0);
pointergraphics : array [0..31] of byte
= (0,0,0,3,2,2,3,0,0,0,0,0,0,0,0,0,0,0,0,$E0,$20,$20,$E0,0,0,0,0,0,0,
0,0,0);
type
ways = (still,up,down,left,right);
Xcoords = 1..Xmax;
Ycoords = 1..Ymax;
track = record
X : Xcoords;
Y : Ycoords;
end;
trackpointer = ^track;
var
maze : array [Xcoords,Ycoords] of byte;
mazefile : file of byte;
Xpos : Xcoords;
Ypos : Ycoords;
trackpos,checkpos,bottomofheap : trackpointer;
Gcharnum,wallnumber : byte;
mempos : integer;
key : char;
mazesolved : boolean;
procedure loadgraphics;
begin
inline ($21/0/$F8/ {LD HL,F800H}
$36/0/ {C:LD (HL),0}
$23/ {INC HL}
$7C/ {LD A,H}
$B5/ {OR L}
$20/$F9/ {JR NZ,C:}
$21/wallgraphics/ {LD HL,wallgraphics}
$11/$20/$F8/ {LD DE,F820H}
$01/$60/0/ {LD BC,6*16}
$ED/$B0/ {LDIR}
$21/wallgraphics/ {LD HL,wallgraphics}
$11/$A0/$F8/ {LD DE,F8A0H}
$01/$60/0/ {LD BC,6*16}
$ED/$B0/ {LDIR}
$0E/4/ {LD C,4}
$11/$80/$F8/ {LD DE,F880H}
$21/pointergraphics/ {A:LD HL,pointergraphics}
$06/32/ {LD B,32}
$1A/ {B:LD A,(DE)}
$B6/ {OR (HL)}
$12/ {LD (DE),A}
$23/ {INC HL}
$13/ {INC DE}
$10/$F9/ {DJNZ B:}
$0D/ {DEC C}
$20/$F1); {JR NZ,A:}
end;
procedure loadinverse; external $E02A;
procedure writemaze;
begin
clrscr;
loadgraphics;
for mempos:=$F001 to $F04E do mem[mempos]:=130;
mempos:=$F051;
for Ypos:=1 to Ymax do
begin
for Xpos:=1 to Xmax do
begin
Gcharnum:=128+maze[Xpos,Ypos];
mem[mempos]:=Gcharnum;
mem[succ(mempos)]:=succ(Gcharnum);
mempos:=mempos+2;
end;
mempos:=mempos+2;
end;
mempos:=$F09F;
repeat
mem[mempos]:=132;
mempos:=mempos+80;
until mempos=$F7CF;
end;
function confirm:boolean;
begin
write(^M^J^I^I'Are you sure (Y/N) ? ');
repeat
read(kbd,key);
key:=upcase(key);
until key in ['N','Y'];
write(key,' ');
delay(500);
confirm:=(key='Y');
end;
procedure killmaze;
begin
for Ypos:=1 to Ymax do
for Xpos:=1 to Xmax do
begin
wallnumber:=0;
if Ypos=Ymax then wallnumber:=downwall;
if Xpos=1 then wallnumber:=wallnumber or leftwall;
maze[Xpos,Ypos]:=wallnumber;
end;
mazesolved:=false;
end;
procedure pointXY(setpoint:boolean);
begin
mempos:=$EFFF+Ypos*80+Xpos+Xpos;
if setpoint then
begin
mem[mempos]:=mem[mempos] or 8;
mem[succ(mempos)]:=mem[succ(mempos)] or 8;
end
else begin
mem[mempos]:=mem[mempos] and $F7;
mem[succ(mempos)]:=mem[succ(mempos)] and $F7;
end
end;
procedure getfilename;
var
inputfilename : string[10];
begin
inputfilename:='';
write(^M^J'Enter file name (8 letters & optional drivecode,');
write(' <ESC> to quit) - ');
repeat
repeat
read(kbd,key);
key:=upcase(key);
until key in [^M,^[,'0'..'9',':','A'..'Z',#127];
if key>' ' then
if (key=#127) and (length(inputfilename)<>0) then
begin mem[addr(inputfilename)]:=length(inputfilename)-1;
gotoXY(67,23); write(inputfilename,' ',^H); end
else if (key<>#127) and
(((key=':') and (length(inputfilename)=1)) or
((key<>':') and ((length(inputfilename)<8) or
(length(inputfilename)<10) and (inputfilename[2]=':')))) then
begin write(key);
inputfilename:=inputfilename+key; end;
until key in [^M,^[];
if key=^M then
begin
write('.MAZ');
assign(mazefile,inputfilename+'.MAZ');
end;
end;
procedure waitforESC;
begin
repeat read(kbd,key); until key=^[;
end;
procedure editmaze;
procedure invertwall(whichwall:ways);
var
tempXpos : Xcoords;
tempYpos : Ycoords;
begin
tempXpos:=Xpos;
tempYpos:=Ypos;
wallnumber:=leftwall;
case whichwall of
up : begin tempYpos:=pred(Ypos); wallnumber:=downwall; end;
down : wallnumber:=downwall;
left : ;
right : tempXpos:=succ(Xpos);
end;
mempos:=$EFFF+tempYpos*80+tempXpos shl 1;
maze[tempXpos,tempYpos]:=maze[tempXpos,tempYpos] xor wallnumber;
mem[mempos]:=mem[mempos] xor wallnumber;
mem[succ(mempos)]:=mem[succ(mempos)] xor wallnumber;
end;
begin
writemaze;
Xpos:=1;
Ypos:=1;
pointXY(true);
repeat
read(kbd,key);
key:=upcase(key);
case key of
'I' : if Ypos>1 then invertwall(up);
'M' : if Ypos<Ymax then invertwall(down);
'J' : if Xpos>1 then invertwall(left);
'K' : if Xpos<Xmax then invertwall(right);
else if key in ['W','Z','A','S'] then
begin
pointXY(false);
case key of
'W' : if Ypos>1 then Ypos:=pred(Ypos);
'Z' : if Ypos<Ymax then Ypos:=succ(Ypos);
'A' : if Xpos>1 then Xpos:=pred(Xpos);
'S' : if Xpos<Xmax then Xpos:=succ(Xpos);
end;
pointXY(true);
end;
end;
until key=^[;
mazesolved:=false;
end;
procedure loadmaze;
begin
getfilename;
if key<>^[ then
begin
reset(mazefile);
if IOresult=0 then
begin
for Ypos:=1 to Ymax do
for Xpos:=1 to Xmax do
read(mazefile,maze[Xpos,Ypos]);
mazesolved:=false;
close(mazefile);
end
else begin
write(^I^I'File does not exist. Press <ESC>. ');
waitforESC;
end;
end;
end;
procedure savemaze;
begin
getfilename;
if key=^M then
begin
rewrite(mazefile);
for Ypos:=1 to Ymax do
for Xpos:=1 to Xmax do
write(mazefile,maze[Xpos,Ypos]);
close(mazefile);
end;
end;
procedure solvemaze;
var
thisway : ways;
solutionfound,finished : boolean;
begin
writemaze;
thisway:=right;
Xpos:=1; Ypos:=1;
pointXY(true);
release(bottomofheap);
new(trackpos);
trackpos^.X:=Xpos; trackpos^.Y:=Ypos;
repeat
case thisway of
up : if ((maze[succ(Xpos),Ypos] and leftwall)=0) and
(Xpos<>Xmax) then
begin Xpos:=succ(Xpos); thisway:=right; end
else if ((maze[Xpos,pred(Ypos)] and downwall)>0) or
(Ypos=1) then
thisway:=left
else Ypos:=pred(Ypos);
down : if ((maze[Xpos,Ypos] and leftwall)=0) and (Xpos<>1) then
begin Xpos:=pred(Xpos); thisway:=left; end
else if ((maze[Xpos,Ypos] and downwall)>0) then
thisway:=right
else Ypos:=succ(Ypos);
left : if ((maze[Xpos,pred(Ypos)] and downwall)=0) and
(Ypos<>1) then
begin Ypos:=pred(Ypos); thisway:=up; end
else if ((maze[Xpos,Ypos] and leftwall)>0) then
thisway:=down
else Xpos:=pred(Xpos);
right : if ((maze[Xpos,Ypos] and downwall)=0) and (Ypos<>Ymax) then
begin Ypos:=succ(Ypos); thisway:=down; end
else if ((maze[succ(Xpos),Ypos] and leftwall)>0) or
(Xpos=Xmax) then
thisway:=up
else Xpos:=succ(Xpos);
end;
solutionfound:=(Xpos=Xmax) and (Ypos=Ymax);
finished:=solutionfound or (Xpos=1) and (Ypos=1) and (thisway=left);
new(trackpos);
trackpos^.X:=Xpos;
trackpos^.Y:=Ypos;
pointXY(true);
if not finished then
begin
checkpos:=bottomofheap;
while (checkpos^.X<>Xpos) and (checkpos^.Y<>Ypos) do
checkpos:=ptr(ord(checkpos)+2);
trackpos:=checkpos;
end;
until finished;
if solutionfound then
begin write(^G); mazesolved:=true; end
else begin
gotoXY(24,1);
write(^G'** This maze has no solution. **'#130);
end;
waitforESC;
end;
procedure displaysolution;
begin
if not mazesolved then
write(^M^J^I^I'Maze has not been solved. Press <ESC>. ')
else begin
writemaze;
release(bottomofheap);
trackpos:=bottomofheap;
repeat
Xpos:=trackpos^.X;
Ypos:=trackpos^.Y;
pointXY(true);
trackpos:=ptr(ord(trackpos)+2);
until (Xpos=Xmax) and (Ypos=Ymax);
write(^G);
end;
waitforESC;
end;
procedure printmaze;
const
preline : string [23] = ' '^[#42#5#57#1;
var
prtnum1,prtnum2 : byte;
i : integer;
begin
write(^M^J^I'Press <RETURN> when printer ready, or <ESC> to quit. ');
repeat read(kbd,key); until key in [^M,^[];
if key=^M then
begin
write(lst,^M^J^[#65#8);
write(lst,preline);
for i:=1 to 313 do write(lst,#1);
write(lst,^M^J' START -->'^M);
for Ypos:=1 to Ymax do
begin
write(lst,preline);
for Xpos:=1 to Xmax do
begin
prtnum1:=0; prtnum2:=0;
if ((maze[Xpos,Ypos] and leftwall)>0) or
(Xpos=1) then
prtnum1:=255;
if ((maze[Xpos,Ypos] and downwall)>0) or
(Ypos=Ymax) then
begin
prtnum1:=1 or prtnum1;
prtnum2:=1;
end;
write(lst,chr(prtnum1));
for i:=1 to 7 do write(lst,chr(prtnum2));
end;
if Ypos=Ymax then writeln(lst,#255' <-- FINISH')
else writeln(lst,#255);
end;
writeln(lst,^[#50);
end;
end;
procedure helpscreen;
begin
end;
begin
killmaze;
mark(bottomofheap);
repeat
clrscr;
loadinverse;
writeln;
writeln(^I^I^I^H^H'+------------------------------+');
writeln(^I^I^I^H^H'| |');
writeln(^I^I^I^H^H'| MAZE SOLVING PROGRAM |');
writeln(^I^I^I^H^H'| |');
writeln(^I^I^I^H^H'+------------------------------+'^M^J^J);
writeln(^I^I^I^I^H^H'MAIN OPTION MENU');
writeln(^I^I^I' ========================'^M^J);
writeln(^I^I^I' 1. Edit maze.');
writeln(^I^I^I' 2. Load maze from disk.');
writeln(^I^I^I' 3. Save maze to disk.');
writeln(^I^I^I' 4. Erase maze.');
writeln(^I^I^I' 5. Create solution path.');
writeln(^I^I^I' 6. Display solution path.');
writeln(^I^I^I' 7. Print maze on printer.');
writeln(^I^I^I' 8. Display help screen.');
writeln(^I^I^I' 9. Quit program.'^M^J);
write(^I^I'Select option (1-9) - ');
repeat
read(kbd,key);
until key in ['1'..'9'];
write(key,' ');
delay(500);
case key of
'1' : editmaze;
'2' : loadmaze;
'3' : savemaze;
'4' : if confirm then killmaze;
'5' : solvemaze;
'6' : displaysolution;
'7' : printmaze;
'8' : helpscreen;
'9' : exit:=confirm;
end;
until exit;
clrscr;
end.