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
/
MBUG153.ARC
/
LS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1979-12-31
|
14KB
|
489 lines
program LetterShift;
{ programmed by: Konstantin Articus
Gross strasse 21
2250 Husum
West Germany
This game is Public Domain.
You may change it for your own purpose.
last changes: 23.6.1989
Converted from DOS to Microbee CP/M
by A J Laughton on 14th October '90 }
var
again,i,index,indicator,shuffl,OldDir,empty : integer;
finished : boolean;
place : array[1..16] of string[1];
result : array[1..4] of integer;
moves,
number : real;
const
TL = #128; { Top Left Border characters }
TR = #129; { Top Right }
BL = #130; { Bottom Left }
BR = #131; { Bottom Right }
TM = #132; { Top Middle }
BM = #133; { Bottom Middle }
HL = #134; { Horizontal Line }
VL = #135; { Vertical Line }
LM = #136; { Left Middle }
RM = #137; { Right Middle }
Cr = #138; { Center Cross }
Procedure BorderPCGs;
Var
X : integer;
J : byte;
Begin
For x:=$F800 to $F80B do {TLeft}
Begin
Case x of
$F800..$F803 : J:=$00;
$F804 : J:=$0F;
$F805,$F806 : J:=$1F;
$F807 : J:=$1C;
$F808..$F80A : J:=$18;
end;
Mem[x]:=j;
End;
For x:=$F810 to $F81B do {TRight}
Begin
Case x of
$F810..$F813 : J:=$00;
$F814 : J:=$F0;
$F815,$F816 : J:=$F8;
$F817 : J:=$38;
$F818..$F81A : J:=$18;
end;
Mem[x]:=j;
End;
For x:=$f820 to $F82B do {BLeft}
Begin
Case x of
$F820..$F822 : J:=$18;
$F823 : J:=$1C;
$F824,$F825 : J:=$1F;
$F826 : J:=$0F;
$F827..$F82A : J:=$00;
end;
Mem[x]:=j;
End;
For x:=$F830 to $F83B do {BRight}
Begin
Case x of
$F830..$F832 : J:=$18;
$F833 : J:=$38;
$F834,$F835 : J:=$F8;
$F836 : J:=$F0;
$F837..$F83A : J:=$00;
end;
Mem[x]:=j;
End;
For x:=$F840 to $F84B do {TMid}
Begin
Case x of
$F840..$F843 : J:=$00;
$F844 : J:=$81;
$F845 : J:=$E7;
$F846 : J:=$FF;
$F847 : J:=$3C;
$F848..$F84A : J:=$18;
end;
Mem[x]:=j;
End;
For x:=$F850 to $F85B do {BMid}
Begin
Case x of
$F850..$F852 : J:=$18;
$F853 : J:=$3C;
$F854 : J:=$FF;
$F855 : J:=$E7;
$F856 : J:=$81;
$F857..$F85A : J:=$00;
end;
Mem[x]:=j;
End;
For x:=$F860 to $F86B do {HLin}
Begin
Case x of
$F860..$F863 : J:=$00;
$F864..$F866 : J:=$FF;
$F867..$F86B : J:=$00;
end;
Mem[x]:=j;
End;
For x:=$F880 to $F88B do {LMid}
Begin
Case x of
$F880..$F882,$F888..$F88A : J:=$18;
$F883,$F887 : J:=$1C;
$F884,$F886 : J:=$0F;
$F885 : J:=$07;
End;
Mem[x]:=j;
End;
For x:=$F890 to $F89B do {RMid}
Begin
Case x of
$F890..$F892,$F898..$F89A : J:=$18;
$F893,$F897 : J:=$38;
$F894,$F896 : J:=$F0;
$F895 : J:=$E0;
end;
Mem[x]:=j;
End;
For x:=$F870 to $F87B do {VLin}
Mem[x]:=$18;
For x:=$F8A0 to $F8AB do {Cross}
Begin
Case x of
$F8A0..$F8A2,$F8A8..$F8AA : J:=$18;
$F8A3,$F8A7 : J:=$3C;
$F8A4..$F8A6 : J:=$FF;
End;
Mem[x]:=j;
End;
End;
procedure bold;
begin { SCNTOP EQU 0F000H }
{ PCGRAM EQU 0F800H }
{ ROMPORT EQU 0BH }
inline(
$3E/$01/ {BOLD: LD A,1 }
$D3/$0B/ { OUT (ROMPORT),A }
$21/$F000/ { LD HL,SCNTOP }
$11/$F800/ { LD DE,PCGRAM }
$7E/ {BOLD_1: LD A,(HL) }
$07/ { RLCA }
$B6/ { OR (HL) }
$12/ { LD (DE),A }
$23/ { INC HL }
$13/ { INC DE }
$CB/$5C/ { BIT 3,H }
$28/$F6/ { JR Z,BOLD_1 }
$AF/ { XOR A }
$D3/$0B ) { OUT (ROMPORT),A }
end;
procedure Inverse;
begin { SCNTOP EQU 0F000H }
{ PCGRAM EQU 0F800H }
{ ROMPORT EQU 0BH }
{ INVERSE: }
inline($3E/ $01/ { LD A,1 }
$D3/ $0B/ { OUT (ROMPORT),A }
$21/ $F000/ { LD HL,SCNTOP }
$11/ $F800/ { LD DE,PCGRAM }
$7E/ { INV_1: LD A,(HL) }
$2F/ { CPL }
$12/ { LD (DE),A }
$23/ { INC HL }
$13/ { INC DE }
$CB/ $5C/ { BIT 3,H }
$28/ $F7/ { JR Z,INV_1 }
$AF/ { XOR A }
$D3/ $0B ); { OUT (ROMPORT),A }
end;
procedure RestoreAll;
begin
port[$1c] := $80; {Restore PCG Ram to normal inverse chr's}
inverse;
end;
procedure DeleteLine(x,y:integer);
begin
gotoxy(x,y);
for i := 1 to (78-x) do
write(' ');
end;
procedure Border;
var
x,j : integer;
begin
clrscr;
gotoxy(1,1);
write(TL);
for i := 1 to 78 do
write(HL);
write(TR,VL);
for i := 0 to 20 do
begin
gotoxy(80,2+i);
write(VL,VL);
end;
write(#8,BL);
for i := 1 to 78 do
write(HL);
write(BR);
gotoxy(1,1);
end;
procedure ScreenSetUp;
var line,
plus : integer;
begin
gotoxy(19,23);
write(' No. of moves: ',moves:3:0,' ');
gotoxy(32,3);
Lowvideo;
writeln('L E T T E R S H I F T');
Normvideo;
gotoxy(20,5);
writeln(TL,HL,HL,HL,TM,HL,HL,HL,TM,HL,HL,HL,TM,HL,HL,HL,TR);
gotoxy(20,6);
writeln(VL,' ',place[1],' ',VL,' ',place[2],' ',VL,' ',place[3],' ',VL,' ',place[4],' ',VL);
gotoxy(20,7);
writeln(LM,HL,HL,HL,CR,HL,HL,HL,CR,HL,HL,HL,CR,HL,HL,HL,RM);
gotoxy(20,8);
writeln(VL,' ',place[5],' ',VL,' ',place[6],' ',VL,' ',place[7],' ',VL,' ',place[8],' ',VL);
gotoxy(20,9);
writeln(LM,HL,HL,HL,CR,HL,HL,HL,CR,HL,HL,HL,CR,HL,HL,HL,RM);
gotoxy(20,10);
writeln(VL,' ',place[9],' ',VL,' ',place[10],' ',VL,' ',place[11],' ',VL,' ',place[12],' ',VL);
gotoxy(20,11);
writeln(LM,HL,HL,HL,CR,HL,HL,HL,CR,HL,HL,HL,CR,HL,HL,HL,RM);
gotoxy(20,12);
writeln(VL,' ',place[13],' ',VL,' ',place[14],' ',VL,' ',place[15],' ',VL,' ',place[16],' ',VL);
gotoxy(20,13);
writeln(BL,HL,HL,HL,BM,HL,HL,HL,BM,HL,HL,HL,BM,HL,HL,HL,BR);
end;
function PlayAgain:boolean;
var ch : char;
begin
DeleteLine(2,22);
gotoxy(20,21);
LowVideo;
write('Play again ? ');
NormVideo;
repeat
read(kbd,ch);
ch := upcase(ch);
if not (ch in ['Y','N']) then
begin
gotoxy(40,21);
write(#7,'Please press Y or N !');
end;
until ch in ['Y','N'];
DeleteLine(2,18);
DeleteLine(2,21);
if ch = 'N' then
begin
clrscr;
RestoreAll;
Halt;
end;
if ch = 'Y' then
PlayAgain := true
else
PlayAgain := false;
end;
procedure Stop;
begin
index := -1;
gotoxy(20,16);
writeln(#7,'I don`t believe that you can finish the game ! ');
DeleteLine(2,17);
finished := true;
end;
procedure PossibleDirections;
var r : integer;
begin
result[1] := indicator -4;
result[2] := indicator +4;
result[3] := indicator +1;
result[4] := indicator -1;
for r := 1 to 4 do
if (result[r] >16 ) or (result[r] <1) then
result[r]:=-1;
case indicator of
4: result[3] := -1;
5: result[4] := -1;
8: result[3] := -1;
9: result[4] := -1;
12: result[3] := -1;
13: result[4] := -1;
end;
end;
procedure Input;
var
wahl : char;
direction : integer;
begin
repeat
DeleteLine(2,17);
gotoxy(20,16);
LowVideo;
writeln('Which letter should be moved ? (Q = Quit) ');
NormVideo;
repeat
DeleteLine(20,17);
gotoxy(20,17);
read(kbd,wahl);
wahl := upcase(wahl);
DeleteLine(2,18);
if not (wahl in ['Q','A'..'O'] )then
begin
gotoxy(20,18);
write(#7,'Please choose from A up to O or Q ! ');
end;
until wahl in ['Q','A'..'O'] ;
direction := -1;
if wahl = 'Q' then
begin
clrscr;
RestoreAll;
Halt;
end;
for i := 1 to 16 do
if place[i] = wahl then
indicator := i;
PossibleDirections;
for i := 1 to 4 do
if empty = result[i] then
direction := empty;
if direction = -1 then
begin
gotoxy(20,18);
write(#7,'You can`t move that letter yet ! ');
end;
until direction <> -1;
place[direction] := place[indicator];
place[indicator] := ' ';
empty := indicator;
end;
function managed : boolean;
var ready : boolean;
sequence : string[18];
j : integer;
begin
ready := false;
sequence := '';
for j := 1 to 16 do
sequence := sequence + place[j];
if sequence = 'ABCDEFGHIJKLMNO ' then
ready := true;
if ready = true then
begin
gotoxy(20,16); writeln('You managed it ! ');
number := (moves*100)/shuffl;
gotoxy(20,17);
writeln('You needed ',number:1:0,'% of the number of ');
gotoxy(20,18);
writeln('moves the computer used to shuffle ! ');
end;
managed := ready;
end;
procedure schuffle;
var
inp2 : string[5];
inp,full,PossibleDir,code : integer;
wrong : boolean;
begin
gotoxy(20,16); writeln('How many times should I shuffle ?');
DeleteLine(54,16);
repeat
DeleteLine(20,17);
gotoxy(20,17);
readln(inp2);
val(inp2,shuffl,code);
if not ((shuffl>1) and (code=0) and (shuffl <201)) then
begin
DeleteLine(2,18);
DeleteLine(2,19);
gotoxy(20,18);
writeln(#7,'Please input an integer number between 2 and 200 !');
end;
until (shuffl > 1) and (code = 0) and (shuffl < 201);
DeleteLine(2,18);
gotoxy(20,19); writeln('Shuffling - please wait ! ');
for I := 1 to shuffl do
begin
repeat
repeat
wrong := false;
PossibleDir := round(random(4)+1);
if PossibleDir = OldDir then wrong := true;
until wrong = false;
indicator := empty;
PossibleDirections;
until result[PossibleDir] <> -1;
full := result[PossibleDir];
place[empty] := place[full];
place[full] := ' ';
empty := full;
ScreenSetUp;
if PossibleDir = 1 then OldDir := 2;
if PossibleDir = 2 then OldDir := 1;
if PossibleDir = 3 then OldDir := 4;
if PossibleDir = 4 then OldDir := 3;
gotoxy(40,23);
Writeln(i:3,' times shuffled! ');
end;
DeleteLine(2,19);
end;
procedure Initialisation;
begin
if again <> 2 then
begin
LowVideo;
gotoxy(44,6); writeln('Programmed by:');
NormVideo;
gotoxy(44,8); writeln('Konstantin Articus,');
gotoxy(44,9); writeln('West Germany.');
gotoxy(44,11); writeln('Converted to Microbee');
gotoxy(44,12); writeln('by A J Laughton, 1990');
end;
randomize;
OldDir := 0;
for i := 1 to 15 do
begin
place[i] := chr(64+i);
end;
place[16] := ' ';
finished := false;
empty := 16;
index := 0;
moves := 0;
ScreenSetUp;
gotoxy(40,23);
write(0:3,' times shuffled! ');
gotoxy(1,1);
end;
begin {Main Program starts here}
Bold; { Puts BOLD chr's in PCG ram }
BorderPCGs; { Puts Border chr's in PCG ram }
Border; { Draws the Border }
again := 1;
repeat
Initialisation;
again := 2;
schuffle;
repeat
moves := moves + 1;
Input;
if index <> -1 then
begin
ScreenSetUp;
finished := managed;
if moves = 500 then Stop; { If you can't do it in 500 turns ...}
end
else finished := true;
until finished = true;
until PlayAgain = false;
end.