Subversion Repositories jumper

Rev

Rev 23 | Rev 25 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 daniel-mar 1
unit LevelFunctions;
2
 
3
interface
4
 
5
uses
21 daniel-mar 6
  SysUtils, Dialogs, Functions, ExtCtrls, Classes, Math;
1 daniel-mar 7
 
8
type
23 daniel-mar 9
  TCoord = record
10
    X: integer;
11
    Y: integer;
12
  end;
13
 
19 daniel-mar 14
  TFieldType = (ftUndefined, ftFullSpace, ftEmpty, ftRed, ftYellow, ftGreen);
1 daniel-mar 15
 
11 daniel-mar 16
  TGameMode = (gmUndefined, gmNormal, gmDiagonal);
1 daniel-mar 17
 
19 daniel-mar 18
  TLevelError = (leUndefined, leNone, leInvalidElement, leEmptyBoard, leRowInvalidLength,
11 daniel-mar 19
                 leUnsupportedVersion, leUnsupportedMode);
1 daniel-mar 20
 
21 daniel-mar 21
  TField = record
24 daniel-mar 22
    Indent: integer;
21 daniel-mar 23
    FieldType: TFieldType;
24
    Goal: Boolean;
25
    Panel: TPanel;
26
    Stone: TImage;
27
  end;
28
 
29
  TGoalStatus = (gsUndefined, gsNoGoal, gsMultipleStonesRemaining, gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen, gsLastStoneOutsideGoal);
30
 
24 daniel-mar 31
  TFieldState = (fsUndefined, fsLocked, fsAvailable, fsOccupied);
21 daniel-mar 32
 
33
  TPlayGroundMatrix = record
34
    Fields: array of array of TField;
35
  public
23 daniel-mar 36
    procedure InitFieldArray(width, height: integer);
21 daniel-mar 37
    function MatrixHasGoal: boolean;
38
    function GoalFieldType: TFieldType;
39
    function MatrixWorth: integer;
40
    procedure ClearMatrix(FreeVCL: boolean);
41
    function CloneMatrix: TPlayGroundMatrix;
23 daniel-mar 42
    class function FieldState(t: TFieldType): TFieldState; overload; static;
21 daniel-mar 43
    function FieldState(f: TField): TFieldState; overload;
44
    function FieldState(x, y: integer): TFieldState; overload;
22 daniel-mar 45
    function CanJump(SourceX, SourceY, DestX, DestY: integer; DiagonalOK: boolean): boolean; overload;
24 daniel-mar 46
    function CanJump(Source, Dest: TCoord; DiagonalOK: boolean): boolean; overload;
22 daniel-mar 47
    function CanJump(SourceX, SourceY: integer; DiagonalOK: boolean): boolean; overload;
24 daniel-mar 48
    function CanJump(Source: TCoord; DiagonalOK: boolean): boolean; overload;
22 daniel-mar 49
    function CanJump(DiagonalOK: boolean): boolean; overload;
23 daniel-mar 50
    function IndexToCoord(index: integer): TCoord;
51
    function CoordToIndex(coord: TCoord): integer; overload;
52
    function CoordToIndex(x, y: integer): integer; overload;
53
    function Width: integer;
54
    function Height: integer;
21 daniel-mar 55
  end;
56
 
24 daniel-mar 57
  TLevel = class(TObject)
58
  private
59
    FStringList: TStringList;
60
    procedure Load(ABoardFile: string);
61
    function GetGameMode: TGameMode;
62
  public
63
    constructor Create(ABoardFile: string);
64
    destructor Destroy; override;
65
    procedure FillPlaygroundMatrix(var matrix: TPlayGroundMatrix; ShowErrors: boolean);
66
    function CheckLevelIntegrity: TLevelError; overload;
67
    function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload;
68
    property GameMode: TGameMode read GetGameMode;
69
  end;
70
 
8 daniel-mar 71
function FieldTypeWorth(t: TFieldType): integer;
1 daniel-mar 72
 
73
implementation
74
 
21 daniel-mar 75
function FieldTypeWorth(t: TFieldType): integer;
76
begin
77
  if t = ftGreen then result := 10
78
  else if t = ftYellow then result := 20
79
  else if t = ftRed then result := 30
