home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
turbopas
/
amouse55.zip
/
SQUARE.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1988-02-17
|
7KB
|
253 lines
(*
This program computes a solution to game #5 on a Merlin!
*)
{$M 16300,0,655360}
program ai_1;
uses
crt,mouse,graph;
procedure display(config_num:integer);
var x,y:integer;
begin
y:=0;
for x:=1 to 9 do begin
y:=y+1;
if (config_num and 1)=1
then write('* ')
else write(' ');
if y=3 then begin
writeln;
y:=0
end;
config_num:=config_num shr 1
end
end;
function config_after(config_num,move_num:integer):integer;
begin
case move_num of
1: config_after:=config_num xor 27; { 1 2 4 }
2: config_after:=config_num xor 7; { 8 16 32 }
3: config_after:=config_num xor 54; { 64 128 256 }
4: config_after:=config_num xor 73;
5: config_after:=config_num xor 186;
6: config_after:=config_num xor 292;
7: config_after:=config_num xor 216; (*** 495 ***)
8: config_after:=config_num xor 448;
9: config_after:=config_num xor 432
end
end;
procedure human_plays;
var move_num,config_num : integer;
begin
write('Initial Config # '); readln(config_num);
display(config_num);
while true do begin
write('Move # '); readln(move_num);
config_num:=config_after(config_num,move_num);
writeln('Generates config ',config_num);
display(config_num)
end
end;
type c_or_p = (con,poi);
chain9pointer = ^chain9;
config_or_pointer = record
kind : c_or_p;
config : word;
point : chain9pointer
end;
c_or_p9 = array[1..9] of config_or_pointer;
chain9 = record
nextchain : chain9pointer;
data : c_or_p9
end;
var initial_move : c_or_p9;
procedure create_initial_chain(config_num:integer);
var x:integer;
begin
for x:=1 to 9 do begin
initial_move[x].kind:=con;
initial_move[x].config:=config_after(config_num,x);
if initial_move[x].config=495 then begin
writeln('I got it... just press ',x);
halt
end
end
end;
function is_in(a_chain : c_or_p9):boolean;
var x:integer;
begin
is_in:=false;
for x:=1 to 9 do
if a_chain[x].kind=poi
then if is_in(a_chain[x].point^.data)
then begin
writeln('Middle move ',x);
is_in:=true;
exit
end
else
else if a_chain[x].config=495 then begin
writeln('Final move ',x);
is_in:=true;
exit
end
end;
procedure trace_out;
var x : integer;
begin
for x:=1 to 9 do
if is_in(initial_move[x].point^.data) then begin
writeln('First move ',x);
halt
end;
writeln('Done tracing');
halt
end;
procedure make_a_chain(thechain:chain9pointer;initial_config:integer);
var x: integer;
begin
for x:=1 to 9 do begin
thechain^.data[x].kind:=con;
thechain^.data[x].config:=config_after(initial_config,x);
if thechain^.data[x].config=495 then trace_out
end
end;
var chain_levelptr : array[1..7] of chain9pointer;
procedure make_second_chain(var initial_move : c_or_p9;
level : integer;
var engineptr : chain9pointer;
var cabooseptr : chain9pointer);
var y : integer;
nextchain9,oldchain : chain9pointer;
begin
oldchain:=nil;
for y:=1 to 9 do begin
new(nextchain9);
gotoxy(1,1); writeln(memavail,' ');
nextchain9^.nextchain:=nil;
if oldchain<>nil
then oldchain^.nextchain:=nextchain9
else engineptr:=nextchain9;
oldchain:=nextchain9;
initial_move[y].kind:=poi;
initial_move[y].point:=nextchain9;
cabooseptr:=nextchain9;
make_a_chain(nextchain9,initial_move[y].config)
end
end;
procedure make_third_chain(curr_chain : chain9pointer;level:integer);
var engineptr,cabooseptr,oldcabooseptr : chain9pointer;
begin
while curr_chain<>nil do begin
make_second_chain(curr_chain^.data,level,engineptr,cabooseptr);
if chain_levelptr[level]=nil
then chain_levelptr[level]:=engineptr
else oldcabooseptr^.nextchain:=engineptr;
oldcabooseptr:=cabooseptr;
curr_chain:=curr_chain^.nextchain
end
end;
{ here is a mouse_area array used by calls to mouse_area }
{ You should make the first index as small as needed, but }
{ the function can take up to 100. Note that the last }
{ entry is all zeros }
const
ma : array[1..10,1..4] of word =
( (30,130,30,60) , (160,260,30,60) , (290,390,30,60) ,
(30,130,80,110) , (160,260,80,110) , (290,390,80,110) ,
(30,130,130,160) , (160,260,130,160) , (290,390,130,160) ,
(0,0,0,0) );
procedure read_config(var config_num : integer);
var num_buttons : word;
grDriver,
grMode,
ErrCode : Integer;
button,x,y : word;
label finish;
begin
config_num:=0;
if not mouseparams(num_buttons) then begin { call first to reset }
writeln('Need a mouse for this.'); { the mouse }
halt
end;
grDriver := Detect;
InitGraph(grDriver,grMode,'c:\program\turbopas\bgi');
ErrCode := GraphResult;
if ErrCode = grOk then
begin
for x:= 1 to 9 do rectangle(ma[x,1],ma[x,3],ma[x,2],ma[x,4]);
settextstyle(defaultfont,vertdir,1);
outtextxy(640,20,'Click here when done');
set_speed2(100); { sets the double speed to 100 cps }
mouse_cursor(true); { displays the mouse cursor }
set_mouse_cursor(5,2,hand); { sets the cursor to a hand & hot spots }
while true do begin
while mousebutton=0 do; { mousebutton = 0 if not pressing anything }
if mousex>630 then goto finish; { mousex = x location }
x:=mouse_area(ma); { returns 1 - 9 or 0 if not in any }
if x>0 then begin
config_num:=config_num or (1 shl (x-1));
mouse_cursor(false); { shuts off cursor before drawing over it}
bar(ma[x,1],ma[x,3],ma[x,2],ma[x,4]);
mouse_cursor(true) { turns it back on }
end
end
end
else
WriteLn('Graphics error:',
GraphErrorMsg(ErrCode));
halt;
finish:
closegraph;
end;
var
x,move_num,
config_num : integer;
garbage : chain9pointer;
begin (* 499 - 2 moves , 453 - 3 moves *)
read_config(config_num);
clrscr;
{ if config_num=0 then human_plays;
}
for x:=1 to 7 do chain_levelptr[x]:=nil;
writeln('Move 1');
create_initial_chain(config_num);
writeln('Move 2');
make_second_chain(initial_move,1,chain_levelptr[1],garbage);
for x:=1 to 90 do begin
writeln('Move ',x+2);
make_third_chain(chain_levelptr[x],x+1)
end;
end.