Subversion Repositories jumper

Rev

Rev 9 | Rev 19 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9 Rev 11
Line 1... Line 1...
1
unit LevelFunctions;
1
unit LevelFunctions;
2
 
2
 
3
interface
3
interface
4
 
4
 
5
uses
5
uses
6
  SysUtils, Dialogs, Functions, ExtCtrls, Graphics;
6
  SysUtils, Dialogs, Functions, ExtCtrls, Graphics, Classes, Math;
7
 
7
 
8
type
8
type
9
  TFieldType = (ftLocked, ftLockedWithTab, ftEmpty, ftGreen, ftYellow, ftRed);
9
  TFieldType = (ftFullSpace, ftHalfSpace, 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
  TLevelType = (ltStandard, ltDiagonal, ltError);
16
  TGameMode = (gmUndefined, gmNormal, gmDiagonal);
17
 
17
 
18
  TLevelArray = array of array of TFieldProperties;
18
  TLevelArray = array of array of TFieldProperties;
19
 
19
 
20
  TLevelError = (leNone, leInvalidElement, leNoIndicator, leMultipleIndicator,
20
  TLevelError = (leNone, leInvalidElement, leEmptyBoard, leRowInvalidLength,
21
                 leLevelIncomplete, leHeaderError, leInvalidGoal);
21
                 leUnsupportedVersion, leUnsupportedMode);
22
 
22
 
-
 
23
  TLevel = class(TObject)
-
 
24
  private
-
 
25
    FStringList: TStringList;
23
procedure DrawLevelPreview(LevelString: string; Image: TImage; BackgroundColor: TColor);
26
    procedure Load(ABoardFile: string);
-
 
27
  public
24
function GetLevelType(LevelString: string): TLevelType;
28
    constructor Create(ABoardFile: string);
-
 
29
    destructor Destroy; override;
25
function CheckLevelIntegrity(LevelString: string; ShowErrors: boolean): TLevelError; overload;
30
    function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray;
26
function CheckLevelIntegrity(LevelString: string): TLevelError; overload;
31
    function CheckLevelIntegrity: TLevelError; overload;
27
function LevelStringToLevelArray(LevelString: string; ShowErrors: boolean): TLevelArray;
32
    function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload;
28
function FieldTypeWorth(t: TFieldType): integer;
33
    function GetGameMode: TGameMode;
-
 
34
  end;
29
 
35
 
30
var
-
 
-
 
36
procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor);
31
  AllowDiagonalMoves: boolean;
37
function FieldTypeWorth(t: TFieldType): integer;
32
 
38
 
33
implementation
39
implementation
34
 
40
 
35
const
-
 
36
  PREVIEW_BLOCK_SIZE = 10; // Enthält Field und Abstand
-
 
37
  PREVIEW_TAB_SIZE = PREVIEW_BLOCK_SIZE div 2; // 5
-
 
38
  HEADER_SIZE = 3;
-
 
39
  ERED = '3';
-
 
40
  EYEL = '2';
-
 
41
  EGRE = '1';
-
 
42
  ELOC = 'X';
-
 
43
  EEMP = 'E';
-
 
44
  EIND = '!';
-
 
45
  ETAR = '>';
-
 
46
  ESPE = '*';
-
 
47
  TY_DIA = 'D';
-
 
48
  TY_NOR = 'N';
-
 
49
 
-
 
50
resourcestring
-
 
51
  LNG_LVL_INVALID_ELEMENT = 'Level invalid: There are invalid elements in the file.'+#13#10#13#10+'Valid elements are "1", "2", "3", "X", "*", "E" and ">" as goal prefix.';
-
 
52
  LNG_LVL_INVALID_WIDTH = 'Level invalid: No width indicator ("!") found.';
-
 
53
  LNG_LVL_INVALID_HEIGHT_MUTLIPLE = 'Level invalid: The level''s actual length is not a multiple of the width.';
-
 
54
  LNG_LVL_INVALID_MULTIPLE_WIND = 'Level invalid: There are multiple width indicators ("!").';
-
 
55
  LNG_LVL_INVALID_HEADER = 'Level invalid: The header is invalid. It does not match the structure "1(D|N)~".';
-
 
56
  LNG_INVALID_GOAL = 'Level invalid: A goal does not point to a valid accessable element ("3", "2", "1" or "E").';