80
  else result := 0;
81
end;
82
 
83
{ TPlayGroundMatrix }
84
 
85
function TPlayGroundMatrix.MatrixHasGoal: boolean;
1 daniel-mar 86
var
22 daniel-mar 87
  x, y: integer;
1 daniel-mar 88
begin
21 daniel-mar 89
  result := false;
22 daniel-mar 90
  for x := Low(Fields) to High(Fields) do
21 daniel-mar 91
  begin
22 daniel-mar 92
    for y := Low(Fields[x]) to High(Fields[x]) do
21 daniel-mar 93
    begin
23 daniel-mar 94
      result := result or Fields[x,y].Goal;
21 daniel-mar 95
    end;
96
  end;
97
end;
1 daniel-mar 98
 
21 daniel-mar 99
function TPlayGroundMatrix.GoalFieldType: TFieldType;
100
var
22 daniel-mar 101
  x, y: integer;
21 daniel-mar 102
begin
103
  result := ftEmpty; // Damit der Compiler nicht meckert
22 daniel-mar 104
  for x := Low(Fields) to High(Fields) do
21 daniel-mar 105
  begin
22 daniel-mar 106
    for y := Low(Fields[x]) to High(Fields[x]) do
21 daniel-mar 107
    begin
23 daniel-mar 108
      if Fields[x,y].Goal then result := Fields[x,y].FieldType
21 daniel-mar 109
    end;
110
  end;
111
end;
1 daniel-mar 112
 
23 daniel-mar 113
function TPlayGroundMatrix.Height: integer;
114
begin
115
  if Length(Fields) = 0 then
116
    result := 0
117
  else
118
    result := Length(Fields[0]);
119
end;
120
 
121
function TPlayGroundMatrix.IndexToCoord(index: integer): TCoord;
122
begin
123
  result.X := index mod Width;
124
  result.Y := index div Width;
125
end;
126
 
127
procedure TPlayGroundMatrix.InitFieldArray(width, height: integer);
128
var
129
  x, y: integer;
130
begin
131
  SetLength(Fields, width, height);
132
  for x := Low(Fields) to High(Fields) do
133
  begin
134
    for y := Low(Fields[x]) to High(Fields[x]) do
135
    begin
24 daniel-mar 136
      Fields[x,y].FieldType := ftUndefined
23 daniel-mar 137
    end;
138
  end;
139
end;
140
 
21 daniel-mar 141
function TPlayGroundMatrix.MatrixWorth: integer;
142
var
22 daniel-mar 143
  x, y: integer;
21 daniel-mar 144
begin
145
  result := 0;
22 daniel-mar 146
  for x := Low(Fields) to High(Fields) do
21 daniel-mar 147
  begin
22 daniel-mar 148
    for y := Low(Fields[x]) to High(Fields[x]) do
21 daniel-mar 149
    begin
23 daniel-mar 150
      Inc(result, FieldTypeWorth(Fields[x,y].FieldType));
21 daniel-mar 151
    end;
152
  end;
153
end;
1 daniel-mar 154
 
23 daniel-mar 155
function TPlayGroundMatrix.Width: integer;
156
begin
157
  result := Length(Fields);
158
end;
159
 
24 daniel-mar 160
function TPlayGroundMatrix.CanJump(Source: TCoord;
161
  DiagonalOK: boolean): boolean;
162
begin
163
  result := CanJump(Source.X, Source.Y, DiagonalOK);
164
end;
165
 
166
function TPlayGroundMatrix.CanJump(Source, Dest: TCoord;
167
  DiagonalOK: boolean): boolean;
168
begin
169
  result := CanJump(Source.X, Source.Y, Dest.X, Dest.Y, DiagonalOK);
170
end;
171
 
21 daniel-mar 172
procedure TPlayGroundMatrix.ClearMatrix(FreeVCL: boolean);
173
var
22 daniel-mar 174
  x, y: integer;
21 daniel-mar 175
begin
24 daniel-mar 176
  if FreeVCL then
1 daniel-mar 177
  begin
24 daniel-mar 178
    for x := Low(Fields) to High(Fields) do
1 daniel-mar 179
    begin
