Subversion Repositories jumper

Rev

Rev 19 | Rev 22 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 19 Rev 21
1
unit LevelFunctions;
1
unit LevelFunctions;
2
 
2
 
3
interface
3
interface
4
 
4
 
5
uses
5
uses
6
  SysUtils, Dialogs, Functions, ExtCtrls, Graphics, Classes, Math;
6
  SysUtils, Dialogs, Functions, ExtCtrls, Classes, Math;
7
 
7
 
8
type
8
type
9
  TFieldType = (ftUndefined, ftFullSpace, ftEmpty, ftRed, ftYellow, ftGreen);
9
  TFieldType = (ftUndefined, ftFullSpace, ftEmpty, ftRed, ftYellow, ftGreen);
10
 
10
 
11
  TFieldProperties = record
11
  TFieldProperties = record
12
    Typ: TFieldType;
12
    Typ: TFieldType;
13
    Goal: Boolean;
13
    Goal: Boolean;
14
  end;
14
  end;
15
 
15
 
16
  TGameMode = (gmUndefined, gmNormal, gmDiagonal);
16
  TGameMode = (gmUndefined, gmNormal, gmDiagonal);
17
 
17
 
18
  TRow = record
18
  TRow = record
19
    Indent: integer;
19
    Indent: integer;
20
    Fields: array of TFieldProperties;
20
    Fields: array of TFieldProperties;
21
  end;
21
  end;
22
  TLevelArray = array of TRow;
22
  TLevelArray = array of TRow;
23
 
23
 
24
  TLevelError = (leUndefined, leNone, leInvalidElement, leEmptyBoard, leRowInvalidLength,
24
  TLevelError = (leUndefined, leNone, leInvalidElement, leEmptyBoard, leRowInvalidLength,
25
                 leUnsupportedVersion, leUnsupportedMode);
25
                 leUnsupportedVersion, leUnsupportedMode);
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
  public
31
  public
32
    constructor Create(ABoardFile: string);
32
    constructor Create(ABoardFile: string);
33
    destructor Destroy; override;
33
    destructor Destroy; override;
34
    function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray;
34
    function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray;
35
    function CheckLevelIntegrity: TLevelError; overload;
35
    function CheckLevelIntegrity: TLevelError; overload;
36
    function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload;
36
    function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload;
37
    function GetGameMode: TGameMode;
37
    function GetGameMode: TGameMode;
38
  end;
38
  end;
39
 
39
 
-
 
40
  TField = record
-
 
41
    FieldType: TFieldType;
-
 
42
    Goal: Boolean;
-
 
43
    Panel: TPanel;
-
 
44
    Stone: TImage;
-
 
45
  end;
-
 
46
 
-
 
47
  TGoalStatus = (gsUndefined, gsNoGoal, gsMultipleStonesRemaining, gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen, gsLastStoneOutsideGoal);
-
 
48
 
-
 
49
  TFieldState = (fsUndefined, fsError, fsLocked, fsAvailable, fsStone);
-
 
50
 
-
 
51
  TPlayGroundMatrix = record
-
 
52
    Fields: array of array of TField;
-
 
53
  public
-
 
54
    function MatrixHasGoal: boolean;
-
 
55
    function GoalFieldType: TFieldType;
-
 
56
    function MatrixWorth: integer;
-
 
57
    procedure ClearMatrix(FreeVCL: boolean);
-
 
58
    function CloneMatrix: TPlayGroundMatrix;
40
procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor);
59
    function FieldState(t: TFieldType): TFieldState; overload;
-
 
60
    function FieldState(f: TField): TFieldState; overload;
-
 
61
    function FieldState(x, y: integer): TFieldState; overload;
-
 
62
  end;
-
 
63
 
41
function FieldTypeWorth(t: TFieldType): integer;
64
function FieldTypeWorth(t: TFieldType): integer;
42
 
65
 
43
implementation
66
implementation
44
 
67
 
45
procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor);
-
 
46
var
-
 
47
  LevelArray: TLevelArray;
-
 
48
  y, x: integer;
-
 
49
  t: TFieldType;
-
 
50
  indent: Integer;
-
 
51
const
-
 
52
  PREVIEW_BLOCK_SIZE = 10; // Enthält Field und Abstand
68
function FieldTypeWorth(t: TFieldType): integer;
53
  PREVIEW_TAB_SIZE = PREVIEW_BLOCK_SIZE div 2; // 5