-
 
57
 
-
 
58
procedure DrawLevelPreview(LevelString: string; Image: TImage; BackgroundColor: TColor);
41
procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor);
59
var
42
var
60
  LevelArray: TLevelArray;
43
  LevelArray: TLevelArray;
61
  i, j: integer;
44
  y, x: integer;
62
  t: TFieldType;
45
  t: TFieldType;
63
  halftabs: integer;
46
  halftabs: integer;
-
 
47
const
-
 
48
  PREVIEW_BLOCK_SIZE = 10; // Enthält Field und Abstand
-
 
49
  PREVIEW_TAB_SIZE = PREVIEW_BLOCK_SIZE div 2; // 5
64
begin
50
begin
65
  LevelArray := nil;
51
  LevelArray := nil;
66
 
52
 
67
  ClearImage(Image, BackgroundColor);
53
  ClearImage(Image, BackgroundColor);
68
 
54
 
69
  LevelArray := LevelStringToLevelArray(LevelString, false);
55
  LevelArray := Level.LevelStringToLevelArray(false);
70
 
56
 
71
  for i := Low(LevelArray) to High(LevelArray) do
57
  for y := Low(LevelArray) to High(LevelArray) do
72
  begin
58
  begin
73
    halftabs := 0;
59
    halftabs := 0;
74
    for j := Low(LevelArray[i]) to High(LevelArray[i]) do
60
    for x := Low(LevelArray[y]) to High(LevelArray[y]) do
75
    begin
61
    begin
76
      t := LevelArray[i][j].Typ;
62
      t := LevelArray[y][x].Typ;
77
 
63
 
78
      case t of
64
      case t of
79
        ftLocked: Image.Canvas.Brush.Color := BackgroundColor;
65
        ftFullSpace: Image.Canvas.Brush.Color := BackgroundColor;
80
        ftLockedWithTab: begin
66
        ftHalfSpace: begin
81
          Image.Canvas.Brush.Color := BackgroundColor;
67
          Image.Canvas.Brush.Color := BackgroundColor;
82
          inc(halftabs);
68
          inc(halftabs);
83
        end;
69
        end;
84
        ftEmpty: Image.Canvas.Brush.Color := clWhite;
70
        ftEmpty: Image.Canvas.Brush.Color := clWhite;
85
        ftGreen: Image.Canvas.Brush.Color := clLime;
71
        ftGreen: Image.Canvas.Brush.Color := clLime;
86
        ftYellow: Image.Canvas.Brush.Color := clYellow;
72
        ftYellow: Image.Canvas.Brush.Color := clYellow;
87
        ftRed: Image.Canvas.Brush.Color := clRed;
73
        ftRed: Image.Canvas.Brush.Color := clRed;
88
      end;
74
      end;
89
 
75
 
90
      if LevelArray[i][j].Goal then
76
      if LevelArray[y][x].Goal then
91
        Image.Canvas.Pen.Color := clBlack
77
        Image.Canvas.Pen.Color := clBlack
92
      else
78
      else
93
        Image.Canvas.Pen.Color := BackgroundColor;
79
        Image.Canvas.Pen.Color := BackgroundColor;
94
 
80
 
-
 
81
      Image.Canvas.Rectangle((x-halftabs)*PREVIEW_BLOCK_SIZE + halftabs*PREVIEW_TAB_SIZE,
-
 
82
                             y*PREVIEW_BLOCK_SIZE,
95
      Image.Canvas.Rectangle(j*PREVIEW_BLOCK_SIZE - halftabs*PREVIEW_TAB_SIZE, i*PREVIEW_BLOCK_SIZE, j*PREVIEW_BLOCK_SIZE - halftabs*PREVIEW_TAB_SIZE+PREVIEW_BLOCK_SIZE, i*PREVIEW_BLOCK_SIZE+PREVIEW_BLOCK_SIZE);
83
                             (x-halftabs)*PREVIEW_BLOCK_SIZE + halftabs*PREVIEW_TAB_SIZE + PREVIEW_BLOCK_SIZE,
-
 
84
                             y*PREVIEW_BLOCK_SIZE                                        + PREVIEW_BLOCK_SIZE);
96
    end;
85
    end;
97
  end;
86
  end;
98
end;
87
end;
99
 
88
 
