Subversion Repositories jumper

Rev

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

Rev 11 Rev 19
Line 4... Line 4...
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;
Line 41... Line 45...
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;
Line 54... Line 58...
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
 
Line 135... Line 135...
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;
Line 214... Line 236...
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
 
Line 239... Line 260...
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;