-
 
54
begin
69
begin
-
 
70
  if t = ftGreen then result := 10
-
 
71
  else if t = ftYellow then result := 20
-
 
72
  else if t = ftRed then result := 30
55
  LevelArray := nil;
73
  else result := 0;
-
 
74
end;
56
 
75
 
57
  ClearImage(Image, BackgroundColor);
76
{ TPlayGroundMatrix }
58
 
77
 
-
 
78
function TPlayGroundMatrix.MatrixHasGoal: boolean;
-
 
79
var
-
 
80
  i, j: integer;
-
 
81
begin
-
 
82
  result := false;
-
 
83
  for i := Low(Fields) to High(Fields) do
-
 
84
  begin
59
  LevelArray := Level.LevelStringToLevelArray(false);
85
    for j := Low(Fields[i]) to High(Fields[i]) do
-
 
86
    begin
-
 
87
      result := result or Fields[i][j].Goal;
-
 
88
    end;
-
 
89
  end;
-
 
90
end;
60
 
91
 
61
  for y := Low(LevelArray) to High(LevelArray) do
92
function TPlayGroundMatrix.GoalFieldType: TFieldType;
-
 
93
var
-
 
94
  i, j: integer;
62
  begin
95
begin
-
 
96
  result := ftEmpty; // Damit der Compiler nicht meckert
63
    for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do
97
  for i := Low(Fields) to High(Fields) do
64
    begin
98
  begin
65
      t      := LevelArray[y].Fields[x].Typ;
99
    for j := Low(Fields[i]) to High(Fields[i]) do
-
 
100
    begin
66
      indent := LevelArray[y].Indent;
101
      if Fields[i][j].Goal then result := Fields[i][j].FieldType
-
 
102
    end;
-
 
103
  end;
-
 
104
end;
67
 
105
 
-
 
106
function TPlayGroundMatrix.MatrixWorth: integer;
-
 
107
var
68
      case t of
108
  i, j: integer;
-
 
109
begin
69
        ftFullSpace: Image.Canvas.Brush.Color := BackgroundColor;
110
  result := 0;
70
        ftEmpty:     Image.Canvas.Brush.Color := clWhite;
111
  for i := Low(Fields) to High(Fields) do
-
 
112
  begin
71
        ftGreen:     Image.Canvas.Brush.Color := clLime;
113
    for j := Low(Fields[i]) to High(Fields[i]) do
-
 
114
    begin
72
        ftYellow:    Image.Canvas.Brush.Color := clYellow;
115
      Inc(result, FieldTypeWorth(Fields[i][j].FieldType));
73
        ftRed:       Image.Canvas.Brush.Color := clRed;
116
    end;
-
 
117
  end;
74
      end;
118
end;
75
 
119
 
-
 
120
procedure TPlayGroundMatrix.ClearMatrix(FreeVCL: boolean);
-
 
121
var
-
 
122
  i, j: integer;
-
 
123
begin
76
      if LevelArray[y].Fields[x].Goal then
124
  for i := Low(Fields) to High(Fields) do
-
 
125
  begin
77
        Image.Canvas.Pen.Color := clBlack
126
    for j := Low(Fields[i]) to High(Fields[i]) do
-
 
127
    begin
-
 
128
      if FreeVCL then
78
      else
129
      begin
-
 
130
        if Assigned(Fields[i][j].Stone) then Fields[i][j].Stone.Free;
79
        Image.Canvas.Pen.Color := BackgroundColor;
131
        if Assigned(Fields[i][j].Panel) then Fields[i][j].Panel.Free;
-
 
132
      end;
-
 
133
    end;
-
 
134
    SetLength(Fields[i], 0);
-
 
135
  end;
-
 
136
  SetLength(Fields, 0);
-
 
137
end;
80
 
138
 
-
 
139
function TPlayGroundMatrix.CloneMatrix: TPlayGroundMatrix;
-
 
140
var
-
 
141
  i, j: integer;
-
 
142
begin
-
 
143
  SetLength(result.Fields, Length(Fields));
-
 
144
  for i := Low(Fields) to High(Fields) do
-
 
145
  begin
-
 
146
    SetLength(result.Fields[i], Length(Fields[i]));
-
 
147
    for j := Low(Fields[i]) to High(Fields[i]) do
-
 
148
    begin
