Rev 11 | Rev 21 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 11 | Rev 19 | ||
---|---|---|---|
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, Graphics, Classes, Math; |
7 | 7 | ||
8 | type |
8 | type |
9 | TFieldType = (ftFullSpace, ftHalfSpace, 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 |
|
- | 19 | Indent: integer; |
|
18 | TLevelArray = array of array of TFieldProperties; |
20 | Fields: array of TFieldProperties; |
- | 21 | end; |
|
- | 22 | TLevelArray = array of TRow; |
|
19 | 23 | ||
20 | TLevelError = (leNone, leInvalidElement, leEmptyBoard, leRowInvalidLength, |
24 | TLevelError = (leUndefined, leNone, leInvalidElement, leEmptyBoard, leRowInvalidLength, |
21 | leUnsupportedVersion, leUnsupportedMode); |
25 | leUnsupportedVersion, leUnsupportedMode); |
22 | 26 | ||
23 | TLevel = class(TObject) |
27 | TLevel = class(TObject) |
24 | private |
28 | private |
25 | FStringList: TStringList; |
29 | FStringList: TStringList; |
26 | procedure Load(ABoardFile: string); |
30 | procedure Load(ABoardFile: string); |
27 | public |
31 | public |
28 | constructor Create(ABoardFile: string); |
32 | constructor Create(ABoardFile: string); |
29 | destructor Destroy; override; |
33 | destructor Destroy; override; |
30 | function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
34 | function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
31 | function CheckLevelIntegrity: TLevelError; overload; |
35 | function CheckLevelIntegrity: TLevelError; overload; |
32 | function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload; |
36 | function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload; |
33 | function GetGameMode: TGameMode; |
37 | function GetGameMode: TGameMode; |
34 | end; |
38 | end; |
35 | 39 | ||
36 | procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor); |
40 | procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor); |
37 | function FieldTypeWorth(t: TFieldType): integer; |
41 | function FieldTypeWorth(t: TFieldType): integer; |
38 | 42 | ||
39 | implementation |
43 | implementation |
40 | 44 | ||
41 | procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor); |
45 | procedure DrawLevelPreview(Level: TLevel; Image: TImage; BackgroundColor: TColor); |
42 | var |
46 | var |
43 | LevelArray: TLevelArray; |
47 | LevelArray: TLevelArray; |
44 | y, x: integer; |
48 | y, x: integer; |
45 | t: TFieldType; |
49 | t: TFieldType; |
46 | halftabs: integer; |
50 | indent: Integer; |
47 | const |
51 | const |
48 | PREVIEW_BLOCK_SIZE = 10; // Enthält Field und Abstand |
52 | PREVIEW_BLOCK_SIZE = 10; // Enthält Field und Abstand |
49 | PREVIEW_TAB_SIZE = PREVIEW_BLOCK_SIZE div 2; // 5 |
53 | PREVIEW_TAB_SIZE = PREVIEW_BLOCK_SIZE div 2; // 5 |
50 | begin |
54 | begin |
51 | LevelArray := nil; |
55 | LevelArray := nil; |
52 | 56 | ||
53 | ClearImage(Image, BackgroundColor); |
57 | ClearImage(Image, BackgroundColor); |
54 | 58 | ||
55 | LevelArray := Level.LevelStringToLevelArray(false); |
59 | LevelArray := Level.LevelStringToLevelArray(false); |
56 | 60 | ||
57 | for y := Low(LevelArray) to High(LevelArray) do |
61 | for y := Low(LevelArray) to High(LevelArray) do |
58 | begin |
62 | begin |
59 | halftabs := 0; |
- | |
60 | for x := Low(LevelArray[y]) to High(LevelArray[y]) do |
63 | for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do |
61 | begin |
64 | begin |
62 | t := LevelArray[y][x].Typ; |
65 | t := LevelArray[y].Fields[x].Typ; |
- | 66 | indent := LevelArray[y].Indent; |
|
63 | 67 | ||
64 | case t of |
68 | case t of |
65 | ftFullSpace: Image.Canvas.Brush.Color := BackgroundColor; |
69 | ftFullSpace: Image.Canvas.Brush.Color := BackgroundColor; |
66 | ftHalfSpace: begin |
- | |
67 | Image.Canvas.Brush.Color := BackgroundColor; |
- | |
68 | inc(halftabs); |
- | |
69 | end; |
- | |
70 | ftEmpty: Image.Canvas.Brush.Color := clWhite; |
70 | ftEmpty: Image.Canvas.Brush.Color := clWhite; |
71 | ftGreen: Image.Canvas.Brush.Color := clLime; |
71 | ftGreen: Image.Canvas.Brush.Color := clLime; |
72 | ftYellow: Image.Canvas.Brush.Color := clYellow; |
72 | ftYellow: Image.Canvas.Brush.Color := clYellow; |
73 | ftRed: Image.Canvas.Brush.Color := clRed; |
73 | ftRed: Image.Canvas.Brush.Color := clRed; |
74 | end; |
74 | end; |
75 | 75 | ||
76 | if LevelArray[y][x].Goal then |
76 | if LevelArray[y].Fields[x].Goal then |
77 | Image.Canvas.Pen.Color := clBlack |
77 | Image.Canvas.Pen.Color := clBlack |
78 | else |
78 | else |
79 | Image.Canvas.Pen.Color := BackgroundColor; |
79 | Image.Canvas.Pen.Color := BackgroundColor; |
80 | 80 | ||
81 | Image.Canvas.Rectangle((x-halftabs)*PREVIEW_BLOCK_SIZE + halftabs*PREVIEW_TAB_SIZE, |
81 | Image.Canvas.Rectangle(x*PREVIEW_BLOCK_SIZE + indent*PREVIEW_TAB_SIZE, |
82 | y*PREVIEW_BLOCK_SIZE, |
82 | y*PREVIEW_BLOCK_SIZE, |
83 | (x-halftabs)*PREVIEW_BLOCK_SIZE + halftabs*PREVIEW_TAB_SIZE + PREVIEW_BLOCK_SIZE, |
83 | x*PREVIEW_BLOCK_SIZE + indent*PREVIEW_TAB_SIZE + PREVIEW_BLOCK_SIZE, |
84 | y*PREVIEW_BLOCK_SIZE + PREVIEW_BLOCK_SIZE); |
84 | y*PREVIEW_BLOCK_SIZE + PREVIEW_BLOCK_SIZE); |
85 | end; |
85 | end; |
86 | end; |
86 | end; |
87 | end; |
87 | end; |
88 | 88 | ||
89 | function FieldTypeWorth(t: TFieldType): integer; |
89 | function FieldTypeWorth(t: TFieldType): integer; |
90 | begin |
90 | begin |
91 | if t = ftGreen then result := 10 |
91 | if t = ftGreen then result := 10 |
92 | else if t = ftYellow then result := 20 |
92 | else if t = ftYellow then result := 20 |
93 | else if t = ftRed then result := 30 |
93 | else if t = ftRed then result := 30 |
94 | else result := 0; |
94 | else result := 0; |
95 | end; |
95 | end; |
96 | 96 | ||
97 | { TLevel } |
97 | { TLevel } |
98 | 98 | ||
99 | const NUM_HEADERS = 2; |
99 | const NUM_HEADERS = 2; |
100 | 100 | ||
101 | constructor TLevel.Create(ABoardFile: string); |
101 | constructor TLevel.Create(ABoardFile: string); |
102 | begin |
102 | begin |
103 | inherited Create; |
103 | inherited Create; |
104 | FStringList := TStringList.Create; |
104 | FStringList := TStringList.Create; |
105 | Load(ABoardFile); |
105 | Load(ABoardFile); |
106 | end; |
106 | end; |
107 | 107 | ||
108 | destructor TLevel.Destroy; |
108 | destructor TLevel.Destroy; |
109 | begin |
109 | begin |
110 | FreeAndNil(FStringList); |
110 | FreeAndNil(FStringList); |
111 | 111 | ||
112 | inherited; |
112 | inherited; |
113 | end; |
113 | end; |
114 | 114 | ||
115 | function TLevel.GetGameMode: TGameMode; |
115 | function TLevel.GetGameMode: TGameMode; |
116 | begin |
116 | begin |
117 | if LowerCase(FStringList.Strings[1]) = 'mode: normal' then |
117 | if LowerCase(FStringList.Strings[1]) = 'mode: normal' then |
118 | result := gmNormal |
118 | result := gmNormal |
119 | else if LowerCase(FStringList.Strings[1]) = 'mode: diagonal' then |
119 | else if LowerCase(FStringList.Strings[1]) = 'mode: diagonal' then |
120 | result := gmDiagonal |
120 | result := gmDiagonal |
121 | else |
121 | else |
122 | result := gmUndefined; |
122 | result := gmUndefined; |
123 | end; |
123 | end; |
124 | 124 | ||
125 | procedure TLevel.Load(ABoardFile: string); |
125 | procedure TLevel.Load(ABoardFile: string); |
126 | var |
126 | var |
127 | i: Integer; |
127 | i: Integer; |
128 | begin |
128 | begin |
129 | FStringList.Clear; |
129 | FStringList.Clear; |
130 | FStringList.LoadFromFile(ABoardFile); |
130 | FStringList.LoadFromFile(ABoardFile); |
131 | 131 | ||
132 | // Remove whitespaces and empty lines |
132 | // Remove whitespaces and empty lines |
133 | for i := FStringList.Count-1 downto NUM_HEADERS do |
133 | for i := FStringList.Count-1 downto NUM_HEADERS do |
134 | begin |
134 | begin |
135 | FStringList.Strings[i] := StringReplace(FStringList.Strings[i], ' ', '', [rfReplaceAll]); |
135 | FStringList.Strings[i] := StringReplace(FStringList.Strings[i], ' ', '', [rfReplaceAll]); |
136 | if FStringList.Strings[i] = '' then FStringList.Delete(i); |
136 | if FStringList.Strings[i] = '' then FStringList.Delete(i); |
137 | end; |
137 | end; |
138 | end; |
138 | end; |
139 | 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; |
|
- | 167 | ||
140 | function TLevel.LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
168 | function TLevel.LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
141 | var |
169 | var |
142 | i: integer; |
170 | i: integer; |
143 | t: TFieldType; |
171 | t: TFieldType; |
144 | err: TLevelError; |
172 | err: TLevelError; |
145 | longestLine: Integer; |
- | |
146 | thisLine: Integer; |
- | |
147 | y: Integer; |
173 | y: Integer; |
148 | x: Integer; |
174 | x: Integer; |
149 | Line: string; |
175 | Line: string; |
150 | lch, uch: char; |
176 | lch, uch: char; |
151 | ch: char; |
177 | ch: char; |
152 | begin |
178 | begin |
153 | // Zuerst nach Fehlern suchen |
179 | // Zuerst nach Fehlern suchen |
154 | err := CheckLevelIntegrity(ShowErrors); |
180 | err := CheckLevelIntegrity(ShowErrors); |
155 | if err <> leNone then exit; |
181 | if err <> leNone then exit; |
156 | 182 | ||
157 | // Längste Zeile finden |
- | |
158 | longestLine := 0; |
- | |
159 | for i := NUM_HEADERS to FStringList.Count-1 do |
- | |
160 | begin |
- | |
161 | longestLine := Max(longestLine, Length(FStringList.Strings[i])); |
- | |
162 | end; |
- | |
163 | - | ||
164 | // Nun Matrix aufbauen |
183 | // Nun Matrix aufbauen |
165 | SetLength(result, 0); |
184 | SetLength(result, 0); |
166 | for i := NUM_HEADERS to FStringList.Count-1 do |
185 | for i := NUM_HEADERS to FStringList.Count-1 do |
167 | begin |
186 | begin |
168 | y := i - NUM_HEADERS; |
187 | y := i - NUM_HEADERS; |
169 | 188 | ||
170 | SetLength(result, Length(result)+1); // add line to matrix |
189 | SetLength(result, Length(result)+1); // add line to matrix |
171 | SetLength(result[y], longestLine); |
- | |
172 | 190 | ||
173 | Line := FStringList.Strings[i]; |
191 | Line := FStringList.Strings[i]; |
- | 192 | result[y].Indent := DotsAtBeginning(Line) - DotsAtEnd(Line); |
|
- | 193 | Line := StringReplace(Line, '.', '', [rfReplaceAll]); |
|
- | 194 | SetLength(result[y].Fields, Length(Line)); |
|
174 | 195 | ||
175 | for x := 0 to LongestLine-1 do |
196 | for x := 0 to Length(Line)-1 do |
176 | begin |
197 | begin |
177 | ch := Copy(Line,x+1,1)[1]; |
198 | ch := Line[x+1]; |
178 | lch := LowerCase(ch)[1]; |
199 | lch := LowerCase(ch)[1]; |
179 | uch := UpperCase(ch)[1]; |
200 | uch := UpperCase(ch)[1]; |
- | 201 | ||
- | 202 | t := ftUndefined; |
|
180 | case lch of |
203 | case lch of |
181 | '*': t := ftFullSpace; |
204 | '*': t := ftFullSpace; |
182 | '.': t := ftHalfSpace; |
- | |
183 | 'e': t := ftEmpty; |
205 | 'e': t := ftEmpty; |
184 | 'r': t := ftRed; |
206 | 'r': t := ftRed; |
185 | 'y': t := ftYellow; |
207 | 'y': t := ftYellow; |
186 | 'g': t := ftGreen; |
208 | 'g': t := ftGreen; |
187 | end; |
209 | end; |
188 | 210 | ||
189 | result[y][x].Typ := t; |
211 | result[y].Fields[x].Typ := t; |
190 | result[y][x].Goal := (ch = uch) and (ch <> lch); |
212 | result[y].Fields[x].Goal := (ch = uch) and (ch <> lch); |
191 | end; |
213 | end; |
192 | end; |
214 | end; |
193 | end; |
215 | end; |
194 | 216 | ||
195 | function TLevel.CheckLevelIntegrity(ShowErrors: boolean): TLevelError; |
217 | function TLevel.CheckLevelIntegrity(ShowErrors: boolean): TLevelError; |
196 | resourcestring |
218 | resourcestring |
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 *.'; |
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 *.'; |
198 | LNG_LVL_UNSUPPORTED_VERSION = 'Level format invalid: Version not supported.'; |
220 | LNG_LVL_UNSUPPORTED_VERSION = 'Level format invalid: Version not supported.'; |
199 | LNG_LVL_UNSUPPORTED_MODE = 'Level format invalid: Mode not supported.'; |
221 | LNG_LVL_UNSUPPORTED_MODE = 'Level format invalid: Mode not supported.'; |
200 | LNG_LVL_EMPTY_BOARD = 'Level invalid: Board is empty.'; |
222 | 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.'; |
223 | LNG_LVL_INVALID_LENGTH = 'Level invalid: Lines don''t have an equal amount of elements.'; |
202 | begin |
224 | begin |
203 | result := CheckLevelIntegrity; |
225 | result := CheckLevelIntegrity; |
204 | if ShowErrors then |
226 | if ShowErrors then |
205 | begin |
227 | begin |
206 | case result of |
228 | case result of |
207 | leNone: ; |
229 | leNone: ; |
208 | leInvalidElement: MessageDlg(LNG_LVL_INVALID_ELEMENT, mtError, [mbOk], 0); |
230 | leInvalidElement: MessageDlg(LNG_LVL_INVALID_ELEMENT, mtError, [mbOk], 0); |
209 | leUnsupportedVersion: MessageDlg(LNG_LVL_UNSUPPORTED_VERSION, mtError, [mbOk], 0); |
231 | leUnsupportedVersion: MessageDlg(LNG_LVL_UNSUPPORTED_VERSION, mtError, [mbOk], 0); |
210 | leUnsupportedMode: MessageDlg(LNG_LVL_UNSUPPORTED_MODE, mtError, [mbOk], 0); |
232 | leUnsupportedMode: MessageDlg(LNG_LVL_UNSUPPORTED_MODE, mtError, [mbOk], 0); |
211 | leEmptyBoard: MessageDlg(LNG_LVL_EMPTY_BOARD, mtError, [mbOk], 0); |
233 | leEmptyBoard: MessageDlg(LNG_LVL_EMPTY_BOARD, mtError, [mbOk], 0); |
212 | leRowInvalidLength: MessageDlg(LNG_LVL_INVALID_LENGTH, mtError, [mbOk], 0); |
234 | leRowInvalidLength: MessageDlg(LNG_LVL_INVALID_LENGTH, mtError, [mbOk], 0); |
213 | end; |
235 | end; |
214 | end; |
236 | end; |
215 | end; |
237 | end; |
216 | 238 | ||
217 | function TLevel.CheckLevelIntegrity: TLevelError; |
239 | function TLevel.CheckLevelIntegrity: TLevelError; |
218 | var |
240 | var |
219 | W: integer; |
- | |
220 | H: extended; |
- | |
221 | header, h_ver, h_dia, h_del, tmp: string; |
- | |
222 | p: integer; |
241 | tmp: string; |
223 | i: Integer; |
242 | i: Integer; |
224 | Line: string; |
243 | Line: string; |
- | 244 | firstLine: string; |
|
- | 245 | thisLine: string; |
|
225 | begin |
246 | begin |
226 | result := leNone; |
247 | result := leNone; |
227 | 248 | ||
228 | // Check 1: Ist der Header OK? |
249 | // Check 1: Ist der Header OK? |
229 | 250 | ||
230 | if LowerCase(FStringList.Strings[0]) <> 'version 2' then |
251 | if LowerCase(FStringList.Strings[0]) <> 'version 2' then |
231 | begin |
252 | begin |
232 | result := leUnsupportedVersion; |
253 | result := leUnsupportedVersion; |
233 | exit; |
254 | exit; |
234 | end; |
255 | end; |
235 | 256 | ||
236 | if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and (LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then |
257 | if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and (LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then |
237 | begin |
258 | begin |
238 | result := leUnsupportedMode; |
259 | result := leUnsupportedMode; |
239 | exit; |
260 | exit; |
240 | end; |
261 | end; |
241 | 262 | ||
242 | // Check 2: Ist das Brett leer? |
263 | // Check 2: Ist das Brett leer? |
243 | 264 | ||
- | 265 | tmp := ''; |
|
- | 266 | for i := NUM_HEADERS to FStringList.Count-1 do tmp := tmp + FStringList.Strings[i]; |
|
244 | if FStringList.Count - NUM_HEADERS = 0 then |
267 | if Trim(StringReplace(tmp, '.', '', [rfReplaceAll])) = '' then |
245 | begin |
268 | begin |
246 | result := leEmptyBoard; |
269 | result := leEmptyBoard; |
247 | exit; |
270 | exit; |
248 | end; |
271 | end; |
249 | 272 | ||
250 | // Check 3: Geht das Level nicht in einem Quadrat oder Rechteck auf? |
273 | // Check 3: Geht das Level nicht in einem Quadrat oder Rechteck auf? |
251 | 274 | ||
- | 275 | firstLine := StringReplace(FStringList.Strings[NUM_HEADERS], '.', '', [rfReplaceAll]); |
|
252 | for i := NUM_HEADERS to FStringList.Count-1 do |
276 | for i := NUM_HEADERS to FStringList.Count-1 do |
253 | begin |
277 | begin |
- | 278 | thisLine := StringReplace(FStringList.Strings[i], '.', '', [rfReplaceAll]); |
|
254 | if Length(FStringList.Strings[i]) <> Length(FStringList.Strings[NUM_HEADERS]) then |
279 | if Length(thisLine) <> Length(firstLine) then |
255 | begin |
280 | begin |
256 | result := leRowInvalidLength; // at row y-NUM_HEADERS |
281 | result := leRowInvalidLength; // at row y-NUM_HEADERS |
257 | exit; |
282 | exit; |
258 | end; |
283 | end; |
259 | end; |
284 | end; |
260 | 285 | ||
261 | // Check 4: Gibt es ungültige Elemente in den Zeilen? |
286 | // Check 4: Gibt es ungültige Elemente in den Zeilen? |
262 | 287 | ||
263 | for i := NUM_HEADERS to FStringList.Count-1 do |
288 | for i := NUM_HEADERS to FStringList.Count-1 do |
264 | begin |
289 | begin |
265 | Line := FStringList.Strings[i]; |
290 | Line := FStringList.Strings[i]; |
266 | 291 | ||
267 | Line := StringReplace(Line, '.', '', [rfReplaceAll]); |
292 | Line := StringReplace(Line, '.', '', [rfReplaceAll]); |
268 | Line := StringReplace(Line, '*', '', [rfReplaceAll]); |
293 | Line := StringReplace(Line, '*', '', [rfReplaceAll]); |
269 | Line := StringReplace(Line, 'r', '', [rfReplaceAll, rfIgnoreCase]); |
294 | Line := StringReplace(Line, 'r', '', [rfReplaceAll, rfIgnoreCase]); |
270 | Line := StringReplace(Line, 'y', '', [rfReplaceAll, rfIgnoreCase]); |
295 | Line := StringReplace(Line, 'y', '', [rfReplaceAll, rfIgnoreCase]); |
271 | Line := StringReplace(Line, 'g', '', [rfReplaceAll, rfIgnoreCase]); |
296 | Line := StringReplace(Line, 'g', '', [rfReplaceAll, rfIgnoreCase]); |
272 | Line := StringReplace(Line, 'e', '', [rfReplaceAll, rfIgnoreCase]); |
297 | Line := StringReplace(Line, 'e', '', [rfReplaceAll, rfIgnoreCase]); |
273 | 298 | ||
274 | if Length(Line) > 0 then |
299 | if Length(Line) > 0 then |
275 | begin |
300 | begin |
276 | result := leInvalidElement; // at row y-NUM_HEADERS |
301 | result := leInvalidElement; // at row y-NUM_HEADERS |
277 | Exit; |
302 | Exit; |
278 | end; |
303 | end; |
279 | end; |
304 | end; |
280 | 305 | ||
281 | // Check 5: Kann im Level gesprungen werden |
306 | // Check 5: Kann im Level gesprungen werden |
282 | 307 | ||
283 | { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss. |
308 | { Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss. |
284 | Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! } |
309 | Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! } |
285 | end; |
310 | end; |
286 | 311 | ||
287 | end. |
312 | end. |
288 | 313 |