Compare commits

...

2 Commits

  1. 65
      dataUnit.pas
  2. 5
      gameUnit.pas
  3. 8
      heroEnemy.pas
  4. 171
      moversProc.pas
  5. 4
      toolsProc.pas

@ -3,7 +3,7 @@ Unit dataUnit;
Interface
type
Type
TMoverType = (glider, walker, pusher);
TMoverDir = (up, left, down, right);
@ -13,7 +13,18 @@ Const
empty = '.';
man = '&';
gem = '*';
movers : array[TMoverType, TMoverDir] of char =
wall = '#';
wallSlip = '@';
earth = 'H';
boulder = '0';
block = 'M';
magnetx = 'N';
magnety = 'Z';
turnerRight = 'a';
turnerLeft = 'c';
monster = '%';
walkable = [empty,earth,gem];
movers : array[TMoverType, TMoverDir] Of char =
(
('^','>','v','<'),
('u','r','d','l'),
@ -26,11 +37,10 @@ Const
DownMovers = ['d', 'D', 'v'];
LeftMovers = ['l', 'L', '<'];
RightMovers = ['r', 'R', '>'];
walkable = [empty,'H',gem];
magnets = ['N','Z'];
pushable = ['M','0','c','a']
magnets = [magnetx,magnety];
pushable = [block,boulder,turnerLeft,turnerRight]
+ magnets + gliders + walkers + pushers;
slipery = ['@','0',gem] + gliders;
slipery = [wallSlip,boulder,gem] + gliders;
enemies = ['%'];
@ -54,47 +64,47 @@ Type GameState = Record
next : string;
End;
function readLevel(levelFile, levelID:String; var succes: Boolean): GameState;
Function readLevel(levelFile, levelID:String; Var succes: Boolean): GameState;
Implementation
Uses sysutils;
function convert(x: Char):Char;
Function convert(x: Char): Char;
Begin
Case x of
Case x Of
'K': Exit(man);
' ': Exit(empty);
'5': Exit('#');
'1'..'4','6'..'9': Exit('@');
'e': Exit('H');
'b': Exit('M');
's': Exit('Z');
'~','E','C','[': Exit('%');
'B': Exit('0');
else Exit(x);
'5': Exit(wall);
'1'..'4','6'..'9': Exit(wallSlip);
'e': Exit(earth);
'b': Exit(block);
's': Exit(magnety);
'~','E','C','[': Exit(monster);
'B': Exit(boulder);
Else Exit(x);
End;
End;
function readLevel(levelFile, levelID:String; var succes: Boolean): GameState;
Function readLevel(levelFile, levelID:String; Var succes: Boolean): GameState;
Var
aFile: textfile;
thisID: String;
row, col: integer;
x :Char;
x : Char;
Begin
succes := false;
Assign(aFile,levelFile);
Reset(aFile);
readLn(aFile, thisID);
If length(levelID) <> 0 then
repeat
If EOF(aFile) then
If length(levelID) <> 0 Then
Repeat
If EOF(aFile) Then
Exit;
readLn(aFile, thisID);
until compareStr(thisID,levelID) = 0
else
Until compareStr(thisID,levelID) = 0
Else
readLn(aFile, thisID);
readLevel.ID := thisID;
readLn(aFile, readLevel.clue);
@ -115,7 +125,7 @@ Begin
readLevel.manRow := row;
readLevel.manCol := col;
End;
'%':
monster:
Begin
inc (readLevel.numEnemies);
readLevel.enemy[readLevel.numEnemies].col := col;
@ -126,13 +136,12 @@ Begin
End;
readLn(aFile);
End;
If not EOF(aFile) then
If Not EOF(aFile) Then
readLn(aFile,readLevel.next)
else
Else
readLevel.next := '';
Close(aFile);
succes := true;
End;
End.

@ -1,3 +1,4 @@
Unit GameUnit;
Interface
@ -5,7 +6,7 @@ Interface
Uses
dataUnit;
Procedure playLevel(var theGS: dataUnit.GameState);
Procedure playLevel(Var theGS: dataUnit.GameState);
Implementation
@ -31,7 +32,7 @@ Begin
End;
End;
Procedure playLevel(var theGS: dataUnit.GameState);
Procedure playLevel(Var theGS: dataUnit.GameState);
Var
move: boolean;

@ -27,8 +27,8 @@ Begin
(* Move man *)
If move Or (nextTile In walkable) Then
Begin
(* Colect diamonds while where at it *)
If nextTile = '*' Then
(* Colect gems while where at it *)
If nextTile = gem Then
dec(theGS.goal);
(* The moving *)
theGS.map[theGS.manRow, theGS.manCol] := empty;
@ -66,9 +66,9 @@ Begin
For tries := 4 Downto 1 Do
Begin
(* If there's an obstacle. *)
If theGS.map[row+rowstep, col+colstep] <> '.' Then
If theGS.map[row+rowstep, col+colstep] <> empty Then
Begin
If random(1) = 0 then
If random(1) = 0 Then
colstep := -colstep
Else
rowstep := -rowstep;

@ -1,151 +1,154 @@
unit moversProc;
interface
Unit moversProc;
uses dataUnit;
Interface
procedure moveMovers(var g: GameState);
Uses dataUnit;
implementation
Procedure moveMovers(Var g: GameState);
function turnMover(c: char; d: integer): char;
const
Implementation
Function turnMover(c: char; d: integer): char;
Const
period = ord(high(TMoverDir))+1;
var
Var
j, x: integer;
i :TMoverType;
begin
for i := low(TMoverType) to high(TMoverType) do
for j := ord(low(TMoverDir)) to ord(high(TMoverDir)) do
if c = movers[i, TMoverDir(j)] then
begin
x := (j+d) mod period;
i : TMoverType;
Begin
For i := low(TMoverType) To high(TMoverType) Do
For j := ord(low(TMoverDir)) To ord(high(TMoverDir)) Do
If c = movers[i, TMoverDir(j)] Then
Begin
x := (j+d) Mod period;
Exit(movers[i, TMoverDir(x)]);
end;
End;
Exit(c);
end;
End;
procedure rotateStep(var rstep, cstep: integer; clockWise: boolean);
begin
Procedure rotateStep(Var rstep, cstep: integer; clockWise: boolean);
Begin
cstep := cstep + rstep;
rstep := cstep - rstep;
cstep := cstep - rstep;
if clockWise then
If clockWise Then
cstep := -cstep
else
Else
rstep := -rstep;
end;
End;
procedure moveMover(var g: GameState; row, col, rstep, cstep: integer);
var
Procedure moveMover(Var g: GameState; row, col, rstep, cstep: integer);
Var
rns : integer = 0;
cns : integer = 0;
begin
Begin
(* I don't move if I'm cought by a magnet *)
If (rstep <> 0) and (g.map[row - rstep, col] = 'Z') then Exit;
If (cstep <> 0) and (g.map[row, col - cstep] = 'N') then Exit;
If (rstep <> 0) And (g.map[row - rstep, col] = magnety) Then Exit;
If (cstep <> 0) And (g.map[row, col - cstep] = magnetx) Then Exit;
(* I don't move beyond the map *)
if (col + cstep > g.mapWidth) or (col + cstep < 1) or
(row + rstep > g.mapHeight) or (row + rstep < 1) then
begin
if g.map[row,col] in pushers then
If (col + cstep > g.mapWidth) Or (col + cstep < 1) Or
(row + rstep > g.mapHeight) Or (row + rstep < 1) Then
Begin
If g.map[row,col] In pushers Then
g.map[row, col] := turnMover(g.map[row,col], 2);
Exit;
end;
End;
(* Turners turn me *)
case g.map[row + rstep, col + cstep] of
Case g.map[row + rstep, col + cstep] Of
'a':
begin
Begin
g.map[row, col] := turnMover(g.map[row,col], 1);
rotateStep(rstep, cstep, True);
end;
End;
'c':
begin
Begin
g.map[row, col] := turnMover(g.map[row,col], -1);
rotateStep(rstep, cstep, False);
end;
end;
End;
End;
(* Simple movement *)
if g.map[row + rstep, col + cstep] = empty then
begin
If g.map[row + rstep, col + cstep] = empty Then
Begin
g.map[row + rstep, col + cstep] := g.map[row,col];
g.map[row, col] := empty;
Exit;
end;
End;
(* Pushers turn around and push pushables *)
if (g.map[row,col] in pushers) then
begin
if (g.map[row + rstep, col + cstep] in pushable) and
(g.map[row + 2 * rstep, col + 2 * cstep] = empty) then
begin
If (g.map[row,col] In pushers) Then
Begin
If (g.map[row + rstep, col + cstep] In pushable) And
(g.map[row + 2 * rstep, col + 2 * cstep] = empty) Then
Begin
g.map[row + 2 * rstep, col + 2 * cstep] := g.map[row + rstep, col + cstep];
g.map[row + rstep, col + cstep] := empty;
end;
End;
g.map[row, col] := turnMover(g.map[row,col], 2);
Exit;
end;
End;
(* Gliders slip on slipery things*)
if (g.map[row,col] in gliders) and
(g.map[row + rstep, col + cstep] in slipery) then
begin
if cstep <> 0 then
If (g.map[row,col] In gliders) And
(g.map[row + rstep, col + cstep] In slipery) Then
Begin
If cstep <> 0 Then
rns := 2 * random(1) - 1
else
Else
cns := 2 * random(1) - 1;
if (g.map[row + rns, col + cns] = empty) and
(g.map[row + rstep + rns, col + cstep + cns] = empty) then
begin
If (g.map[row + rns, col + cns] = empty) And
(g.map[row + rstep + rns, col + cstep + cns] = empty) Then
Begin
g.map[row + rstep + rns, col + cstep + cns] := g.map[row,col];
g.map[row, col] := empty;
end
else if (g.map[row - rns, col - cns] = empty) and
(g.map[row + rstep - rns, col + cstep - cns] = empty) then
begin
End
Else If (g.map[row - rns, col - cns] = empty) And
(g.map[row + rstep - rns, col + cstep - cns] = empty) Then
Begin
g.map[row + rstep - rns, col + cstep - cns] := g.map[row,col];
g.map[row, col] := empty;
end;
end;
end;
End;
End;
End;
procedure moveMovers(var g: GameState);
Procedure moveMovers(Var g: GameState);
var
Var
idx, row, col, Width, Height: integer;
begin
Begin
Width := g.mapWidth;
Height := g.mapHeight;
for idx := 0 to Height * Width - 1 do
begin
For idx := 0 To Height * Width - 1 Do
Begin
(* for up movers *)
row := idx div Width + 1;
col := idx mod Width + 1;
if (g.map[row, col] in UpMovers) then
row := idx Div Width + 1;
col := idx Mod Width + 1;
If (g.map[row, col] In UpMovers) Then
moveMover(g, row, col, -1, 0);
(* for left movers *)
col := idx div Height + 1;
row := idx mod Height + 1;
if (g.map[row, col] in LeftMovers) then
col := idx Div Height + 1;
row := idx Mod Height + 1;
If (g.map[row, col] In LeftMovers) Then
moveMover(g, row, col, 0, -1);
(* for down movers *)
row := Height - idx div Width + 1;
col := Width - idx mod Width + 1;
if (g.map[row, col] in DownMovers) then
row := Height - idx Div Width + 1;
col := Width - idx Mod Width + 1;
If (g.map[row, col] In DownMovers) Then
moveMover(g, row, col, 1, 0);
(* for Right movers *)
col := Width - idx div Height + 1;
row := Height - idx mod Height + 1;
if (g.map[row, col] in RightMovers) then
col := Width - idx Div Height + 1;
row := Height - idx Mod Height + 1;
If (g.map[row, col] In RightMovers) Then
moveMover(g, row, col, 0, 1);
end;
end;
end.
End;
End;
End.

@ -31,8 +31,8 @@ Begin
For col := 1 To g.mapWidth Do
Begin
Case g.map[row,col] Of
'N': cstep := 1;
'Z': rstep := 1;
magnetx: cstep := 1;
magnety: rstep := 1;
Else continue;
End;
For i := 0 To 1 Do

Loading…
Cancel
Save