parent
9c9cb28d5f
commit
76c8f1f5cb
2 changed files with 241 additions and 0 deletions
@ -0,0 +1,138 @@ |
|||||||
|
|
||||||
|
Unit dataUnit; |
||||||
|
|
||||||
|
Interface |
||||||
|
|
||||||
|
type |
||||||
|
TMoverType = (glider, walker, pusher); |
||||||
|
TMoverDir = (up, left, down, right); |
||||||
|
|
||||||
|
Const |
||||||
|
maxHeight = 20; |
||||||
|
maxWidth = 40; |
||||||
|
empty = '.'; |
||||||
|
man = '&'; |
||||||
|
gem = '*'; |
||||||
|
movers : array[TMoverType, TMoverDir] of char = |
||||||
|
( |
||||||
|
('^','>','v','<'), |
||||||
|
('u','r','d','l'), |
||||||
|
('U','R','D','L') |
||||||
|
); |
||||||
|
gliders = ['^','>','v','<']; |
||||||
|
walkers = ['u','r','d','l']; |
||||||
|
pushers = ['U','R','D','L']; |
||||||
|
UpMovers = ['u', 'U', '^']; |
||||||
|
DownMovers = ['d', 'D', 'v']; |
||||||
|
LeftMovers = ['l', 'L', '<']; |
||||||
|
RightMovers = ['r', 'R', '>']; |
||||||
|
walkable = [empty,'H',gem]; |
||||||
|
magnets = ['N','Z']; |
||||||
|
pushable = ['M','0','c','a'] |
||||||
|
+ magnets + gliders + walkers + pushers; |
||||||
|
slipery = ['@','0',gem] + gliders; |
||||||
|
enemies = ['%']; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Type Position = Record |
||||||
|
col: integer; |
||||||
|
row: integer; |
||||||
|
End; |
||||||
|
|
||||||
|
Type GameState = Record |
||||||
|
ID : string; |
||||||
|
map : array [1..maxHeight, 1..maxWidth] Of char; |
||||||
|
mapHeight : integer; |
||||||
|
mapWidth : integer; |
||||||
|
manRow : integer; |
||||||
|
manCol : integer; |
||||||
|
goal : integer; |
||||||
|
enemy : array [1..10] Of Position; |
||||||
|
numEnemies : integer; |
||||||
|
clue : string; |
||||||
|
next : string; |
||||||
|
End; |
||||||
|
|
||||||
|
function readLevel(levelFile, levelID:String; var succes: Boolean): GameState; |
||||||
|
|
||||||
|
Implementation |
||||||
|
|
||||||
|
Uses sysutils; |
||||||
|
|
||||||
|
function convert(x: Char):Char; |
||||||
|
Begin |
||||||
|
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); |
||||||
|
End; |
||||||
|
End; |
||||||
|
|
||||||
|
function readLevel(levelFile, levelID:String; var succes: Boolean): GameState; |
||||||
|
|
||||||
|
Var |
||||||
|
aFile: textfile; |
||||||
|
thisID: String; |
||||||
|
row, col: integer; |
||||||
|
x :Char; |
||||||
|
Begin |
||||||
|
succes := false; |
||||||
|
Assign(aFile,levelFile); |
||||||
|
Reset(aFile); |
||||||
|
readLn(aFile, thisID); |
||||||
|
If length(levelID) <> 0 then |
||||||
|
repeat |
||||||
|
If EOF(aFile) then |
||||||
|
Exit; |
||||||
|
readLn(aFile, thisID); |
||||||
|
until compareStr(thisID,levelID) = 0 |
||||||
|
else |
||||||
|
readLn(aFile, thisID); |
||||||
|
readLevel.ID := thisID; |
||||||
|
readLn(aFile, readLevel.clue); |
||||||
|
readLn(aFile); |
||||||
|
readLevel.mapHeight := 20; |
||||||
|
readLevel.mapWidth := 30; |
||||||
|
readLevel.numEnemies := 0; |
||||||
|
readLevel.goal := 0; |
||||||
|
For row := 1 To readLevel.mapHeight Do |
||||||
|
Begin |
||||||
|
For col:= 1 To readLevel.mapWidth Do |
||||||
|
Begin |
||||||
|
read(aFile, x); |
||||||
|
readLevel.map[row,col] := convert(x); |
||||||
|
Case readLevel.map[row,col] Of |
||||||
|
man: |
||||||
|
Begin |
||||||
|
readLevel.manRow := row; |
||||||
|
readLevel.manCol := col; |
||||||
|
End; |
||||||
|
'%': |
||||||
|
Begin |
||||||
|
inc (readLevel.numEnemies); |
||||||
|
readLevel.enemy[readLevel.numEnemies].col := col; |
||||||
|
readLevel.enemy[readLevel.numEnemies].row := row; |
||||||
|
End; |
||||||
|
gem: inc(readLevel.goal); |
||||||
|
End; |
||||||
|
End; |
||||||
|
readLn(aFile); |
||||||
|
End; |
||||||
|
If not EOF(aFile) then |
||||||
|
readLn(aFile,readLevel.next) |
||||||
|
else |
||||||
|
readLevel.next := ''; |
||||||
|
Close(aFile); |
||||||
|
succes := true; |
||||||
|
End; |
||||||
|
|
||||||
|
End. |
||||||
|
|
@ -0,0 +1,103 @@ |
|||||||
|
|
||||||
|
Unit heroEnemy; |
||||||
|
|
||||||
|
Interface |
||||||
|
|
||||||
|
Uses dataUnit, Math; |
||||||
|
|
||||||
|
Procedure moveMan(Var theGS:GameState;rowStep,colStep:integer); |
||||||
|
Procedure moveEnemies(Var theGS:GameState); |
||||||
|
|
||||||
|
Implementation |
||||||
|
|
||||||
|
Procedure moveMan(Var theGS:GameState;rowStep,colStep:integer); |
||||||
|
|
||||||
|
Var |
||||||
|
move: boolean = false; |
||||||
|
nextTile: char; |
||||||
|
Begin |
||||||
|
nextTile := theGS.map[theGS.manRow+rowStep, theGS.manCol+colStep]; |
||||||
|
(* Push the boulder *) |
||||||
|
If (nextTile In pushable) And |
||||||
|
(theGS.map[theGS.manRow+2*rowStep, theGS.manCol+2*colStep] = empty) Then |
||||||
|
Begin |
||||||
|
theGS.map[theGS.manRow+2*rowStep, theGS.manCol+2*colStep] := nextTile; |
||||||
|
move := true; |
||||||
|
End; |
||||||
|
(* Move man *) |
||||||
|
If move Or (nextTile In walkable) Then |
||||||
|
Begin |
||||||
|
(* Colect diamonds while where at it *) |
||||||
|
If nextTile = '*' Then |
||||||
|
dec(theGS.goal); |
||||||
|
(* The moving *) |
||||||
|
theGS.map[theGS.manRow, theGS.manCol] := empty; |
||||||
|
theGS.manRow := theGS.manRow + rowStep; |
||||||
|
theGS.manCol := theGS.manCol + colStep; |
||||||
|
theGS.map[theGS.manRow, theGS.manCol] := man; |
||||||
|
End; |
||||||
|
End; |
||||||
|
|
||||||
|
|
||||||
|
Procedure moveEnemies(Var theGS:GameState); |
||||||
|
|
||||||
|
Var |
||||||
|
i, row, col, rowstep, colstep, tries: integer; |
||||||
|
Begin |
||||||
|
For i := 1 To theGS.numEnemies Do |
||||||
|
Begin |
||||||
|
col := theGS.enemy[i].col; |
||||||
|
row := theGS.enemy[i].row; |
||||||
|
rowstep := theGS.manRow - row; |
||||||
|
colstep := theGS.manCol - col; |
||||||
|
(* Figures out general direction. *) |
||||||
|
If abs(rowstep) > abs(colstep) Then |
||||||
|
colstep := 0 |
||||||
|
Else If abs(colstep) > abs(rowstep) Then |
||||||
|
rowstep := 0 |
||||||
|
Else If random(2) = 0 Then |
||||||
|
rowstep := 0 |
||||||
|
Else |
||||||
|
colstep := 0; |
||||||
|
(* Restrict movement to vecinity. *) |
||||||
|
rowstep := min(max(-1,rowstep),1); |
||||||
|
colstep := min(max(-1,colstep),1); |
||||||
|
(* Try to move there. *) |
||||||
|
For tries := 4 Downto 1 Do |
||||||
|
Begin |
||||||
|
(* If there's an obstacle. *) |
||||||
|
If theGS.map[row+rowstep, col+colstep] <> '.' Then |
||||||
|
Begin |
||||||
|
If random(1) = 0 then |
||||||
|
colstep := -colstep |
||||||
|
Else |
||||||
|
rowstep := -rowstep; |
||||||
|
If tries Mod 2 = 0 Then |
||||||
|
Begin |
||||||
|
(* Ol' swap trick *) |
||||||
|
colstep := colstep + rowstep; |
||||||
|
rowstep := colstep - rowstep; |
||||||
|
colstep := colstep - rowstep; |
||||||
|
End |
||||||
|
End |
||||||
|
Else |
||||||
|
Begin |
||||||
|
(* Move the enemy. *) |
||||||
|
theGS.map[row+rowstep, col+colstep] := theGS.map[row,col]; |
||||||
|
theGS.map[row,col] := empty; |
||||||
|
col := col+colstep; |
||||||
|
row := row+rowstep; |
||||||
|
theGS.enemy[i].col := col; |
||||||
|
theGS.enemy[i].row := row; |
||||||
|
(* Attack man *) |
||||||
|
If abs(col-theGS.manCol) + abs(row-theGS.manRow) <= 1 Then |
||||||
|
Begin |
||||||
|
theGS.goal := -1; |
||||||
|
End; |
||||||
|
break; |
||||||
|
End; |
||||||
|
End; |
||||||
|
End; |
||||||
|
End; |
||||||
|
|
||||||
|
End. |
Loading…
Reference in new issue