100
function GetLevelType(LevelString: string): TLevelType;
89
function FieldTypeWorth(t: TFieldType): integer;
101
begin
-
 
102
  if CheckLevelIntegrity(LevelString) = leNone then
-
 
103
  begin
-
 
104
    if Copy(LevelString, 2, 1) = TY_DIA then
-
 
105
    begin
-
 
106
      result := ltDiagonal;
-
 
107
    end
-
 
108
    else // if Copy(LevelString, 2, 1) = TY_NOR
-
 
109
    begin
90
begin
-
 
91
  if t = ftGreen then result := 10
-
 
92
  else if t = ftYellow then result := 20
-
 
93
  else if t = ftRed then result := 30
110
      result := ltStandard;
94
  else result := 0;
111
    end;
95
end;
112
  end
96
 
113
  else
97
{ TLevel }
-
 
98
 
-
 
99
const NUM_HEADERS = 2;
-
 
100
 
-
 
101
constructor TLevel.Create(ABoardFile: string);
114
  begin
102
begin
115
    result := ltError;
103
  inherited Create;
-
 
104
  FStringList := TStringList.Create;
116
  end;
105
  Load(ABoardFile);
117
end;
106
end;
118
 
107
 
119
procedure ShowErrorMessage(error: TLevelError);
108
destructor TLevel.Destroy;
120
begin
109
begin
121
  case error of
110
  FreeAndNil(FStringList);
-
 
111
 
122
    leNone: ;
112
  inherited;
123
    leInvalidElement: MessageDlg(LNG_LVL_INVALID_ELEMENT, mtError, [mbOk], 0);
-
 
124
    leNoIndicator: MessageDlg(LNG_LVL_INVALID_WIDTH, mtError, [mbOk], 0);
-
 
125
    leMultipleIndicator: MessageDlg(LNG_LVL_INVALID_MULTIPLE_WIND, mtError, [mbOk], 0);
-
 
126
    leLevelIncomplete: MessageDlg(LNG_LVL_INVALID_HEIGHT_MUTLIPLE, mtError, [mbOk], 0);
-
 
127
    leHeaderError: MessageDlg(LNG_LVL_INVALID_HEADER, mtError, [mbOk], 0);
-
 
128
    leInvalidGoal: MessageDlg(LNG_INVALID_GOAL, mtError, [mbOk], 0);
-
 
129
  end;
-
 
130
end;
113
end;
131
 
114
 
132
function CheckLevelIntegrity(LevelString: string; ShowErrors: boolean): TLevelError;
115
function TLevel.GetGameMode: TGameMode;
133
begin
116
begin
-
 
117
  if LowerCase(FStringList.Strings[1]) = 'mode: normal' then
134
  result := CheckLevelIntegrity(LevelString);
118
    result := gmNormal
135
  if ShowErrors then ShowErrorMessage(result);
119
  else if LowerCase(FStringList.Strings[1]) = 'mode: diagonal' then
-
 
120
    result := gmDiagonal
-
 
121
  else
-
 
122
    result := gmUndefined;
136
end;
123
end;
137
 
124
 
138
function CheckLevelIntegrity(LevelString: string): TLevelError;
125
procedure TLevel.Load(ABoardFile: string);
139
var
126
var
140
  W: integer;
127
  i: Integer;
141
  H: extended;
-
 
142
  header, h_ver, h_dia, h_del, tmp: string;
-
 
143
  p: integer;
-
 
144
begin
128
begin
145
  result := leNone;
129
  FStringList.Clear;
146
 
-
 
147
  // Entfernt die Zeilenumbrüche
130
  FStringList.LoadFromFile(ABoardFile);
148
 
131
 
149
  LevelString := RemoveLineBreaks(LevelString);
-
 
150
 
-
 
151
  // Check 1: Ist der Header OK?
132
  // Remove whitespaces and empty lines
152
 
-
 
153
  header := copy(LevelString, 1, HEADER_SIZE);
133
  for i := FStringList.Count-1 downto NUM_HEADERS do
154
 
-
 
155
  h_ver := copy(header, 1, 1);
-
 
156
  if h_ver <> '1' then
-
 
157
  begin
134
  begin
-
 
135
    FStringList.Strings[i] := StringReplace(FStringList.Strings[i], ' ', '', [rfReplaceAll]);
158
    result := leHeaderError;