24 daniel-mar 180
      for y := Low(Fields[x]) to High(Fields[x]) do
21 daniel-mar 181
      begin
23 daniel-mar 182
        if Assigned(Fields[x,y].Stone) then Fields[x,y].Stone.Free;
183
        if Assigned(Fields[x,y].Panel) then Fields[x,y].Panel.Free;
1 daniel-mar 184
      end;
21 daniel-mar 185
    end;
186
  end;
23 daniel-mar 187
  SetLength(Fields, 0, 0);
21 daniel-mar 188
end;
1 daniel-mar 189
 
21 daniel-mar 190
function TPlayGroundMatrix.CloneMatrix: TPlayGroundMatrix;
191
var
22 daniel-mar 192
  x, y: integer;
21 daniel-mar 193
begin
194
  SetLength(result.Fields, Length(Fields));
22 daniel-mar 195
  for x := Low(Fields) to High(Fields) do
21 daniel-mar 196
  begin
22 daniel-mar 197
    SetLength(result.Fields[x], Length(Fields[x]));
198
    for y := Low(Fields[x]) to High(Fields[x]) do
21 daniel-mar 199
    begin
23 daniel-mar 200
      result.Fields[x,y].FieldType := Fields[x,y].FieldType;
201
      result.Fields[x,y].Goal      := Fields[x,y].Goal;
202
      result.Fields[x,y].Panel     := Fields[x,y].Panel;
203
      result.Fields[x,y].Stone     := Fields[x,y].Stone;
1 daniel-mar 204
    end;
205
  end;
206
end;
207
 
23 daniel-mar 208
function TPlayGroundMatrix.CoordToIndex(x, y: integer): integer;
1 daniel-mar 209
begin
24 daniel-mar 210
  result := x + y * Width;
23 daniel-mar 211
end;
212
 
213
function TPlayGroundMatrix.CoordToIndex(coord: TCoord): integer;
214
begin
24 daniel-mar 215
  result := CoordToIndex(coord.X, coord.Y);
23 daniel-mar 216
end;
217
 
218
class function TPlayGroundMatrix.FieldState(t: TFieldType): TFieldState;
219
begin
24 daniel-mar 220
  result := fsUndefined;
21 daniel-mar 221
  case t of
222
    ftFullSpace: result := fsLocked;
223
    ftEmpty:     result := fsAvailable;
24 daniel-mar 224
    ftGreen:     result := fsOccupied;
225
    ftYellow:    result := fsOccupied;
226
    ftRed:       result := fsOccupied;
21 daniel-mar 227
  end;
1 daniel-mar 228
end;
229
 
21 daniel-mar 230
function TPlayGroundMatrix.FieldState(f: TField): TFieldState;
231
begin
232
  result := FieldState(f.FieldType);
233
end;
234
 
235
function TPlayGroundMatrix.FieldState(x, y: integer): TFieldState;
236
begin
24 daniel-mar 237
  result := fsUndefined;
21 daniel-mar 238
  if (x < Low(Fields)) or (x > High(Fields)) then exit;
239
  if (y < Low(Fields[x])) or (y > High(Fields[x])) then exit;
240
 
23 daniel-mar 241
  result := FieldState(Fields[x,y]);
21 daniel-mar 242
end;
243
 
22 daniel-mar 244
function TPlayGroundMatrix.CanJump(SourceX, SourceY, DestX, DestY: integer; DiagonalOK: boolean): boolean;
245
begin
246
  result := false;
247
 
248
  // Check 1: Ist das Zielfeld überhaupt leer?
249
  if FieldState(DestX, DestY) <> fsAvailable then exit;
250
 
251
  // Check 2: Befindet sich ein Stein zwischen Source und Destination und ist der Abstand 2?
252
  if DiagonalOK then
253
  begin
24 daniel-mar 254
    if (SourceX-2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX-1, SourceY-1) = fsOccupied) then result := true;
255
    if (SourceX-2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX-1, SourceY+1) = fsOccupied) then result := true;
256
    if (SourceX+2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX+1, SourceY-1) = fsOccupied) then result := true;
257
    if (SourceX+2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX+1, SourceY+1) = fsOccupied) then result := true;
22 daniel-mar 258
  end;
259
 
