Subversion Repositories jumper

Rev

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