136
    if FStringList.Strings[i] = '' then FStringList.Delete(i);
159
    Exit;
137
  end;
160
  end;
138
end;
161
 
139
 
-
 
140
function TLevel.LevelStringToLevelArray(ShowErrors: boolean): TLevelArray;
-
 
141
var
-
 
142
  i: integer;
-
 
143
  t: TFieldType;
-
 
144
  err: TLevelError;
-
 
145
  longestLine: Integer;
162
  h_dia := copy(header, 2, 1);
146
  thisLine: Integer;
-
 
147
  y: Integer;
-
 
148
  x: Integer;
-
 
149
  Line: string;
163
  if (h_dia <> TY_DIA) and (h_dia <> TY_NOR) then
150
  lch, uch: char;
-
 
151
  ch: char;
164
  begin
152
begin
165
    result := leHeaderError;
153
  // Zuerst nach Fehlern suchen
166
    Exit;
154
  err := CheckLevelIntegrity(ShowErrors);
167
  end;
155
  if err <> leNone then exit;
168
 
156
 
169
  h_del := copy(header, 3, 1);
157
  // Längste Zeile finden
170
  if h_del <> '~' then
158
  longestLine := 0;
-
 
159
  for i := NUM_HEADERS to FStringList.Count-1 do
171
  begin
160
  begin
172
    result := leHeaderError;
161
    longestLine := Max(longestLine, Length(FStringList.Strings[i]));
173
    Exit;
-
 
174
  end;
162
  end;
175
 
163
 
-
 
164
  // Nun Matrix aufbauen
-
 
165
  SetLength(result, 0);
176
  LevelString := copy(LevelString, HEADER_SIZE+1, Length(LevelString)-HEADER_SIZE);
166
  for i := NUM_HEADERS to FStringList.Count-1 do
-
 
167
  begin
-
 
168
    y := i - NUM_HEADERS;
177
 
169
 
178
  // Check 2: Steht das ggf. vorhandenen ">" vor einem gültigen Feld 1, 2, 3, E?
170
    SetLength(result, Length(result)+1); // add line to matrix
-
 
171
    SetLength(result[y], longestLine);
179
 
172
 
180
  p := Position(LevelString, ETAR);
173
    Line := FStringList.Strings[i];
181
 
174
 
182
  while (p <> -1) do
175
    for x := 0 to LongestLine-1 do
183
  begin
176
    begin
184
    tmp := copy(LevelString, p+1, 1);
177
      ch := Copy(Line,x+1,1)[1];
185
 
-
 
-
 
178
      lch := LowerCase(ch)[1];
186
    if (tmp <> EEMP) and (tmp <> EGRE) and (tmp <> EYEL) and (tmp <> ERED) then
179
      uch := UpperCase(ch)[1];
187
    begin
180
      case lch of
-
 
181
        '*': t := ftFullSpace;
188
      result := leInvalidGoal;
182
        '.': t := ftHalfSpace;
-
 
183
        'e': t := ftEmpty;
189
      Exit;
184
        'r': t := ftRed;
-
 
185
        'y': t := ftYellow;
-
 
186
        'g': t := ftGreen;
190
    end;
187
      end;
191
 
188
 
-
 
189
      result[y][x].Typ := t;
192
    LevelString := StringReplace(LevelString, ETAR, '', []); // Dieses Ziel entfernen
190
      result[y][x].Goal := (ch = uch) and (ch <> lch);
193
 
191
    end;
194
    p := Position(LevelString, ETAR);
192
  end;
195
  end;
193
end;
196
 
194
 
197
  // Check 3: Kommt überhaupt ein "!" vor?
195
function TLevel.CheckLevelIntegrity(ShowErrors: boolean): TLevelError;
198
 
-
 
199
  W := Position(LevelString, EIND);
196
resourcestring
200
 
-
 
-
 
197
  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 *.';
-
 
198
  LNG_LVL_UNSUPPORTED_VERSION = 'Level format invalid: Version not supported.';
-
 
199
  LNG_LVL_UNSUPPORTED_MODE = 'Level format invalid: Mode not supported.';
201
  if W = -1 then
200
  LNG_LVL_EMPTY_BOARD = 'Level invalid: Board is empty.';
-
 
201
  LNG_LVL_INVALID_LENGTH = 'Level invalid: Lines don''t have an equal amount of elements.';