24 daniel-mar 260
  if (SourceX+2 = DestX) and (SourceY   = DestY) and (FieldState(SourceX+1, SourceY  ) = fsOccupied) then result := true;
261
  if (SourceX-2 = DestX) and (SourceY   = DestY) and (FieldState(SourceX-1, SourceY  ) = fsOccupied) then result := true;
262
  if (SourceX   = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX  , SourceY+1) = fsOccupied) then result := true;
263
  if (SourceX   = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX  , SourceY-1) = fsOccupied) then result := true;
22 daniel-mar 264
end;
265
 
266
function TPlayGroundMatrix.CanJump(SourceX, SourceY: integer; DiagonalOK: boolean): boolean;
267
begin
24 daniel-mar 268
  if FieldState(SourceX, SourceY) <> fsOccupied then
22 daniel-mar 269
  begin
270
    result := false;
271
    exit;
272
  end;
273
 
274
  result := true;
275
 
276
  if CanJump(SourceX, SourceY, SourceX+2, SourceY, DiagonalOK) then exit;
277
  if CanJump(SourceX, SourceY, SourceX-2, SourceY, DiagonalOK) then exit;
278
  if CanJump(SourceX, SourceY, SourceX, SourceY+2, DiagonalOK) then exit;
279
  if CanJump(SourceX, SourceY, SourceX, SourceY-2, DiagonalOK) then exit;
280
 
281
  if DiagonalOK then
282
  begin
283
    if CanJump(SourceX, SourceY, SourceX-2, SourceY-2, DiagonalOK) then exit;
284
    if CanJump(SourceX, SourceY, SourceX+2, SourceY-2, DiagonalOK) then exit;
285
    if CanJump(SourceX, SourceY, SourceX-2, SourceY+2, DiagonalOK) then exit;
286
    if CanJump(SourceX, SourceY, SourceX+2, SourceY+2, DiagonalOK) then exit;
287
  end;
288
 
289
  result := false;
290
end;
291
 
292
function TPlayGroundMatrix.CanJump(DiagonalOK: boolean): boolean;
293
var
294
  x, y: integer;
295
begin
296
  result := false;
297
  for x := Low(Fields) to High(Fields) do
298
  begin
299
    for y := Low(Fields[x]) to High(Fields[x]) do
300
    begin
301
      if CanJump(x, y, DiagonalOK) then
302
      begin
303
        result := true;
304
        break;
305
      end;
306
      if result then break;
307
    end;
308
  end;
309
end;
310
 
11 daniel-mar 311
{ TLevel }
312
 
313
const NUM_HEADERS = 2;
314
 
315
constructor TLevel.Create(ABoardFile: string);
1 daniel-mar 316
begin
11 daniel-mar 317
  inherited Create;
318
  FStringList := TStringList.Create;
319
  Load(ABoardFile);
1 daniel-mar 320
end;
321
 
11 daniel-mar 322
destructor TLevel.Destroy;
1 daniel-mar 323
begin
11 daniel-mar 324
  FreeAndNil(FStringList);
325
 
326
  inherited;
1 daniel-mar 327
end;
328
 
11 daniel-mar 329
function TLevel.GetGameMode: TGameMode;
330
begin
331
  if LowerCase(FStringList.Strings[1]) = 'mode: normal' then
332
    result := gmNormal
333
  else if LowerCase(FStringList.Strings[1]) = 'mode: diagonal' then
334
    result := gmDiagonal
335
  else
336
    result := gmUndefined;
337
end;
338
 
339
procedure TLevel.Load(ABoardFile: string);
1 daniel-mar 340
var
11 daniel-mar 341
  i: Integer;
1 daniel-mar 342
begin
11 daniel-mar 343
  FStringList.Clear;
344
  FStringList.LoadFromFile(ABoardFile);
1 daniel-mar 345
 
11 daniel-mar 346
  // Remove whitespaces and empty lines
347
  for i := FStringList.Count-1 downto NUM_HEADERS do
1 daniel-mar 348
  begin
11 daniel-mar 349
    FStringList.Strings[i] := StringReplace(FStringList.Strings[i], ' ', '', [rfReplaceAll]);
350
    if FStringList.Strings[i] = '' then FStringList.Delete(i);