81
      Image.Canvas.Rectangle(x*PREVIEW_BLOCK_SIZE + indent*PREVIEW_TAB_SIZE,
149
      result.Fields[i][j].FieldType := Fields[i][j].FieldType;
82
                             y*PREVIEW_BLOCK_SIZE,
150
      result.Fields[i][j].Goal      := Fields[i][j].Goal;
83
                             x*PREVIEW_BLOCK_SIZE + indent*PREVIEW_TAB_SIZE + PREVIEW_BLOCK_SIZE,
151
      result.Fields[i][j].Panel     := Fields[i][j].Panel;
84
                             y*PREVIEW_BLOCK_SIZE                           + PREVIEW_BLOCK_SIZE);
152
      result.Fields[i][j].Stone     := Fields[i][j].Stone;
85
    end;
153
    end;
86
  end;
154
  end;
87
end;
155
end;
88
 
156
 
89
function FieldTypeWorth(t: TFieldType): integer;
157
function TPlayGroundMatrix.FieldState(t: TFieldType): TFieldState;
90
begin
158
begin
-
 
159
  result := fsError;
-
 
160
  case t of
-
 
161
    ftFullSpace: result := fsLocked;
-
 
162
    ftEmpty:     result := fsAvailable;
91
  if t = ftGreen then result := 10
163
    ftGreen:     result := fsStone;
92
  else if t = ftYellow then result := 20
164
    ftYellow:    result := fsStone;
93
  else if t = ftRed then result := 30
165
    ftRed:       result := fsStone;
-
 
166
  end;
-
 
167
end;
-
 
168
 
-
 
169
function TPlayGroundMatrix.FieldState(f: TField): TFieldState;
-
 
170
begin
-
 
171
  result := FieldState(f.FieldType);
-
 
172
end;
-
 
173
 
-
 
174
function TPlayGroundMatrix.FieldState(x, y: integer): TFieldState;
-
 
175
begin
94
  else result := 0;
176
  result := fsError;
-
 
177
  if (x < Low(Fields)) or (x > High(Fields)) then exit;
-
 
178
  if (y < Low(Fields[x])) or (y > High(Fields[x])) then exit;
-
 
179
 
-
 
180
  result := FieldState(Fields[x][y]);
95
end;
181
end;
96
 
182
 
97
{ TLevel }
183
{ TLevel }
98
 
184
 
99
const NUM_HEADERS = 2;
185
const NUM_HEADERS = 2;
100
 
186
 
101
constructor TLevel.Create(ABoardFile: string);
187
constructor TLevel.Create(ABoardFile: string);
102
begin
188
begin
103
  inherited Create;
189
  inherited Create;
104
  FStringList := TStringList.Create;
190
  FStringList := TStringList.Create;
105
  Load(ABoardFile);
191
  Load(ABoardFile);
106
end;
192
end;
107
 
193
 
108
destructor TLevel.Destroy;
194
destructor TLevel.Destroy;
109
begin
195
begin
110
  FreeAndNil(FStringList);
196
  FreeAndNil(FStringList);
111
 
197
 
112
  inherited;
198
  inherited;
113
end;
199
end;
114
 
200
 
115
function TLevel.GetGameMode: TGameMode;
201
function TLevel.GetGameMode: TGameMode;
116
begin
202
begin
117
  if LowerCase(FStringList.Strings[1]) = 'mode: normal' then
203
  if LowerCase(FStringList.Strings[1]) = 'mode: normal' then
118
    result := gmNormal
204
    result := gmNormal
119
  else if LowerCase(FStringList.Strings[1]) = 'mode: diagonal' then
205
  else if LowerCase(FStringList.Strings[1]) = 'mode: diagonal' then
120
    result := gmDiagonal
206
    result := gmDiagonal
121
  else
207
  else
122
    result := gmUndefined;
208
    result := gmUndefined;
123
end;
209
end;
124
 
210
 
125
procedure TLevel.Load(ABoardFile: string);
211
procedure TLevel.Load(ABoardFile: string);
126
var
212
var
127
  i: Integer;
213
  i: Integer;
128
begin
214
begin
129
  FStringList.Clear;
215
  FStringList.Clear;
130
  FStringList.LoadFromFile(ABoardFile);
216
  FStringList.LoadFromFile(ABoardFile);
131
 
217
 
132
  // Remove whitespaces and empty lines
218
  // Remove whitespaces and empty lines
133
  for i := FStringList.Count-1 downto NUM_HEADERS do
