parent
636b5e0172
commit
9c9cb28d5f
5 changed files with 499 additions and 0 deletions
@ -0,0 +1,61 @@ |
||||
|
||||
Program Boulderman; |
||||
|
||||
Uses |
||||
crt, |
||||
Math, |
||||
gameUnit, |
||||
dataUnit; |
||||
|
||||
Var |
||||
filePath: String; |
||||
levelID: String; |
||||
theGS: GameState; |
||||
valid: boolean; |
||||
levelFound: boolean = true; |
||||
Begin |
||||
clrscr; |
||||
writeLn('<<< Boulderman >>'); |
||||
If paramCount < 1 Then |
||||
Begin |
||||
filePath := './intro.kye'; |
||||
writeLn('This is the introductory level set.'); |
||||
writeLn('Play another level set by calling the game'); |
||||
writeLn('with the path to the new level set file.'); |
||||
End |
||||
Else |
||||
filePath := paramStr(1); |
||||
Repeat |
||||
writeLn('--- Menu ---'); |
||||
writeLn('p -> Play'); |
||||
writeLn('j -> Jump to level'); |
||||
writeLn('q -> Quit'); |
||||
repeat |
||||
valid := true; |
||||
Case readKey Of |
||||
'p': levelID := ''; |
||||
'j': Begin |
||||
writeLn('What is the level name?'); |
||||
readLn(levelID); |
||||
End; |
||||
'q': Exit; |
||||
else valid := false; |
||||
End; |
||||
until valid; |
||||
Repeat |
||||
theGS := readLevel(filePath, UpCase(levelID), levelFound); |
||||
If levelFound then |
||||
begin |
||||
playLevel(theGS); |
||||
levelID := theGS.next; |
||||
end |
||||
else |
||||
begin |
||||
writeLn('!!Level not found.'); |
||||
writeLn('Press ENTER to contiue.'); |
||||
readLn; |
||||
end; |
||||
Until (not levelFound) or (theGS.goal <> 0) or (length(levelID) = 0); |
||||
clrscr; |
||||
Until false; |
||||
End. |
@ -0,0 +1,80 @@ |
||||
Unit GameUnit; |
||||
|
||||
Interface |
||||
|
||||
Uses |
||||
dataUnit; |
||||
|
||||
Procedure playLevel(var theGS: dataUnit.GameState); |
||||
|
||||
Implementation |
||||
|
||||
Uses |
||||
crt, |
||||
Math, |
||||
heroEnemy, |
||||
toolsProc, |
||||
moversProc; |
||||
|
||||
Procedure writeMap(Var theGS: dataUnit.GameState); |
||||
|
||||
Var |
||||
col: integer; |
||||
row: integer; |
||||
Begin |
||||
clrscr; |
||||
For row := 1 To theGS.mapHeight Do |
||||
Begin |
||||
For col := 1 To theGS.mapWidth Do |
||||
Write(theGS.map[row, col]); |
||||
writeln; |
||||
End; |
||||
End; |
||||
|
||||
Procedure playLevel(var theGS: dataUnit.GameState); |
||||
|
||||
Var |
||||
move: boolean; |
||||
Begin |
||||
randomize; |
||||
|
||||
(* Game loop *) |
||||
Repeat |
||||
writeMap(theGS); |
||||
gotoxy(1, theGS.mapHeight + 1); |
||||
writeLn(theGS.ID,' Hint:', theGS.clue); |
||||
gotoxy(theGS.manCol, theGS.manRow); |
||||
(* Player turn *) |
||||
Repeat |
||||
move := True; |
||||
Case readKey Of |
||||
'i': moveMan(theGS, -1, 0); |
||||
'j': moveMan(theGS, 0, -1); |
||||
'k': moveMan(theGS, 1, 0); |
||||
'l': moveMan(theGS, 0, 1); |
||||
' ': ; |
||||
'q': theGS.goal := -1; |
||||
Else |
||||
move := False; |
||||
End; |
||||
Until move; |
||||
(* Update map *) |
||||
doMagnet(theGS); |
||||
moveMovers(theGS); |
||||
moveEnemies(theGS); |
||||
Until theGS.goal <=0; |
||||
(* Win/Lose state *) |
||||
writeMap(theGS); |
||||
gotoxy(theGS.mapWidth Div 2 - 4, theGS.mapHeight Div 2); |
||||
If theGS.goal = 0 Then |
||||
Begin |
||||
Write('You Win!'); |
||||
End |
||||
Else |
||||
Write('You Lose!'); |
||||
gotoxy(1, theGS.mapHeight + 2); |
||||
writeLn('Press ENTER to continue.'); |
||||
readLn; |
||||
End; |
||||
|
||||
End. |
@ -0,0 +1,139 @@ |
||||
6 |
||||
LOGO |
||||
Take the diamond |
||||
Introductory levels follow. Use File > Open to open alternative levels. |
||||
555555555555555555555555555555 |
||||
5 5 |
||||
5 5 |
||||
5 5 |
||||
5 5 |
||||
5 e 5 |
||||
5 e 5 |
||||
5 e 5 |
||||
5 e e 5 |
||||
5 e e 5 |
||||
5 e e e e eee 5 |
||||
5 ee e e e e 5 |
||||
5 e e e e eeeee 5 |
||||
5 e e ee ee e 5 |
||||
5 e e eeee eeee K* 5 |
||||
5 e 5 |
||||
5 e e 5 |
||||
5 eee 5 |
||||
5 5 |
||||
555555555555555555555555555555 |
||||
ROCKIES |
||||
Clear space before the rockfall |
||||
Now an element of danger... |
||||
555555555555555555555555555555 |
||||
5 5*vvvvv*5*vvvvv*5 5 |
||||
5 5vvvvvvv5vvvvvvv5 5 |
||||
5 5vvvvvvv5vvvvvvv5 5 |
||||
5555555vvvvvvv5vvvvvvv55555555 |
||||
5 59vvvvv759vvvvv75 5 |
||||
5 559vvv75559vvv755 5 |
||||
5555555556e4555556e45555555555 |
||||
5 5 5 5 |
||||
5 5veeevevKeveeeve5 5 |
||||
5555555eeveeeeveeeveee55555555 |
||||
5 5ee*eveeeeev*eee5 5 |
||||
5 5eeeeeeevveveeee5 5 |
||||
5555555eeveveeeeeeevee55555555 |
||||
5 5eeee*eee*veeeee5 5 |
||||
5 5eeeveeeeeeeevee5 5 |
||||
5555555evveeeevveeeeee55555555 |
||||
5 5e*eeeeee*eeeeee5 5 |
||||
5 5eeeeeeeeeeeeeee5 5 |
||||
555555555555555555555555555555 |
||||
PACMAN |
||||
Avoid the monsters |
||||
Easy so far |
||||
555555555555555555555555555555 |
||||
5 5 |
||||
5 K 5 |
||||
5 7555555556 7555559 756 5 |
||||
5 5 * 5* *5 5* 5 |
||||
5 5 5 5 5 5 |
||||
5* 5 8 4555553 8 2 5 8 5 |
||||
5 5 5 5 5 5 5 |
||||
5 5 5 5 5 5 5 |
||||
5 2 5 8 45555555 4553 5 5 |
||||
5 5 5 5 *5 5 5 |
||||
5 5 5 [ C 5 2 5 5 |
||||
5 8 5 5 E 5 2 5 |
||||
5 5 5 15555556 2 8 5 |
||||
5 5 5 *5 5 * * 5 |
||||
5 5 *5 5 5 5 |
||||
5 1555556 1556 7553 456 5 |
||||
5 * 5* 5 |
||||
5 *5 5 |
||||
555555555555555555555555555555 |
||||
VAULTS |
||||
Open doors with a magnet |
||||
Now for some basic mechanics |
||||
555555555555555555555555555555 |
||||
5 5* *5 5 |
||||
5 5 vvv 5 5 |
||||
5 5 *8b8* 5 5 |
||||
5 1553b1553 5 |
||||
5 5 |
||||
5 5 |
||||
5 5 |
||||
5 79b79 5 |
||||
5 K 53b15 5 |
||||
5 s 5^^^5 5 |
||||
5 5^^^5 5 |
||||
5 756b455***556b459 5 |
||||
5 5*****5***5*****5 5 |
||||
5 15555555555555553 5 |
||||
5 5 |
||||
5 5 |
||||
5 5 |
||||
5 5 |
||||
555555555555555555555555555555 |
||||
FLOW |
||||
Go with the flow. |
||||
Finally, some basic puzzles. |
||||
555555555555555555555555555555 |
||||
55a555555555555555555555555555 |
||||
55 r r a5 |
||||
55 7559*75559 7555559*7559 55 |
||||
55 5555555555 555555555555d55 |
||||
55u15 55 55 55 55 |
||||
55 *5 55K 55 53 55 |
||||
55 75 55 55 5* 55 |
||||
55 55 55 55 59d55 |
||||
55 15 5555555555555555 55 |
||||
55 *5 1555c D155553 55 |
||||
55 75 55 756 l 55 |
||||
55u55 55d5c 755555a55 |
||||
55 55 55 13 4555555555 |
||||
55 55 55 r a5 |
||||
55 5555555555555c55c559*759 55 |
||||
55 13*155553*15555553*15553 55 |
||||
5a l l 55 |
||||
555555555555555555555555555a55 |
||||
555555555555555555555555555555 |
||||
PUZZLER |
||||
Use the free turning block. |
||||
Go to File > Open and select another level to play |
||||
555555555555555555555555555555 |
||||
5 5 * 5* *5 5 |
||||
5 5 5 5 5 |
||||
5 K 5vvvvvvv5 b5 5 |
||||
5 s 59vvvvv75 T b 5 5 |
||||
5 559vvv755 b 5 5 |
||||
5555559 8 75556e4555bbb 5 5 |
||||
5*rrra5 5 5 5 5 5 |
||||
5 d55 5 5 5 5 5 |
||||
5 d55 5 5 ~ b5 5 5 |
||||
5 d15 5 5 b 5 5 5 |
||||
5 L d 5 5 5 b 5vvvvvv5 5 |
||||
55556 2 5B5 b 59vvvvv5 5 |
||||
5 e 5v5bbbbb 559vvv75 5 |
||||
556 459 5v5 b 5556e453 5 |
||||
5b b 5 5v5 b 5 5 |
||||
5 b b5 5v5 b 2 c c5 |
||||
5 b b 5 5v2 b e 755555 |
||||
5* 5 5ve b [ 75555555555 |
||||
555555555555555555555555555555 |
@ -0,0 +1,151 @@ |
||||
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] = 'Z') then Exit; |
||||
If (cstep <> 0) and (g.map[row, col - cstep] = 'N') 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. |
||||
|
@ -0,0 +1,68 @@ |
||||
|
||||
Unit toolsProc; |
||||
|
||||
Interface |
||||
|
||||
Uses dataUnit; |
||||
|
||||
Procedure doMagnet(Var g:GameState); |
||||
|
||||
Implementation |
||||
|
||||
Function inBounds(g:GameState; row, col:integer): Boolean; |
||||
Begin |
||||
If (row <= g.mapHeight) And |
||||
(col <= g.mapWidth) And |
||||
(row >= 1) And |
||||
(col >= 1) Then |
||||
Exit(true) |
||||
Else |
||||
Exit(false); |
||||
End; |
||||
|
||||
Procedure doMagnet(Var g:GameState); |
||||
|
||||
Var |
||||
row, col, i, s: integer; |
||||
rstep: integer = 0; |
||||
cstep: integer = 0; |
||||
Begin |
||||
For row := 1 To g.mapHeight Do |
||||
For col := 1 To g.mapWidth Do |
||||
Begin |
||||
Case g.map[row,col] Of |
||||
'N': cstep := 1; |
||||
'Z': rstep := 1; |
||||
Else continue; |
||||
End; |
||||
For i := 0 To 1 Do |
||||
Begin |
||||
s := 2*i-1; |
||||
(* Follow man *) |
||||
If inBounds(g,row - 2*s*rstep, col - 2*s*cstep) And |
||||
(g.map[row - 2*s*rstep, col - 2*s*cstep] = man) And |
||||
(g.map[row - s*rstep, col - s*cstep] = empty) Then |
||||
Begin |
||||
g.map[row - s*rstep, col - s*cstep] := g.map[row,col]; |
||||
g.map[row,col] := empty; |
||||
(* Drag pushables *) |
||||
If inBounds(g, row + s*rstep, col + s*cstep) And |
||||
(g.map[row + s*rstep, col + s*cstep] In pushable) Then |
||||
Begin |
||||
g.map[row,col] := g.map[row + s*rstep, col + s*cstep]; |
||||
g.map[row + s*rstep, col + s*cstep] := empty; |
||||
End; |
||||
End; |
||||
(* Pull pushables *) |
||||
If inBounds(g, row + 2*s*rstep, col + 2*s*cstep) And |
||||
(g.map[row + 2*s*rstep, col + 2*s*cstep] In pushable) And |
||||
(g.map[row + s*rstep, col + s*cstep] = empty) Then |
||||
Begin |
||||
g.map[row + s*rstep, col + s*cstep] := g.map[row + 2*s*rstep, col + 2*s*cstep]; |
||||
g.map[row + 2*s*rstep, col + 2*s*cstep] := empty; |
||||
End; |
||||
End; |
||||
End; |
||||
End; |
||||
|
||||
End. |
Loading…
Reference in new issue