1 daniel-mar 351
  end;
11 daniel-mar 352
end;
1 daniel-mar 353
 
24 daniel-mar 354
procedure TLevel.FillPlaygroundMatrix(var matrix: TPlayGroundMatrix; ShowErrors: boolean);
11 daniel-mar 355
var
356
  i: integer;
357
  t: TFieldType;
358
  err: TLevelError;
359
  y: Integer;
360
  x: Integer;
361
  Line: string;
362
  lch, uch: char;
363
  ch: char;
24 daniel-mar 364
  width: Integer;
365
  height: Integer;
366
  lineIndent: Integer;
11 daniel-mar 367
begin
368
  // Zuerst nach Fehlern suchen
369
  err := CheckLevelIntegrity(ShowErrors);
370
  if err <> leNone then exit;
371
 
24 daniel-mar 372
  // Breite feststellen
373
  if FStringList.Count > NUM_HEADERS then
374
  begin
375
    Line := FStringList.Strings[NUM_HEADERS];
376
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
377
    width := Length(Line);
378
  end
379
  else width := 0;
380
 
381
  // Höhe feststellen
382
  height := FStringList.Count - NUM_HEADERS;
383
 
11 daniel-mar 384
  // Nun Matrix aufbauen
24 daniel-mar 385
  matrix.ClearMatrix(true);
386
  matrix.InitFieldArray(width, height);
11 daniel-mar 387
  for i := NUM_HEADERS to FStringList.Count-1 do
1 daniel-mar 388
  begin
11 daniel-mar 389
    y := i - NUM_HEADERS;
1 daniel-mar 390
 
11 daniel-mar 391
    Line := FStringList.Strings[i];
24 daniel-mar 392
    lineIndent := DotsAtBeginning(Line) - DotsAtEnd(Line);
19 daniel-mar 393
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
1 daniel-mar 394
 
19 daniel-mar 395
    for x := 0 to Length(Line)-1 do
11 daniel-mar 396
    begin
19 daniel-mar 397
      ch := Line[x+1];
11 daniel-mar 398
      lch := LowerCase(ch)[1];
399
      uch := UpperCase(ch)[1];
19 daniel-mar 400
 
401
      t := ftUndefined;
11 daniel-mar 402
      case lch of
403
        '*': t := ftFullSpace;
404
        'e': t := ftEmpty;
405
        'r': t := ftRed;
406
        'y': t := ftYellow;
407
        'g': t := ftGreen;
408
      end;
1 daniel-mar 409
 
24 daniel-mar 410
      matrix.Fields[x,y].Indent := lineIndent;
411
      matrix.Fields[x,y].FieldType := t;
412
      matrix.Fields[x,y].Goal := (ch = uch) and (ch <> lch);
11 daniel-mar 413
    end;
414
  end;
415
end;
416
 
417
function TLevel.CheckLevelIntegrity(ShowErrors: boolean): TLevelError;
418
resourcestring
419
  LNG_LVL_INVALID_ELEMENT = 'Level invalid: There are invalid elements in the file.'+#13#10#13#10+'Valid elements are r/R, y/Y, g/G, e/E, . and *.';
420
  LNG_LVL_UNSUPPORTED_VERSION = 'Level format invalid: Version not supported.';
421
  LNG_LVL_UNSUPPORTED_MODE = 'Level format invalid: Mode not supported.';
422
  LNG_LVL_EMPTY_BOARD = 'Level invalid: Board is empty.';
423
  LNG_LVL_INVALID_LENGTH = 'Level invalid: Lines don''t have an equal amount of elements.';
424
begin
425
  result := CheckLevelIntegrity;
426
  if ShowErrors then
1 daniel-mar 427
  begin
11 daniel-mar 428
    case result of
429
      leNone: ;
430
      leInvalidElement: MessageDlg(LNG_LVL_INVALID_ELEMENT, mtError, [mbOk], 0);
431
      leUnsupportedVersion: MessageDlg(LNG_LVL_UNSUPPORTED_VERSION, mtError, [mbOk], 0);
432
      leUnsupportedMode: MessageDlg(LNG_LVL_UNSUPPORTED_MODE, mtError, [mbOk], 0);