219
  for i := FStringList.Count-1 downto NUM_HEADERS do
134
  begin
220
  begin
135
    FStringList.Strings[i] := StringReplace(FStringList.Strings[i], ' ', '', [rfReplaceAll]);
221
    FStringList.Strings[i] := StringReplace(FStringList.Strings[i], ' ', '', [rfReplaceAll]);
136
    if FStringList.Strings[i] = '' then FStringList.Delete(i);
222
    if FStringList.Strings[i] = '' then FStringList.Delete(i);
137
  end;
223
  end;
138
end;
-
 
139
 
-
 
140
function DotsAtBeginning(s: string): integer;
-
 
141
var
-
 
142
  i: integer;
-
 
143
begin
-
 
144
  result := 0;
-
 
145
  for i := 1 to Length(s) do
-
 
146
  begin
-
 
147
    if s[i] = '.' then
-
 
148
      Inc(result)
-
 
149
    else
-
 
150
      Exit;
-
 
151
  end;
-
 
152
end;
-
 
153
 
-
 
154
function DotsAtEnd(s: string): integer;
-
 
155
var
-
 
156
  i: integer;
-
 
157
begin
-
 
158
  result := 0;
-
 
159
  for i := Length(s) downto 1 do
-
 
160
  begin
-
 
161
    if s[i] = '.' then
-
 
162
      Inc(result)
-
 
163
    else
-
 
164
      Exit;
-
 
165
  end;
-
 
166
end;
224
end;
167
 
225
 
168
function TLevel.LevelStringToLevelArray(ShowErrors: boolean): TLevelArray;
226
function TLevel.LevelStringToLevelArray(ShowErrors: boolean): TLevelArray;
169
var
227
var
170
  i: integer;
228
  i: integer;
171
  t: TFieldType;
229
  t: TFieldType;
172
  err: TLevelError;
230
  err: TLevelError;
173
  y: Integer;
231
  y: Integer;
174
  x: Integer;
232
  x: Integer;
175
  Line: string;
233
  Line: string;
176
  lch, uch: char;
234
  lch, uch: char;
177
  ch: char;
235
  ch: char;
178
begin
236
begin
179
  // Zuerst nach Fehlern suchen
237
  // Zuerst nach Fehlern suchen
180
  err := CheckLevelIntegrity(ShowErrors);
238
  err := CheckLevelIntegrity(ShowErrors);
181
  if err <> leNone then exit;
239
  if err <> leNone then exit;
182
 
240
 
183
  // Nun Matrix aufbauen
241
  // Nun Matrix aufbauen
184
  SetLength(result, 0);
242
  SetLength(result, 0);
185
  for i := NUM_HEADERS to FStringList.Count-1 do
243
  for i := NUM_HEADERS to FStringList.Count-1 do
186
  begin
244
  begin
187
    y := i - NUM_HEADERS;
245
    y := i - NUM_HEADERS;
188
 
246
 
189
    SetLength(result, Length(result)+1); // add line to matrix
247
    SetLength(result, Length(result)+1); // add line to matrix
190
 
248
 
191
    Line := FStringList.Strings[i];
249
    Line := FStringList.Strings[i];
192
    result[y].Indent := DotsAtBeginning(Line) - DotsAtEnd(Line);
250
    result[y].Indent := DotsAtBeginning(Line) - DotsAtEnd(Line);
193
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
251
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
194
    SetLength(result[y].Fields, Length(Line));
252
    SetLength(result[y].Fields, Length(Line));
195
 
253
 
196
    for x := 0 to Length(Line)-1 do
254
    for x := 0 to Length(Line)-1 do
197
    begin
255
    begin
198
      ch := Line[x+1];
256
      ch := Line[x+1];
199
      lch := LowerCase(ch)[1];
257
      lch := LowerCase(ch)[1];
200
      uch := UpperCase(ch)[1];
258
      uch := UpperCase(ch)[1];
201
 
259
 
202
      t := ftUndefined;
260
      t := ftUndefined;
203
      case lch of
261
      case lch of
204
        '*': t := ftFullSpace;
262
        '*': t := ftFullSpace;
205
        'e': t := ftEmpty;
263
        'e': t := ftEmpty;
206
        'r': t := ftRed;
264
        'r': t := ftRed;
207
        'y': t := ftYellow;
265
        'y': t := ftYellow;
208
        'g': t := ftGreen;
266
        'g': t := ftGreen;
209
      end;
