Rev 21 | Rev 23 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 21 | Rev 22 | ||
---|---|---|---|
Line 26... | Line 26... | ||
26 | 26 | ||
27 | TLevel = class(TObject) |
27 | TLevel = class(TObject) |
28 | private |
28 | private |
29 | FStringList: TStringList; |
29 | FStringList: TStringList; |
30 | procedure Load(ABoardFile: string); |
30 | procedure Load(ABoardFile: string); |
- | 31 | function GetGameMode: TGameMode; |
|
31 | public |
32 | public |
32 | constructor Create(ABoardFile: string); |
33 | constructor Create(ABoardFile: string); |
33 | destructor Destroy; override; |
34 | destructor Destroy; override; |
34 | function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
35 | function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
35 | function CheckLevelIntegrity: TLevelError; overload; |
36 | function CheckLevelIntegrity: TLevelError; overload; |
36 | function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload; |
37 | function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload; |
37 | function GetGameMode: TGameMode; |
38 | property GameMode: TGameMode read GetGameMode; |
38 | end; |
39 | end; |
39 | 40 | ||
40 | TField = record |
41 | TField = record |
41 | FieldType: TFieldType; |
42 | FieldType: TFieldType; |
42 | Goal: Boolean; |
43 | Goal: Boolean; |
Line 57... | Line 58... | ||
57 | procedure ClearMatrix(FreeVCL: boolean); |
58 | procedure ClearMatrix(FreeVCL: boolean); |
58 | function CloneMatrix: TPlayGroundMatrix; |
59 | function CloneMatrix: TPlayGroundMatrix; |
59 | function FieldState(t: TFieldType): TFieldState; overload; |
60 | function FieldState(t: TFieldType): TFieldState; overload; |
60 | function FieldState(f: TField): TFieldState; overload; |
61 | function FieldState(f: TField): TFieldState; overload; |
61 | function FieldState(x, y: integer): TFieldState; overload; |
62 | function FieldState(x, y: integer): TFieldState; overload; |
- | 63 | function CanJump(SourceX, SourceY, DestX, DestY: integer; DiagonalOK: boolean): boolean; overload; |
|
- | 64 | function CanJump(SourceX, SourceY: integer; DiagonalOK: boolean): boolean; overload; |
|
- | 65 | function CanJump(DiagonalOK: boolean): boolean; overload; |
|
62 | end; |
66 | end; |
63 | 67 | ||
64 | function FieldTypeWorth(t: TFieldType): integer; |
68 | function FieldTypeWorth(t: TFieldType): integer; |
65 | 69 | ||
66 | implementation |
70 | implementation |
Line 75... | Line 79... | ||
75 | 79 | ||
76 | { TPlayGroundMatrix } |
80 | { TPlayGroundMatrix } |
77 | 81 | ||
78 | function TPlayGroundMatrix.MatrixHasGoal: boolean; |
82 | function TPlayGroundMatrix.MatrixHasGoal: boolean; |
79 | var |
83 | var |
80 | i, j: integer; |
84 | x, y: integer; |
81 | begin |
85 | begin |
82 | result := false; |
86 | result := false; |
83 | for i := Low(Fields) to High(Fields) do |
87 | for x := Low(Fields) to High(Fields) do |
84 | begin |
88 | begin |
85 | for j := Low(Fields[i]) to High(Fields[i]) do |
89 | for y := Low(Fields[x]) to High(Fields[x]) do |
86 | begin |
90 | begin |
87 | result := result or Fields[i][j].Goal; |
91 | result := result or Fields[x][y].Goal; |
88 | end; |
92 | end; |
89 | end; |
93 | end; |
90 | end; |
94 | end; |
91 | 95 | ||
92 | function TPlayGroundMatrix.GoalFieldType: TFieldType; |
96 | function TPlayGroundMatrix.GoalFieldType: TFieldType; |
93 | var |
97 | var |
94 | i, j: integer; |
98 | x, y: integer; |
95 | begin |
99 | begin |
96 | result := ftEmpty; // Damit der Compiler nicht meckert |
100 | result := ftEmpty; // Damit der Compiler nicht meckert |
97 | for i := Low(Fields) to High(Fields) do |
101 | for x := Low(Fields) to High(Fields) do |
98 | begin |
102 | begin |
99 | for j := Low(Fields[i]) to High(Fields[i]) do |
103 | for y := Low(Fields[x]) to High(Fields[x]) do |
100 | begin |
104 | begin |
101 | if Fields[i][j].Goal then result := Fields[i][j].FieldType |
105 | if Fields[x][y].Goal then result := Fields[x][y].FieldType |
102 | end; |
106 | end; |
103 | end; |
107 | end; |
104 | end; |
108 | end; |
105 | 109 | ||
106 | function TPlayGroundMatrix.MatrixWorth: integer; |
110 | function TPlayGroundMatrix.MatrixWorth: integer; |
107 | var |
111 | var |
108 | i, j: integer; |
112 | x, y: integer; |
109 | begin |
113 | begin |
110 | result := 0; |
114 | result := 0; |
111 | for i := Low(Fields) to High(Fields) do |
115 | for x := Low(Fields) to High(Fields) do |
112 | begin |
116 | begin |
113 | for j := Low(Fields[i]) to High(Fields[i]) do |
117 | for y := Low(Fields[x]) to High(Fields[x]) do |
114 | begin |
118 | begin |
115 | Inc(result, FieldTypeWorth(Fields[i][j].FieldType)); |
119 | Inc(result, FieldTypeWorth(Fields[x][y].FieldType)); |
116 | end; |
120 | end; |
117 | end; |
121 | end; |
118 | end; |
122 | end; |
119 | 123 | ||
120 | procedure TPlayGroundMatrix.ClearMatrix(FreeVCL: boolean); |
124 | procedure TPlayGroundMatrix.ClearMatrix(FreeVCL: boolean); |
121 | var |
125 | var |
122 | i, j: integer; |
126 | x, y: integer; |
123 | begin |
127 | begin |
124 | for i := Low(Fields) to High(Fields) do |
128 | for x := Low(Fields) to High(Fields) do |
125 | begin |
129 | begin |
126 | for j := Low(Fields[i]) to High(Fields[i]) do |
130 | for y := Low(Fields[x]) to High(Fields[x]) do |
127 | begin |
131 | begin |
128 | if FreeVCL then |
132 | if FreeVCL then |
129 | begin |
133 | begin |
130 | if Assigned(Fields[i][j].Stone) then Fields[i][j].Stone.Free; |
134 | if Assigned(Fields[x][y].Stone) then Fields[x][y].Stone.Free; |
131 | if Assigned(Fields[i][j].Panel) then Fields[i][j].Panel.Free; |
135 | if Assigned(Fields[x][y].Panel) then Fields[x][y].Panel.Free; |
132 | end; |
136 | end; |
133 | end; |
137 | end; |
134 | SetLength(Fields[i], 0); |
138 | SetLength(Fields[x], 0); |
135 | end; |
139 | end; |
136 | SetLength(Fields, 0); |
140 | SetLength(Fields, 0); |
137 | end; |
141 | end; |
138 | 142 | ||
139 | function TPlayGroundMatrix.CloneMatrix: TPlayGroundMatrix; |
143 | function TPlayGroundMatrix.CloneMatrix: TPlayGroundMatrix; |
140 | var |
144 | var |
141 | i, j: integer; |
145 | x, y: integer; |
142 | begin |
146 | begin |
143 | SetLength(result.Fields, Length(Fields)); |
147 | SetLength(result.Fields, Length(Fields)); |
144 | for i := Low(Fields) to High(Fields) do |
148 | for x := Low(Fields) to High(Fields) do |
145 | begin |
149 | begin |
146 | SetLength(result.Fields[i], Length(Fields[i])); |
150 | SetLength(result.Fields[x], Length(Fields[x])); |
147 | for j := Low(Fields[i]) to High(Fields[i]) do |
151 | for y := Low(Fields[x]) to High(Fields[x]) do |
148 | begin |
152 | begin |
149 | result.Fields[i][j].FieldType := Fields[i][j].FieldType; |
153 | result.Fields[x][y].FieldType := Fields[x][y].FieldType; |
150 | result.Fields[i][j].Goal := Fields[i][j].Goal; |
154 | result.Fields[x][y].Goal := Fields[x][y].Goal; |
151 | result.Fields[i][j].Panel := Fields[i][j].Panel; |
155 | result.Fields[x][y].Panel := Fields[x][y].Panel; |
152 | result.Fields[i][j].Stone := Fields[i][j].Stone; |
156 | result.Fields[x][y].Stone := Fields[x][y].Stone; |
153 | end; |
157 | end; |
154 | end; |
158 | end; |
155 | end; |
159 | end; |
156 | 160 | ||
157 | function TPlayGroundMatrix.FieldState(t: TFieldType): TFieldState; |
161 | function TPlayGroundMatrix.FieldState(t: TFieldType): TFieldState; |
Line 178... | Line 182... | ||
178 | if (y < Low(Fields[x])) or (y > High(Fields[x])) then exit; |
182 | if (y < Low(Fields[x])) or (y > High(Fields[x])) then exit; |
179 | 183 | ||
180 | result := FieldState(Fields[x][y]); |
184 | result := FieldState(Fields[x][y]); |
181 | end; |
185 | end; |
182 | 186 | ||
- | 187 | function TPlayGroundMatrix.CanJump(SourceX, SourceY, DestX, DestY: integer; DiagonalOK: boolean): boolean; |
|
- | 188 | begin |
|
- | 189 | result := false; |
|
- | 190 | ||
- | 191 | // Check 1: Ist das Zielfeld überhaupt leer? |
|
- | 192 | if FieldState(DestX, DestY) <> fsAvailable then exit; |
|
- | 193 | ||
- | 194 | // Check 2: Befindet sich ein Stein zwischen Source und Destination und ist der Abstand 2? |
|
- | 195 | if DiagonalOK then |
|
- | 196 | begin |
|
- | 197 | if (SourceX-2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX-1, SourceY-1) = fsStone) then result := true; |
|
- | 198 | if (SourceX-2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX-1, SourceY+1) = fsStone) then result := true; |
|
- | 199 | if (SourceX+2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX+1, SourceY-1) = fsStone) then result := true; |
|
- | 200 | if (SourceX+2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX+1, SourceY+1) = fsStone) then result := true; |
|
- | 201 | end; |
|
- | 202 | ||
- | 203 | if (SourceX+2 = DestX) and (SourceY = DestY) and (FieldState(SourceX+1, SourceY ) = fsStone) then result := true; |
|
- | 204 | if (SourceX-2 = DestX) and (SourceY = DestY) and (FieldState(SourceX-1, SourceY ) = fsStone) then result := true; |
|
- | 205 | if (SourceX = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX , SourceY+1) = fsStone) then result := true; |
|
- | 206 | if (SourceX = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX , SourceY-1) = fsStone) then result := true; |
|
- | 207 | end; |
|
- | 208 | ||
- | 209 | function TPlayGroundMatrix.CanJump(SourceX, SourceY: integer; DiagonalOK: boolean): boolean; |
|
- | 210 | begin |
|
- | 211 | if FieldState(SourceX, SourceY) <> fsStone then |
|
- | 212 | begin |
|
- | 213 | result := false; |
|
- | 214 | exit; |
|
- | 215 | end; |
|
- | 216 | ||
- | 217 | result := true; |
|
- | 218 | ||
- | 219 | if CanJump(SourceX, SourceY, SourceX+2, SourceY, DiagonalOK) then exit; |
|
- | 220 | if CanJump(SourceX, SourceY, SourceX-2, SourceY, DiagonalOK) then exit; |
|
- | 221 | if CanJump(SourceX, SourceY, SourceX, SourceY+2, DiagonalOK) then exit; |
|
- | 222 | if CanJump(SourceX, SourceY, SourceX, SourceY-2, DiagonalOK) then exit; |
|
- | 223 | ||
- | 224 | if DiagonalOK then |
|
- | 225 | begin |
|
- | 226 | if CanJump(SourceX, SourceY, SourceX-2, SourceY-2, DiagonalOK) then exit; |
|
- | 227 | if CanJump(SourceX, SourceY, SourceX+2, SourceY-2, DiagonalOK) then exit; |
|
- | 228 | if CanJump(SourceX, SourceY, SourceX-2, SourceY+2, DiagonalOK) then exit; |
|
- | 229 | if CanJump(SourceX, SourceY, SourceX+2, SourceY+2, DiagonalOK) then exit; |
|
- | 230 | end; |
|
- | 231 | ||
- | 232 | result := false; |
|
- | 233 | end; |
|
- | 234 | ||
- | 235 | function TPlayGroundMatrix.CanJump(DiagonalOK: boolean): boolean; |
|
- | 236 | var |
|
- | 237 | x, y: integer; |
|
- | 238 | begin |
|
- | 239 | result := false; |
|
- | 240 | for x := Low(Fields) to High(Fields) do |
|
- | 241 | begin |
|
- | 242 | for y := Low(Fields[x]) to High(Fields[x]) do |
|
- | 243 | begin |
|
- | 244 | if CanJump(x, y, DiagonalOK) then |
|
- | 245 | begin |
|
- | 246 | result := true; |
|
- | 247 | break; |
|
- | 248 | end; |
|
- | 249 | if result then break; |
|
- | 250 | end; |
|
- | 251 | end; |
|
- | 252 | end; |
|
- | 253 | ||
183 | { TLevel } |
254 | { TLevel } |
184 | 255 | ||
185 | const NUM_HEADERS = 2; |
256 | const NUM_HEADERS = 2; |
186 | 257 | ||
187 | constructor TLevel.Create(ABoardFile: string); |
258 | constructor TLevel.Create(ABoardFile: string); |
Line 359... | Line 430... | ||
359 | result := leInvalidElement; // at row y-NUM_HEADERS |
430 | result := leInvalidElement; // at row y-NUM_HEADERS |
360 | Exit; |
431 | Exit; |
361 | end; |
432 | end; |
362 | end; |
433 | end; |
363 | 434 | ||
364 | // Check 5: Kann im Level gesprungen werden |
435 | // Check 5: Kann im Level gesprungen werden? |
365 | 436 | ||
366 | { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss. |
437 | { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss. |
367 | Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! } |
438 | Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! } |
368 | end; |
439 | end; |
369 | 440 |