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