202
  begin
202
begin
203
    result := leNoIndicator;
203
  result := CheckLevelIntegrity;
-
 
204
  if ShowErrors then
-
 
205
  begin
-
 
206
    case result of
-
 
207
      leNone: ;
-
 
208
      leInvalidElement: MessageDlg(LNG_LVL_INVALID_ELEMENT, mtError, [mbOk], 0);
-
 
209
      leUnsupportedVersion: MessageDlg(LNG_LVL_UNSUPPORTED_VERSION, mtError, [mbOk], 0);
-
 
210
      leUnsupportedMode: MessageDlg(LNG_LVL_UNSUPPORTED_MODE, mtError, [mbOk], 0);
-
 
211
      leEmptyBoard: MessageDlg(LNG_LVL_EMPTY_BOARD, mtError, [mbOk], 0);
-
 
212
      leRowInvalidLength: MessageDlg(LNG_LVL_INVALID_LENGTH, mtError, [mbOk], 0);
204
    Exit;
213
    end;
-
 
214
  end;
205
  end;
215
end;
206
 
216
 
-
 
217
function TLevel.CheckLevelIntegrity: TLevelError;
-
 
218
var
-
 
219
  W: integer;
-
 
220
  H: extended;
207
  // Check 4: Kam das "!" mehrmals vor?
221
  header, h_ver, h_dia, h_del, tmp: string;
-
 
222
  p: integer;
-
 
223
  i: Integer;
-
 
224
  Line: string;
-
 
225
begin
-
 
226
  result := leNone;
208
 
227
 
209
  LevelString := StringReplace(LevelString, EIND, '', []); // Das Erste entfernen
228
  // Check 1: Ist der Header OK?
210
 
229
 
211
  if Position(LevelString, EIND) <> -1 then // gibt es ein Zweites?
230
  if LowerCase(FStringList.Strings[0]) <> 'version 2' then
212
  begin
231
  begin
213
    result := leMultipleIndicator;
232
    result := leUnsupportedVersion;
214
    Exit;
233
    exit;
215
  end;
234
  end;
216
 
235
 
217
  // Check 5: Geht das Level nicht in einem Quadrat oder Rechteck auf?