267
      end;
210
 
268
 
211
      result[y].Fields[x].Typ := t;
269
      result[y].Fields[x].Typ := t;
212
      result[y].Fields[x].Goal := (ch = uch) and (ch <> lch);
270
      result[y].Fields[x].Goal := (ch = uch) and (ch <> lch);
213
    end;
271
    end;
214
  end;
272
  end;
215
end;
273
end;
216
 
274
 
217
function TLevel.CheckLevelIntegrity(ShowErrors: boolean): TLevelError;
275
function TLevel.CheckLevelIntegrity(ShowErrors: boolean): TLevelError;
218
resourcestring
276
resourcestring
219
  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 *.';
277
  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 *.';
220
  LNG_LVL_UNSUPPORTED_VERSION = 'Level format invalid: Version not supported.';
278
  LNG_LVL_UNSUPPORTED_VERSION = 'Level format invalid: Version not supported.';
221
  LNG_LVL_UNSUPPORTED_MODE = 'Level format invalid: Mode not supported.';
279
  LNG_LVL_UNSUPPORTED_MODE = 'Level format invalid: Mode not supported.';
222
  LNG_LVL_EMPTY_BOARD = 'Level invalid: Board is empty.';
280
  LNG_LVL_EMPTY_BOARD = 'Level invalid: Board is empty.';
223
  LNG_LVL_INVALID_LENGTH = 'Level invalid: Lines don''t have an equal amount of elements.';
281
  LNG_LVL_INVALID_LENGTH = 'Level invalid: Lines don''t have an equal amount of elements.';
224
begin
282
begin
225
  result := CheckLevelIntegrity;
283
  result := CheckLevelIntegrity;
226
  if ShowErrors then
284
  if ShowErrors then
227
  begin
285
  begin
228
    case result of
286
    case result of
229
      leNone: ;
287
      leNone: ;
230
      leInvalidElement: MessageDlg(LNG_LVL_INVALID_ELEMENT, mtError, [mbOk], 0);
288
      leInvalidElement: MessageDlg(LNG_LVL_INVALID_ELEMENT, mtError, [mbOk], 0);
231
      leUnsupportedVersion: MessageDlg(LNG_LVL_UNSUPPORTED_VERSION, mtError, [mbOk], 0);
289
      leUnsupportedVersion: MessageDlg(LNG_LVL_UNSUPPORTED_VERSION, mtError, [mbOk], 0);
232
      leUnsupportedMode: MessageDlg(LNG_LVL_UNSUPPORTED_MODE, mtError, [mbOk], 0);
290
      leUnsupportedMode: MessageDlg(LNG_LVL_UNSUPPORTED_MODE, mtError, [mbOk], 0);
233
      leEmptyBoard: MessageDlg(LNG_LVL_EMPTY_BOARD, mtError, [mbOk], 0);
291
      leEmptyBoard: MessageDlg(LNG_LVL_EMPTY_BOARD, mtError, [mbOk], 0);
234
      leRowInvalidLength: MessageDlg(LNG_LVL_INVALID_LENGTH, mtError, [mbOk], 0);
292
      leRowInvalidLength: MessageDlg(LNG_LVL_INVALID_LENGTH, mtError, [mbOk], 0);
235
    end;
293
    end;
236
  end;
294
  end;
237
end;
295
end;
238
 
296
 
239
function TLevel.CheckLevelIntegrity: TLevelError;
297
function TLevel.CheckLevelIntegrity: TLevelError;
240
var
298
var
241
  tmp: string;
299
  tmp: string;
242
  i: Integer;
300
  i: Integer;
243
  Line: string;
301
  Line: string;
244
  firstLine: string;
302
  firstLine: string;
245
  thisLine: string;
303
  thisLine: string;
246
begin
304
begin
247
  result := leNone;
305
  result := leNone;
248
 
306
 
249
  // Check 1: Ist der Header OK?
307
  // Check 1: Ist der Header OK?
250
 
308
 
251
  if LowerCase(FStringList.Strings[0]) <> 'version 2' then
309
  if LowerCase(FStringList.Strings[0]) <> 'version 2' then
252
  begin
310
  begin
253
    result := leUnsupportedVersion;
311
    result := leUnsupportedVersion;
254
    exit;
312
    exit;
255
  end;
313
  end;
256
 
314
 
