You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
4.0 KiB

Unit moversProc;
Interface
Uses dataUnit;
Procedure moveMovers(Var g: GameState);
Implementation
Function turnMover(c: char; d: integer): char;
Const
period = ord(high(TMoverDir))+1;
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;
Exit(movers[i, TMoverDir(x)]);
End;
Exit(c);
End;
Procedure rotateStep(Var rstep, cstep: integer; clockWise: boolean);
Begin
cstep := cstep + rstep;
rstep := cstep - rstep;
cstep := cstep - rstep;
If clockWise Then
cstep := -cstep
Else
rstep := -rstep;
End;
Procedure moveMover(Var g: GameState; row, col, rstep, cstep: integer);
Var
rns : integer = 0;
cns : integer = 0;
Begin
(* I don't move if I'm cought by a magnet *)
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
g.map[row, col] := turnMover(g.map[row,col], 2);
Exit;
End;
(* Turners turn me *)
Case g.map[row + rstep, col + cstep] Of
'a':
Begin
g.map[row, col] := turnMover(g.map[row,col], 1);
rotateStep(rstep, cstep, True);
End;
'c':
Begin
g.map[row, col] := turnMover(g.map[row,col], -1);
rotateStep(rstep, cstep, False);
End;
End;
(* Simple movement *)
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;
(* 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
g.map[row + 2 * rstep, col + 2 * cstep] := g.map[row + rstep, col + cstep];
g.map[row + rstep, col + cstep] := empty;
End;
g.map[row, col] := turnMover(g.map[row,col], 2);
Exit;
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
rns := 2 * random(1) - 1
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
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
g.map[row + rstep - rns, col + cstep - cns] := g.map[row,col];
g.map[row, col] := empty;
End;
End;
End;
Procedure moveMovers(Var g: GameState);
Var
idx, row, col, Width, Height: integer;
Begin
Width := g.mapWidth;
Height := g.mapHeight;
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
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
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
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
moveMover(g, row, col, 0, 1);
End;
End;
End.