236
  if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and (LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then
218
 
-
 
219
  H := (Length(LevelString) - 1) / W;
-
 
220
 
-
 
221
  if not Ganzzahlig(H) then
-
 
222
  begin
237
  begin
223
    result := leLevelIncomplete;
238
    result := leUnsupportedMode;
224
    Exit;
239
    exit;
225
  end;
240
  end;
226
 
241
 
227
  // Check 6: Gibt es ungültige Elemente im LevelString?
242
  // Check 2: Ist das Brett leer?
228
 
243
 
229
  LevelString := StringReplace(LevelString, ESPE, '', [rfReplaceAll]);
-
 
230
  LevelString := StringReplace(LevelString, ELOC, '', [rfReplaceAll]);
-
 
231
  LevelString := StringReplace(LevelString, EEMP, '', [rfReplaceAll]);
-
 
232
  LevelString := StringReplace(LevelString, EGRE, '', [rfReplaceAll]);
-
 
233
  LevelString := StringReplace(LevelString, EYEL, '', [rfReplaceAll]);
-
 
234
  LevelString := StringReplace(LevelString, ERED, '', [rfReplaceAll]);
-
 
235
 
-
 
236
  if Length(LevelString) > 0 then
244
  if FStringList.Count - NUM_HEADERS = 0 then
237
  begin
245
  begin
238
    result := leInvalidElement;
246
    result := leEmptyBoard;
239
    Exit;
247
    exit;
240
  end;
248
  end;
241
 
249
 
242
  // Check 7: Kann im Level gesprungen werden
250
  // Check 3: Geht das Level nicht in einem Quadrat oder Rechteck auf?
243
 
-
 
244
  { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss.
-
 
245
    Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! }
-
 
246
end;
-
 
247
 
251
 
248
function LevelStringToLevelArray(LevelString: string; ShowErrors: boolean): TLevelArray;
-
 
249
var
-
 
250
  i, j, j_dec, c: integer;
252
  for i := NUM_HEADERS to FStringList.Count-1 do
251
  m: string;
-
 
252
  t: TFieldType;
-
 
253
  W, H: integer;
-
 
254
  err: TLevelError;
-
 
255
  NextIsGoal: boolean;
-
 
256
begin
253
  begin
-
 
254
    if Length(FStringList.Strings[i]) <> Length(FStringList.Strings[NUM_HEADERS]) then
257
  // Zuerst nach Fehlern suchen
255
    begin
258
  err := CheckLevelIntegrity(LevelString, ShowErrors);
256
      result := leRowInvalidLength; // at row y-NUM_HEADERS
259
  if err <> leNone then exit;
257
      exit;
260
 
-
 
261
  // Headerinformationen auslesen
258
    end;
262
  AllowDiagonalMoves := copy(LevelString, 2, 1) = TY_DIA;
-
 
263
 
-
 
264
  // Header entfernen
259
  end;
265
  LevelString := copy(LevelString, HEADER_SIZE+1, Length(LevelString)-HEADER_SIZE);
-
 
266
 
260
 
267
  // Entfernt die Zeilenumbrüche
-
 
268
  LevelString := RemoveLineBreaks(LevelString);
261
  // Check 4: Gibt es ungültige Elemente in den Zeilen?
269
 
262
 
270
  // Dimensionen abmessen
-
 
271
  W := Position(StringReplace(LevelString, ETAR, '', [rfReplaceAll]), EIND) - 1;
-
 
272
  LevelString := StringReplace(LevelString, EIND, '', [rfReplaceAll]);
263
  for i := NUM_HEADERS to FStringList.Count-1 do
-
 
264
  begin
273
  H := Length(LevelString) div W;
265
    Line := FStringList.Strings[i];
274
 
266
 
275
  c := 1;
267
    Line := StringReplace(Line, '.', '', [rfReplaceAll]);
276
  NextIsGoal := false;
268
    Line := StringReplace(Line, '*', '', [rfReplaceAll]);
-
 
269
    Line := StringReplace(Line, 'r', '', [rfReplaceAll, rfIgnoreCase]);
-
 
270
    Line := StringReplace(Line, 'y', '', [rfReplaceAll, rfIgnoreCase]);
-
 
271
    Line := StringReplace(Line, 'g', '', [rfReplaceAll, rfIgnoreCase]);
-
 
272
    Line := StringReplace(Line, 'e', '', [rfReplaceAll, rfIgnoreCase]);
277
 
273
 
278
  SetLength(result, round(H));
-
 
279
  for i := Low(result) to High(result) do
-
 
280
  begin
-
 
281
    j_dec := 0;
-
 
282
    SetLength(result[i], round(W));
274
    if Length(Line) > 0 then
283
    for j := Low(result[i]) to High(result[i])+1 do  // +1 wegen dem möglichen zusätzlichem ">"
-
 
284
    begin
-
 
285
      if (j = High(result[i])+1) and (j_dec = 0) then break;
-
 
286
      m := Copy(LevelString, c, 1);
-
 
287
      if m = ETAR then
-
 
288
      begin
275
    begin
289
        NextIsGoal := true;
-
 
290
        inc(j_dec);
-
 
291
      end
-
 
292
      else
-
 
293
      begin
-
 
294
             if m = EEMP then t := ftEmpty
-
 
295
        else if m = EGRE then t := ftGreen
-
 
296
        else if m = EYEL then t := ftYellow
-
 
297
        else if m = ERED then t := ftRed
-
 
298
        else if m = ESPE then t := ftLockedWithTab
276
      result := leInvalidElement; // at row y-NUM_HEADERS
299
        else t := ftLocked;
-
 
300
        result[i][j-j_dec].Typ := t;
-
 
301
        result[i][j-j_dec].Goal := NextIsGoal;
-
 
302
        if NextIsGoal then NextIsGoal := false;
-
 
303
      end;
277
      Exit;
304
      inc(c);
-
 
305
    end;
-
 
306
  end;
278
    end;
307
end;
279
  end;
308
 
280
 
309
function FieldTypeWorth(t: TFieldType): integer;
281
  // Check 5: Kann im Level gesprungen werden
310
begin
282
 
311
  if t = ftGreen then result := 10
-
 
312
  else if t = ftYellow then result := 20
283
  { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss.
313
  else if t = ftRed then result := 30
284
    Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! }
314
  else result := 0;
-
 
315
end;
285
end;
316
 
286
 
317
end.
287
end.