257
  if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and (LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then
315
  if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and (LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then
258
  begin
316
  begin
259
    result := leUnsupportedMode;
317
    result := leUnsupportedMode;
260
    exit;
318
    exit;
261
  end;
319
  end;
262
 
320
 
263
  // Check 2: Ist das Brett leer?
321
  // Check 2: Ist das Brett leer?
264
 
322
 
265
  tmp := '';
323
  tmp := '';
266
  for i := NUM_HEADERS to FStringList.Count-1 do tmp := tmp + FStringList.Strings[i];
324
  for i := NUM_HEADERS to FStringList.Count-1 do tmp := tmp + FStringList.Strings[i];
267
  if Trim(StringReplace(tmp, '.', '', [rfReplaceAll])) = '' then
325
  if Trim(StringReplace(tmp, '.', '', [rfReplaceAll])) = '' then
268
  begin
326
  begin
269
    result := leEmptyBoard;
327
    result := leEmptyBoard;
270
    exit;
328
    exit;
271
  end;
329
  end;
272
 
330
 
273
  // Check 3: Geht das Level nicht in einem Quadrat oder Rechteck auf?
331
  // Check 3: Geht das Level nicht in einem Quadrat oder Rechteck auf?
274
 
332
 
275
  firstLine := StringReplace(FStringList.Strings[NUM_HEADERS], '.', '', [rfReplaceAll]);
333
  firstLine := StringReplace(FStringList.Strings[NUM_HEADERS], '.', '', [rfReplaceAll]);
276
  for i := NUM_HEADERS to FStringList.Count-1 do
334
  for i := NUM_HEADERS to FStringList.Count-1 do
277
  begin
335
  begin
278
    thisLine := StringReplace(FStringList.Strings[i], '.', '', [rfReplaceAll]);
336
    thisLine := StringReplace(FStringList.Strings[i], '.', '', [rfReplaceAll]);
279
    if Length(thisLine) <> Length(firstLine) then
337
    if Length(thisLine) <> Length(firstLine) then
280
    begin
338
    begin
281
      result := leRowInvalidLength; // at row y-NUM_HEADERS
339
      result := leRowInvalidLength; // at row y-NUM_HEADERS
282
      exit;
340
      exit;
283
    end;
341
    end;
284
  end;
342
  end;
285
 
343
 
286
  // Check 4: Gibt es ungültige Elemente in den Zeilen?
344
  // Check 4: Gibt es ungültige Elemente in den Zeilen?
287
 
345
 
288
  for i := NUM_HEADERS to FStringList.Count-1 do
346
  for i := NUM_HEADERS to FStringList.Count-1 do
289
  begin
347
  begin
290
    Line := FStringList.Strings[i];
348
    Line := FStringList.Strings[i];
291
 
349
 
292
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
350
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
293
    Line := StringReplace(Line, '*', '', [rfReplaceAll]);
351
    Line := StringReplace(Line, '*', '', [rfReplaceAll]);
294
    Line := StringReplace(Line, 'r', '', [rfReplaceAll, rfIgnoreCase]);
352
    Line := StringReplace(Line, 'r', '', [rfReplaceAll, rfIgnoreCase]);
295
    Line := StringReplace(Line, 'y', '', [rfReplaceAll, rfIgnoreCase]);
353
    Line := StringReplace(Line, 'y', '', [rfReplaceAll, rfIgnoreCase]);
296
    Line := StringReplace(Line, 'g', '', [rfReplaceAll, rfIgnoreCase]);
354
    Line := StringReplace(Line, 'g', '', [rfReplaceAll, rfIgnoreCase]);
297
    Line := StringReplace(Line, 'e', '', [rfReplaceAll, rfIgnoreCase]);
355
    Line := StringReplace(Line, 'e', '', [rfReplaceAll, rfIgnoreCase]);
298
 
356
 
299
    if Length(Line) > 0 then
357
    if Length(Line) > 0 then
300
    begin
358
    begin
301
      result := leInvalidElement; // at row y-NUM_HEADERS
359
      result := leInvalidElement; // at row y-NUM_HEADERS
302
      Exit;
360
      Exit;
303
    end;
361
    end;
304
  end;
362
  end;
305
 
363
 
306
  // Check 5: Kann im Level gesprungen werden
364
  // Check 5: Kann im Level gesprungen werden
307
 
365
 
308
  { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss.
366
  { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss.
309
    Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! }
367
    Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! }
310
end;
368
end;
311
 
369
 
312
end.
370
end.
313
 
371