433
      leEmptyBoard: MessageDlg(LNG_LVL_EMPTY_BOARD, mtError, [mbOk], 0);
434
      leRowInvalidLength: MessageDlg(LNG_LVL_INVALID_LENGTH, mtError, [mbOk], 0);
1 daniel-mar 435
    end;
436
  end;
11 daniel-mar 437
end;
1 daniel-mar 438
 
11 daniel-mar 439
function TLevel.CheckLevelIntegrity: TLevelError;
440
var
19 daniel-mar 441
  tmp: string;
11 daniel-mar 442
  i: Integer;
443
  Line: string;
19 daniel-mar 444
  firstLine: string;
445
  thisLine: string;
11 daniel-mar 446
begin
447
  result := leNone;
1 daniel-mar 448
 
11 daniel-mar 449
  // Check 1: Ist der Header OK?
1 daniel-mar 450
 
11 daniel-mar 451
  if LowerCase(FStringList.Strings[0]) <> 'version 2' then
1 daniel-mar 452
  begin
11 daniel-mar 453
    result := leUnsupportedVersion;
454
    exit;
1 daniel-mar 455
  end;
456
 
24 daniel-mar 457
  if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and
458
      (LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then
1 daniel-mar 459
  begin
11 daniel-mar 460
    result := leUnsupportedMode;
461
    exit;
1 daniel-mar 462
  end;
463
 
11 daniel-mar 464
  // Check 2: Ist das Brett leer?
1 daniel-mar 465
 
19 daniel-mar 466
  tmp := '';
467
  for i := NUM_HEADERS to FStringList.Count-1 do tmp := tmp + FStringList.Strings[i];
468
  if Trim(StringReplace(tmp, '.', '', [rfReplaceAll])) = '' then
1 daniel-mar 469
  begin
11 daniel-mar 470
    result := leEmptyBoard;
471
    exit;
1 daniel-mar 472
  end;
473
 
11 daniel-mar 474
  // Check 3: Geht das Level nicht in einem Quadrat oder Rechteck auf?
1 daniel-mar 475
 
19 daniel-mar 476
  firstLine := StringReplace(FStringList.Strings[NUM_HEADERS], '.', '', [rfReplaceAll]);
11 daniel-mar 477
  for i := NUM_HEADERS to FStringList.Count-1 do
1 daniel-mar 478
  begin
19 daniel-mar 479
    thisLine := StringReplace(FStringList.Strings[i], '.', '', [rfReplaceAll]);
480
    if Length(thisLine) <> Length(firstLine) then
11 daniel-mar 481
    begin
24 daniel-mar 482
      result := leRowInvalidLength; // at row y = i-NUM_HEADERS
11 daniel-mar 483
      exit;
484
    end;
1 daniel-mar 485
  end;
486
 
11 daniel-mar 487
  // Check 4: Gibt es ungültige Elemente in den Zeilen?
1 daniel-mar 488
 
11 daniel-mar 489
  for i := NUM_HEADERS to FStringList.Count-1 do
490
  begin
491
    Line := FStringList.Strings[i];
1 daniel-mar 492
 
11 daniel-mar 493
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
494
    Line := StringReplace(Line, '*', '', [rfReplaceAll]);
495
    Line := StringReplace(Line, 'r', '', [rfReplaceAll, rfIgnoreCase]);
496
    Line := StringReplace(Line, 'y', '', [rfReplaceAll, rfIgnoreCase]);
497
    Line := StringReplace(Line, 'g', '', [rfReplaceAll, rfIgnoreCase]);
498
    Line := StringReplace(Line, 'e', '', [rfReplaceAll, rfIgnoreCase]);
1 daniel-mar 499
 
11 daniel-mar 500
    if Length(Line) > 0 then
1 daniel-mar 501
    begin
24 daniel-mar 502
      result := leInvalidElement; // at row y = i-NUM_HEADERS
11 daniel-mar 503
      Exit;
1 daniel-mar 504
    end;
505
  end;
506
 
22 daniel-mar 507
  // Check 5: Kann im Level gesprungen werden?
11 daniel-mar 508
 
509
  { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss.
510
    Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! }
8 daniel-mar 511
end;
512
 
1 daniel-mar 513
end.