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 Main;
1
unit Main;
2
 
2
 
3
interface
3
interface
4
 
4
 
5
uses
5
uses
6
  Windows, SysUtils, Classes, Graphics, Dialogs, StdCtrls, Menus, Controls,
6
  Windows, SysUtils, Classes, Graphics, Dialogs, StdCtrls, Menus, Controls,
7
  ComCtrls, ExtCtrls, Forms, MMSystem, LevelFunctions, Registry;
7
  ComCtrls, ExtCtrls, Forms, MMSystem, LevelFunctions, Registry;
8
 
8
 
9
type
9
type
10
  TField = record
-
 
11
    FieldType: TFieldType;
-
 
12
    Goal: Boolean;
-
 
13
    Panel: TPanel;
-
 
14
    Stone: TImage;
-
 
15
  end;
-
 
16
 
-
 
17
  TGoalStatus = (gsUndefined, gsNoGoal, gsMultipleStonesRemaining, gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen, gsLastStoneOutsideGoal);
-
 
18
 
-
 
19
  TFieldState = (fsUndefined, fsError, fsLocked, fsAvailable, fsStone);
-
 
20
 
-
 
21
  TPlayGroundMatrix = array of array of TField;
-
 
22
 
-
 
23
  TMainForm = class(TForm)
10
  TMainForm = class(TForm)
24
    Playground: TPanel;
11
    Playground: TPanel;
25
    MainMenu: TMainMenu;
12
    MainMenu: TMainMenu;
26
    Help1: TMenuItem;
13
    Help1: TMenuItem;
27
    MExit: TMenuItem;
14
    MExit: TMenuItem;
28
    Statistics: TStatusBar;
15
    Statistics: TStatusBar;
29
    Timer: TTimer;
16
    Timer: TTimer;
30
    MNewGame: TMenuItem;
17
    MNewGame: TMenuItem;
31
    Help2: TMenuItem;
18
    Help2: TMenuItem;
32
    MAbout: TMenuItem;
19
    MAbout: TMenuItem;
33
    MHelp: TMenuItem;
20
    MHelp: TMenuItem;
34
    N5: TMenuItem;
21
    N5: TMenuItem;
35
    MJumpHistory: TMenuItem;
22
    MJumpHistory: TMenuItem;
36
    N2: TMenuItem;
23
    N2: TMenuItem;
37
    N4: TMenuItem;
24
    N4: TMenuItem;
38
    MHighScores: TMenuItem;
25
    MHighScores: TMenuItem;
39
    MRestartGame: TMenuItem;
26
    MRestartGame: TMenuItem;
40
    MSettings: TMenuItem;
27
    MSettings: TMenuItem;
41
    MEnableSound: TMenuItem;
28
    MEnableSound: TMenuItem;
42
    MPauseTime: TMenuItem;
29
    MPauseTime: TMenuItem;
43
    N1: TMenuItem;
30
    N1: TMenuItem;
44
    MUndo: TMenuItem;
31
    MUndo: TMenuItem;
45
    N3: TMenuItem;
32
    N3: TMenuItem;
46
    Aboutthislevel1: TMenuItem;
33
    Aboutthislevel1: TMenuItem;
47
    procedure MExitClick(Sender: TObject);
34
    procedure MExitClick(Sender: TObject);
48
    procedure TimerTimer(Sender: TObject);
35
    procedure TimerTimer(Sender: TObject);
49
    procedure MNewGameClick(Sender: TObject);
36
    procedure MNewGameClick(Sender: TObject);
50
    procedure MAboutClick(Sender: TObject);
37
    procedure MAboutClick(Sender: TObject);
51
    procedure FormShow(Sender: TObject);
38
    procedure FormShow(Sender: TObject);
52
    procedure FormCreate(Sender: TObject);
39
    procedure FormCreate(Sender: TObject);
53
    procedure FormDestroy(Sender: TObject);
40
    procedure FormDestroy(Sender: TObject);
54
    procedure MJumpHistoryClick(Sender: TObject);
41
    procedure MJumpHistoryClick(Sender: TObject);
55
    procedure MRestartGameClick(Sender: TObject);
42
    procedure MRestartGameClick(Sender: TObject);
56
    procedure MHighScoresClick(Sender: TObject);
43
    procedure MHighScoresClick(Sender: TObject);
57
    procedure MPauseTimeClick(Sender: TObject);
-
 
58
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
44
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
59
    procedure MHelpClick(Sender: TObject);
45
    procedure MHelpClick(Sender: TObject);
60
    procedure MEnableSoundClick(Sender: TObject);
-
 
61
    procedure MUndoClick(Sender: TObject);
46
    procedure MUndoClick(Sender: TObject);
62
    procedure Aboutthislevel1Click(Sender: TObject);
47
    procedure Aboutthislevel1Click(Sender: TObject);
63
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
48
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
64
  private
49
  private
65
    NoCloseQuery: boolean;
50
    NoCloseQuery: boolean;
66
    CountedSeconds: Integer;
51
    CountedSeconds: Integer;
67
    LevelFile: String;
52
    LevelFile: String;
68
    LookupFieldCoordinateArray: array of TPoint;
53
    LookupFieldCoordinateArray: array of TPoint;
69
    PrevPlaygroundMatrixes: array of TPlayGroundMatrix;
54
    PrevPlaygroundMatrixes: array of TPlayGroundMatrix;
70
    PlaygroundMatrix: TPlayGroundMatrix;
55
    PlaygroundMatrix: TPlayGroundMatrix;
71
    Points: Integer;
56
    Points: Integer;
72
    LevelTotalStones: Integer;
57
    LevelTotalStones: Integer;
73
    LevelRemovedStones: Integer;
58
    LevelRemovedStones: Integer;
74
    JumpHistory: TStringList;
59
    JumpHistory: TStringList;
75
    Level: TLevel;
60
    Level: TLevel;
76
    procedure LoadSettings;
61
    procedure LoadSettings;
77
    procedure SaveSettings;
62
    procedure SaveSettings;
78
    procedure RestartLevel;
63
    procedure RestartLevel;
79
    procedure SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
64
    procedure SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
80
    procedure RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
65
    procedure RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
81
    function AskForLevel: String;
66
    function AskForLevel: String;
82
    function AreJumpsPossible: boolean;
67
    function AreJumpsPossible: boolean;
83
    procedure StoneDraggingAllow(Stone: TImage; Allow: boolean);
68
    procedure StoneDraggingAllow(Stone: TImage; Allow: boolean);
84
    procedure NewGame(Filename: string);
69
    procedure NewGame(Filename: string);
85
    function LevelTime: String;
70
    function LevelTime: String;
86
    procedure DestroyLevel;
71
    procedure DestroyLevel;
87
    procedure RefreshTime;
72
    procedure RefreshTime;
88
    procedure RefreshPoints;
73
    procedure RefreshPoints;
89
    procedure RefreshStonesRemoved;
74
    procedure RefreshStonesRemoved;
90
    procedure CountPoints(t: TFieldType);
75
    procedure CountPoints(t: TFieldType);
91
    procedure RemoveStone(x, y: integer; count_points: boolean);
76
    procedure RemoveStone(x, y: integer; count_points: boolean);
92
    procedure DoJump(SourceTag, DestTag: integer);
77
    procedure DoJump(SourceTag, DestTag: integer);
93
    function CanJump(x, y: integer): boolean;
78
    function CanJump(x, y: integer): boolean;
94
    function MayJump(SourceX, SourceY, DestX, DestY: integer): boolean; overload;
79
    function MayJump(SourceX, SourceY, DestX, DestY: integer): boolean; overload;
95
    function MayJump(SourceTag, DestTag: integer): boolean; overload;
80
    function MayJump(SourceTag, DestTag: integer): boolean; overload;
96
    procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
81
    procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
97
    procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
82
    procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
98
    function DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField;
83
    function DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField;
99
    function DrawStone(fieldtype: TFieldType; panel: TPanel): TImage;
84
    function DrawStone(fieldtype: TFieldType; panel: TPanel): TImage;
100
    function DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel;
85
    function DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel;
101
    procedure BuildPlayground(LevelArray: TLevelArray);
86
    procedure BuildPlayground(LevelArray: TLevelArray);
102
    function FieldState(t: TFieldType): TFieldState; overload;
-
 
103
    function FieldState(f: TField): TFieldState; overload;
-
 
104
    function FieldState(x, y: integer): TFieldState; overload;
-
 
105
    procedure ClearMatrix(Matrix: TPlayGroundMatrix; FreeVCL: boolean);
-
 
106
    function CloneMatrix(Source: TPlayGroundMatrix): TPlayGroundMatrix;
-
 
107
    function MatrixHasGoal(Matrix: TPlayGroundMatrix): boolean;
-
 
108
    procedure LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
87
    procedure LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
109
    function MatrixWorth(Matrix: TPlayGroundMatrix): integer;
-
 
110
    function GoalStatus: TGoalStatus;
88
    function GoalStatus: TGoalStatus;
111
    function GoalFieldType(Matrix: TPlayGroundMatrix): TFieldType;
-
 
112
  end;
89
  end;
113
 
90
 
114
var
91
var
115
  MainForm: TMainForm;
92
  MainForm: TMainForm;
116
 
93
 
117
implementation
94
implementation
118
 
95
 
119
uses
96
uses
120
  About, Finish, Choice, Functions, History, HighScore, Help, Constants, Math;
97
  About, Finish, Choice, Functions, History, HighScore, Help, Constants, Math;
121
 
98
 
122
{$R *.dfm}
99
{$R *.dfm}
123
 
100
 
124
function TMainForm.MatrixHasGoal(Matrix: TPlayGroundMatrix): boolean;
-
 
125
var
-
 
126
  i, j: integer;
-
 
127
begin
-
 
128
  result := false;
-
 
129
  for i := Low(Matrix) to High(Matrix) do
-
 
130
  begin
-
 
131
    for j := Low(Matrix[i]) to High(Matrix[i]) do
-
 
132
    begin
-
 
133
      result := result or Matrix[i][j].Goal;
-
 
134
    end;
-
 
135
  end;
-
 
136
end;
-
 
137
 
-
 
138
function TMainForm.GoalFieldType(Matrix: TPlayGroundMatrix): TFieldType;
-
 
139
var
-
 
140
  i, j: integer;
-
 
141
begin
-
 
142
  result := ftEmpty; // Damit der Compiler nicht meckert
-
 
143
  for i := Low(Matrix) to High(Matrix) do
-
 
144
  begin
-
 
145
    for j := Low(Matrix[i]) to High(Matrix[i]) do
-
 
146
    begin
-
 
147
      if Matrix[i][j].Goal then result := Matrix[i][j].FieldType
-
 
148
    end;
-
 
149
  end;
-
 
150
end;
-
 
151
 
-
 
152
function TMainForm.MatrixWorth(Matrix: TPlayGroundMatrix): integer;
-
 
153
var
-
 
154
  i, j: integer;
-
 
155
begin
-
 
156
  result := 0;
101
{ TMainForm }
157
  for i := Low(Matrix) to High(Matrix) do
-
 
158
  begin
-
 
159
    for j := Low(Matrix[i]) to High(Matrix[i]) do
-
 
160
    begin
-
 
161
      Inc(result, FieldTypeWorth(Matrix[i][j].FieldType));
-
 
162
    end;
-
 
163
  end;
-
 
164
end;
-
 
165
 
-
 
166
procedure TMainForm.ClearMatrix(Matrix: TPlayGroundMatrix; FreeVCL: boolean);
-
 
167
var
-
 
168
  i, j: integer;
-
 
169
begin
-
 
170
  for i := Low(Matrix) to High(Matrix) do
-
 
171
  begin
-
 
172
    for j := Low(Matrix[i]) to High(Matrix[i]) do
-
 
173
    begin
-
 
174
      if FreeVCL then
-
 
175
      begin
-
 
176
        if Assigned(Matrix[i][j].Stone) then Matrix[i][j].Stone.Free;
-
 
177
        if Assigned(Matrix[i][j].Panel) then Matrix[i][j].Panel.Free;
-
 
178
      end;
-
 
179
    end;
-
 
180
    SetLength(Matrix[i], 0);
-
 
181
  end;
-
 
182
  SetLength(Matrix, 0);
-
 
183
end;
-
 
184
 
102
 
185
procedure TMainForm.RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
103
procedure TMainForm.RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
186
var
104
var
187
  i, j: integer;
105
  i, j: integer;
188
begin
106
begin
189
  for i := Low(Matrix) to High(Matrix) do
107
  for i := Low(Matrix.Fields) to High(Matrix.Fields) do
190
  begin
108
  begin
191
    for j := Low(Matrix[i]) to High(Matrix[i]) do
109
    for j := Low(Matrix.Fields[i]) to High(Matrix.Fields[i]) do
192
    begin
110
    begin
193
      if Assigned(Matrix[i][j].Stone) then
111
      if Assigned(Matrix.Fields[i][j].Stone) then
194
      begin
112
      begin
195
        LoadPictureForType(Matrix[i][j].FieldType, Matrix[i][j].Stone.Picture);
113
        LoadPictureForType(Matrix.Fields[i][j].FieldType, Matrix.Fields[i][j].Stone.Picture);
196
        StoneDraggingAllow(Matrix[i][j].Stone, FieldState(Matrix[i][j].FieldType) <> fsAvailable);
114
        StoneDraggingAllow(Matrix.Fields[i][j].Stone, Matrix.FieldState(Matrix.Fields[i][j].FieldType) <> fsAvailable);
197
      end;
115
      end;
198
    end;
116
    end;
199
  end;
117
  end;
200
end;
118
end;
201
 
119
 
202
procedure TMainForm.DestroyLevel;
120
procedure TMainForm.DestroyLevel;
203
var
121
var
204
  i: Integer;
122
  i: Integer;
205
begin
123
begin
-
 
124
  MPauseTime.Checked := false;
206
  MPauseTime.Enabled := false;
125
  MPauseTime.Enabled := false;
207
  Timer.Enabled := false;
126
  Timer.Enabled := false;
208
 
127
 
209
  MRestartGame.Enabled := false;
128
  MRestartGame.Enabled := false;
210
 
129
 
211
  LevelFile := '';
130
  LevelFile := '';
212
 
131
 
213
  CountedSeconds := 0;
132
  CountedSeconds := 0;
214
  RefreshTime;
133
  RefreshTime;
215
 
134
 
216
  Points := 0;
135
  Points := 0;
217
  RefreshPoints;
136
  RefreshPoints;
218
 
137
 
219
  LevelRemovedStones := 0;
138
  LevelRemovedStones := 0;
220
  LevelTotalStones := 0;
139
  LevelTotalStones := 0;
221
  RefreshStonesRemoved;
140
  RefreshStonesRemoved;
222
 
141
 
223
  JumpHistory.Clear;
142
  JumpHistory.Clear;
224
 
143
 
225
  ClearMatrix(PlayGroundMatrix, true);
144
  PlayGroundMatrix.ClearMatrix(true);
226
  for i := 0 to Length(PrevPlaygroundMatrixes)-1 do
145
  for i := 0 to Length(PrevPlaygroundMatrixes)-1 do
227
    ClearMatrix(PrevPlaygroundMatrixes[i], false);
146
    PrevPlaygroundMatrixes[i].ClearMatrix(false);
228
  SetLength(PrevPlaygroundMatrixes, 0);
147
  SetLength(PrevPlaygroundMatrixes, 0);
229
  MUndo.Enabled := false;
148
  MUndo.Enabled := false;
230
 
149
 
231
  SetLength(LookupFieldCoordinateArray, 0);
150
  SetLength(LookupFieldCoordinateArray, 0);
232
 
151
 
233
  if Assigned(Level) then FreeAndNil(Level);
152
  if Assigned(Level) then FreeAndNil(Level);
234
end;
153
end;
235
 
154
 
236
procedure TMainForm.LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
155
procedure TMainForm.LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
237
begin
156
begin
238
  case FieldType of
157
  case FieldType of
239
    ftEmpty:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_EMPTY);
158
    ftEmpty:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_EMPTY);
240
    ftGreen:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_GREEN);
159
    ftGreen:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_GREEN);
241
    ftYellow: Picture.Bitmap.LoadFromResourceName(HInstance, RES_YELLOW);
160
    ftYellow: Picture.Bitmap.LoadFromResourceName(HInstance, RES_YELLOW);
242
    ftRed:    Picture.Bitmap.LoadFromResourceName(HInstance, RES_RED);
161
    ftRed:    Picture.Bitmap.LoadFromResourceName(HInstance, RES_RED);
243
  end;
162
  end;
244
end;
163
end;
245
 
164
 
246
function TMainForm.DrawStone(fieldtype: TFieldType; panel: TPanel): TImage;
165
function TMainForm.DrawStone(fieldtype: TFieldType; panel: TPanel): TImage;
247
begin
166
begin
248
  result := TImage.Create(panel);
167
  result := TImage.Create(panel);
249
  result.Parent := panel;
168
  result.Parent := panel;
250
  LoadPictureForType(fieldtype, result.Picture);
169
  LoadPictureForType(fieldtype, result.Picture);
251
  result.Width := panel.Width - 2*MET_SHAPE_MARGIN;
170
  result.Width := panel.Width - 2*MET_SHAPE_MARGIN;
252
  result.Height := panel.Height - 2*MET_SHAPE_MARGIN;
171
  result.Height := panel.Height - 2*MET_SHAPE_MARGIN;
253
  result.Left := MET_SHAPE_MARGIN;
172
  result.Left := MET_SHAPE_MARGIN;
254
  result.Top := MET_SHAPE_MARGIN;
173
  result.Top := MET_SHAPE_MARGIN;
255
  result.Center := true;
174
  result.Center := true;
256
  result.Transparent := true;
175
  result.Transparent := true;
257
 
176
 
258
  result.Tag := panel.Tag;
177
  result.Tag := panel.Tag;
259
  result.OnDragOver := panel.OnDragOver;
178
  result.OnDragOver := panel.OnDragOver;
260
  result.OnDragDrop := panel.OnDragDrop;
179
  result.OnDragDrop := panel.OnDragDrop;
261
 
180
 
262
  StoneDraggingAllow(result, FieldState(fieldtype) <> fsAvailable);
181
  StoneDraggingAllow(result, PlayGroundMatrix.FieldState(fieldtype) <> fsAvailable);
263
end;
182
end;
264
 
183
 
265
procedure TMainForm.StoneDraggingAllow(Stone: TImage; Allow: boolean);
184
procedure TMainForm.StoneDraggingAllow(Stone: TImage; Allow: boolean);
266
begin
185
begin
267
  if Allow then
186
  if Allow then
268
  begin
187
  begin
269
    Stone.DragMode := dmAutomatic;
188
    Stone.DragMode := dmAutomatic;
270
    (Stone.Parent as TPanel).DragMode := dmAutomatic;
189
    (Stone.Parent as TPanel).DragMode := dmAutomatic;
271
  end
190
  end
272
  else
191
  else
273
  begin
192
  begin
274
    Stone.DragMode := dmManual;
193
    Stone.DragMode := dmManual;
275
    (Stone.Parent as TPanel).DragMode := dmManual;
194
    (Stone.Parent as TPanel).DragMode := dmManual;
276
  end;
195
  end;
277
end;
196
end;
278
 
197
 
279
function TMainForm.DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel;
198
function TMainForm.DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel;
280
begin
199
begin
281
  result := TPanel.Create(Playground);
200
  result := TPanel.Create(Playground);
282
  result.Parent := Playground;
201
  result.Parent := Playground;
283
  if isGoal then
202
  if isGoal then
284
  begin
203
  begin
285
    result.BevelInner := bvLowered;
204
    result.BevelInner := bvLowered;
286
  end;
205
  end;
287
  result.Color := Playground.Color;
206
  result.Color := Playground.Color;
288
  result.BevelOuter := bvLowered;
207
  result.BevelOuter := bvLowered;
289
  result.Width := MET_FIELD_SIZE;
208
  result.Width := MET_FIELD_SIZE;
290
  result.Height := MET_FIELD_SIZE;
209
  result.Height := MET_FIELD_SIZE;
291
  result.Left := x * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE + (halftabs*MET_HALFTAB_SIZE);
210
  result.Left := x * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE + (halftabs*MET_HALFTAB_SIZE);
292
  result.Top := y * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE;
211
  result.Top := y * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE;
293
 
212
 
294
  result.Tag := tag;
213
  result.Tag := tag;
295
  result.OnDragOver := StoneDragOver;
214
  result.OnDragOver := StoneDragOver;
296
  result.OnDragDrop := StoneDragDrop;
215
  result.OnDragDrop := StoneDragDrop;
297
end;
216
end;
298
 
217
 
299
procedure TMainForm.MExitClick(Sender: TObject);
218
procedure TMainForm.MExitClick(Sender: TObject);
300
begin
219
begin
301
  Close;
220
  Close;
302
end;
221
end;
303
 
222
 
304
function TMainForm.FieldState(t: TFieldType): TFieldState;
-
 
305
begin
-
 
306
  result := fsError;
-
 
307
  case t of
-
 
308
    ftFullSpace:     result := fsLocked;
-
 
309
    ftEmpty:         result := fsAvailable;
-
 
310
    ftGreen:         result := fsStone;
-
 
311
    ftYellow:        result := fsStone;
-
 
312
    ftRed:           result := fsStone;
-
 
313
  end;
-
 
314
end;
-
 
315
 
-
 
316
function TMainForm.FieldState(f: TField): TFieldState;
-
 
317
begin
-
 
318
  result := FieldState(f.FieldType);
-
 
319
end;
-
 
320
 
-
 
321
function TMainForm.FieldState(x, y: integer): TFieldState;
-
 
322
begin
-
 
323
  result := fsError;
-
 
324
  if (x < Low(PlayGroundMatrix)) or (x > High(PlayGroundMatrix)) then exit;
-
 
325
  if (y < Low(PlayGroundMatrix[x])) or (y > High(PlayGroundMatrix[x])) then exit;
-
 
326
 
-
 
327
  result := FieldState(PlayGroundMatrix[x][y]);
-
 
328
end;
-
 
329
 
-
 
330
procedure TMainForm.RefreshTime;
223
procedure TMainForm.RefreshTime;
331
begin
224
begin
332
  Statistics.Panels.Items[0].Text := Format(LNG_TIME, [LevelTime]);
225
  Statistics.Panels.Items[0].Text := Format(LNG_TIME, [LevelTime]);
333
end;
226
end;
334
 
227
 
335
procedure TMainForm.RefreshStonesRemoved;
228
procedure TMainForm.RefreshStonesRemoved;
-
 
229
resourcestring
-
 
230
  LNG_STONES_REMOVED = '%d of %d stones removed';
336
begin
231
begin
337
  Statistics.Panels.Items[1].Text := Format(LNG_STONES_REMOVED, [LevelRemovedStones, LevelTotalStones-1]);
232
  Statistics.Panels.Items[1].Text := Format(LNG_STONES_REMOVED, [LevelRemovedStones, LevelTotalStones-1]);
338
end;
233
end;
339
 
234
 
340
procedure TMainForm.RefreshPoints;
235
procedure TMainForm.RefreshPoints;
341
begin
236
begin
342
  Statistics.Panels.Items[2].Text := Format(LNG_POINTS, [Points]);
237
  Statistics.Panels.Items[2].Text := Format(LNG_POINTS, [Points]);
343
end;
238
end;
344
 
239
 
345
procedure TMainForm.CountPoints(t: TFieldType);
240
procedure TMainForm.CountPoints(t: TFieldType);
346
begin
241
begin
347
  inc(Points, FieldTypeWorth(t));
242
  inc(Points, FieldTypeWorth(t));
348
  RefreshPoints;
243
  RefreshPoints;
349
end;
244
end;
350
 
245
 
351
procedure TMainForm.RemoveStone(x, y: integer; count_points: boolean);
246
procedure TMainForm.RemoveStone(x, y: integer; count_points: boolean);
352
begin
247
begin
353
  if count_points then
248
  if count_points then
354
  begin
249
  begin
355
    CountPoints(PlayGroundMatrix[x, y].FieldType);
250
    CountPoints(PlayGroundMatrix.Fields[x, y].FieldType);
356
    Inc(LevelRemovedStones);
251
    Inc(LevelRemovedStones);
357
    RefreshStonesRemoved;
252
    RefreshStonesRemoved;
358
  end;
253
  end;
359
  PlayGroundMatrix[x, y].FieldType := ftEmpty;
254
  PlayGroundMatrix.Fields[x, y].FieldType := ftEmpty;
360
  LoadPictureForType(PlayGroundMatrix[x, y].FieldType, PlayGroundMatrix[x, y].Stone.Picture);
255
  LoadPictureForType(PlayGroundMatrix.Fields[x, y].FieldType, PlayGroundMatrix.Fields[x, y].Stone.Picture);
361
  StoneDraggingAllow(PlayGroundMatrix[x, y].Stone, false);
256
  StoneDraggingAllow(PlayGroundMatrix.Fields[x, y].Stone, false);
362
end;
257
end;
363
 
258
 
364
function TMainForm.CanJump(x, y: integer): boolean;
259
function TMainForm.CanJump(x, y: integer): boolean;
365
begin
260
begin
366
  if FieldState(x, y) <> fsStone then
261
  if PlayGroundMatrix.FieldState(x, y) <> fsStone then
367
  begin
262
  begin
368
    result := false;
263
    result := false;
369
    exit;
264
    exit;
370
  end;
265
  end;
371
 
266
 
372
  result := true;
267
  result := true;
373
 
268
 
374
  if MayJump(x, y, x+2, y) then exit;
269
  if MayJump(x, y, x+2, y) then exit;
375
  if MayJump(x, y, x-2, y) then exit;
270
  if MayJump(x, y, x-2, y) then exit;
376
  if MayJump(x, y, x, y+2) then exit;
271
  if MayJump(x, y, x, y+2) then exit;
377
  if MayJump(x, y, x, y-2) then exit;
272
  if MayJump(x, y, x, y-2) then exit;
378
 
273
 
379
  if Level.GetGameMode = gmDiagonal then
274
  if Level.GetGameMode = gmDiagonal then
380
  begin
275
  begin
381
    if MayJump(x, y, x-2, y-2) then exit;
276
    if MayJump(x, y, x-2, y-2) then exit;
382
    if MayJump(x, y, x+2, y-2) then exit;
277
    if MayJump(x, y, x+2, y-2) then exit;
383
    if MayJump(x, y, x-2, y+2) then exit;
278
    if MayJump(x, y, x-2, y+2) then exit;
384
    if MayJump(x, y, x+2, y+2) then exit;
279
    if MayJump(x, y, x+2, y+2) then exit;
385
  end;
280
  end;
386
 
281
 
387
  result := false;
282
  result := false;
388
end;
283
end;
389
 
284
 
390
procedure TMainForm.Aboutthislevel1Click(Sender: TObject);
285
procedure TMainForm.Aboutthislevel1Click(Sender: TObject);
391
var
286
var
392
  mode: string;
287
  mode: string;
393
  goalYeSNo: string;
288
  goalYeSNo: string;
394
resourcestring
289
resourcestring
395
  LNG_BOARD = 'Board: %s';
290
  LNG_BOARD = 'Board: %s';
396
  LNG_MODE = 'Mode: %s';
291
  LNG_MODE = 'Mode: %s';
397
  LNG_STONES_TOTAL = 'Stones: %d';
292
  LNG_STONES_TOTAL = 'Stones: %d';
398
  LNG_GOAL_AVAILABLE = 'Target field defined';
293
  LNG_GOAL_AVAILABLE = 'Target field defined';
399
  LNG_NO_GOAL = 'No target field';
294
  LNG_NO_GOAL = 'No target field';
400
begin
295
begin
401
  if Level.GetGameMode = gmDiagonal then
296
  if Level.GetGameMode = gmDiagonal then
402
    mode := 'Diagonal'
297
    mode := 'Diagonal'
403
  else if Level.GetGameMode = gmNormal then
298
  else if Level.GetGameMode = gmNormal then
404
    mode := 'Normal'
299
    mode := 'Normal'
405
  else
300
  else
406
    mode := '?';
301
    mode := '?';
407
 
302
 
408
  if GoalStatus = gsNoGoal then
303
  if GoalStatus = gsNoGoal then
409
    goalYeSNo := LNG_NO_GOAL
304
    goalYeSNo := LNG_NO_GOAL
410
  else
305
  else
411
    goalYeSNo := LNG_GOAL_AVAILABLE;
306
    goalYeSNo := LNG_GOAL_AVAILABLE;
412
 
307
 
413
  ShowMessage(Format(LNG_BOARD, [ExtractFileNameWithoutExt(LevelFile)]) + #13#10 +
308
  ShowMessage(Format(LNG_BOARD, [ExtractFileNameWithoutExt(LevelFile)]) + #13#10 +
414
              #13#10 +
309
              #13#10 +
415
              Format(LNG_MODE, [mode]) + #13#10 +
310
              Format(LNG_MODE, [mode]) + #13#10 +
416
              Format(LNG_STONES_TOTAL, [LevelTotalStones]) + #13#10 +
311
              Format(LNG_STONES_TOTAL, [LevelTotalStones]) + #13#10 +
417
              goalYesNo);
312
              goalYesNo);
418
end;
313
end;
419
 
314
 
420
function TMainForm.AreJumpsPossible: boolean;
315
function TMainForm.AreJumpsPossible: boolean;
421
var
316
var
422
  i, j: integer;
317
  i, j: integer;
423
begin
318
begin
424
  result := false;
319
  result := false;
425
  for i := Low(PlayGroundMatrix) to High(PlayGroundMatrix) do
320
  for i := Low(PlayGroundMatrix.Fields) to High(PlayGroundMatrix.Fields) do
426
  begin
321
  begin
427
    for j := Low(PlayGroundMatrix[i]) to High(PlayGroundMatrix[i]) do
322
    for j := Low(PlayGroundMatrix.Fields[i]) to High(PlayGroundMatrix.Fields[i]) do
428
    begin
323
    begin
429
      if CanJump(i, j) then
324
      if CanJump(i, j) then
430
      begin
325
      begin
431
        result := true;
326
        result := true;
432
        break;
327
        break;
433
      end;
328
      end;
434
      if result then break;
329
      if result then break;
435
    end;
330
    end;
436
  end;
331
  end;
437
end;
332
end;
438
 
333
 
439
procedure TMainForm.DoJump(SourceTag, DestTag: integer);
334
procedure TMainForm.DoJump(SourceTag, DestTag: integer);
-
 
335
resourcestring
-
 
336
  LNG_JUMP_LOG = '%d [%d, %d] -> %d [%d, %d];';
440
var
337
var
441
  d, s: TPoint;
338
  d, s: TPoint;
442
  old_fieldtype: TFieldType;
339
  old_fieldtype: TFieldType;
443
  res: Integer;
340
  res: Integer;
444
begin
341
begin
445
  if not MayJump(SourceTag, DestTag) then exit;
342
  if not MayJump(SourceTag, DestTag) then exit;
446
 
343
 
447
  d := LookupFieldCoordinateArray[DestTag];
344
  d := LookupFieldCoordinateArray[DestTag];
448
  s := LookupFieldCoordinateArray[SourceTag];
345
  s := LookupFieldCoordinateArray[SourceTag];
449
 
346
 
450
  JumpHistory.Add(Format(LNG_JUMP_LOG, [SourceTag+1, s.x+1, s.y+1, DestTag+1, d.x+1, d.y+1]));
347
  JumpHistory.Add(Format(LNG_JUMP_LOG, [SourceTag+1, s.x+1, s.y+1, DestTag+1, d.x+1, d.y+1]));
451
 
348
 
452
  {$REGION 'Stein entfernen und Punkte vergeben'}
349
  {$REGION 'Stein entfernen und Punkte vergeben'}
453
  if Level.GetGameMode = gmDiagonal then
350
  if Level.GetGameMode = gmDiagonal then
454
  begin
351
  begin
455
    if (s.X-2 = d.X) and (s.Y-2 = d.Y) and (FieldState(s.X-1, s.Y-1) = fsStone) then RemoveStone(s.X-1, s.Y-1, true);
352
    if (s.X-2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y-1) = fsStone) then RemoveStone(s.X-1, s.Y-1, true);
456
    if (s.X-2 = d.X) and (s.Y+2 = d.Y) and (FieldState(s.X-1, s.Y+1) = fsStone) then RemoveStone(s.X-1, s.Y+1, true);
353
    if (s.X-2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y+1) = fsStone) then RemoveStone(s.X-1, s.Y+1, true);
457
    if (s.X+2 = d.X) and (s.Y-2 = d.Y) and (FieldState(s.X+1, s.Y-1) = fsStone) then RemoveStone(s.X+1, s.Y-1, true);
354
    if (s.X+2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y-1) = fsStone) then RemoveStone(s.X+1, s.Y-1, true);
458
    if (s.X+2 = d.X) and (s.Y+2 = d.Y) and (FieldState(s.X+1, s.Y+1) = fsStone) then RemoveStone(s.X+1, s.Y+1, true);
355
    if (s.X+2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y+1) = fsStone) then RemoveStone(s.X+1, s.Y+1, true);
459
  end;
356
  end;
460
 
357
 
461
  if (s.X+2 = d.X) and (s.Y = d.Y) and (FieldState(s.X+1, s.Y  ) = fsStone) then RemoveStone(s.X+1, s.Y, true);
358
  if (s.X+2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y  ) = fsStone) then RemoveStone(s.X+1, s.Y, true);
462
  if (s.X-2 = d.X) and (s.Y = d.Y) and (FieldState(s.X-1, s.Y  ) = fsStone) then RemoveStone(s.X-1, s.Y, true);
359
  if (s.X-2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y  ) = fsStone) then RemoveStone(s.X-1, s.Y, true);
463
  if (s.X = d.X) and (s.Y+2 = d.Y) and (FieldState(s.X  , s.Y+1) = fsStone) then RemoveStone(s.X, s.Y+1, true);
360
  if (s.X = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X  , s.Y+1) = fsStone) then RemoveStone(s.X, s.Y+1, true);
464
  if (s.X = d.X) and (s.Y-2 = d.Y) and (FieldState(s.X  , s.Y-1) = fsStone) then RemoveStone(s.X, s.Y-1, true);
361
  if (s.X = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X  , s.Y-1) = fsStone) then RemoveStone(s.X, s.Y-1, true);
465
  {$ENDREGION}
362
  {$ENDREGION}
466
 
363
 
467
  // Den Timer erst nach dem ersten Zug starten
364
  // Den Timer erst nach dem ersten Zug starten
468
  // oder nach einer Pause neustarten
365
  // oder nach einer Pause neustarten
469
  if not Timer.Enabled then
366
  MPauseTime.Checked := false;
470
  begin
-
 
471
    MPauseTime.Enabled := true;
367
  MPauseTime.Enabled := true;
472
    Timer.Enabled := true;
368
  Timer.Enabled := true;
473
  end;
-
 
474
 
-
 
475
  MRestartGame.Enabled := true;
-
 
476
 
369
 
477
  // Sound abspielen
370
  // Sound abspielen
478
  if MEnableSound.Checked then PlaySound(RES_JUMP, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
371
  if MEnableSound.Checked then PlaySound(RES_JUMP, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
479
 
372
 
480
  {$REGION 'Nun den Stein springen lassen'}
373
  {$REGION 'Nun den Stein springen lassen'}
481
  old_fieldtype := PlayGroundMatrix[s.X, s.Y].FieldType; // Steinfarbe merken
374
  old_fieldtype := PlayGroundMatrix.Fields[s.X, s.Y].FieldType; // Steinfarbe merken
482
  RemoveStone(s.X, s.Y, false); // Eigenen Stein entfernen. Keine Punkte zählen, da das unser eigener Stein ist, der springt
375
  RemoveStone(s.X, s.Y, false); // Eigenen Stein entfernen. Keine Punkte zählen, da das unser eigener Stein ist, der springt
483
  PlayGroundMatrix[d.X, d.Y].FieldType := old_fieldtype; // Farbe wiederherstellen
376
  PlayGroundMatrix.Fields[d.X, d.Y].FieldType := old_fieldtype; // Farbe wiederherstellen
484
  LoadPictureForType(PlayGroundMatrix[d.X, d.Y].FieldType, PlayGroundMatrix[d.X, d.Y].Stone.Picture); // Stein an neue Position malen
377
  LoadPictureForType(PlayGroundMatrix.Fields[d.X, d.Y].FieldType, PlayGroundMatrix.Fields[d.X, d.Y].Stone.Picture); // Stein an neue Position malen
485
  StoneDraggingAllow(PlayGroundMatrix[d.X, d.Y].Stone, true); // Und die Drag-Eigenschaft erneuern
378
  StoneDraggingAllow(PlayGroundMatrix.Fields[d.X, d.Y].Stone, true); // Und die Drag-Eigenschaft erneuern
486
  {$ENDREGION}
379
  {$ENDREGION}
487
 
380
 
488
  {$REGION 'Sind weitere Sprünge möglich oder ist das Spiel vorbei?'}
381
  {$REGION 'Sind weitere Sprünge möglich oder ist das Spiel vorbei?'}
489
  if not AreJumpsPossible then
382
  if not AreJumpsPossible then
490
  begin
383
  begin
-
 
384
    MPauseTime.Checked := false;
491
    MPauseTime.Enabled := false;
385
    MPauseTime.Enabled := false;
492
    Timer.Enabled := false;
386
    Timer.Enabled := false;
493
    RefreshTime;
387
    RefreshTime;
494
    if MEnableSound.Checked then
388
    if MEnableSound.Checked then
495
    begin
389
    begin
496
      if LevelRemovedStones = LevelTotalStones-1 then
390
      if LevelRemovedStones = LevelTotalStones-1 then
497
      begin
391
      begin
498
        if GoalStatus in [gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen] then
392
        if GoalStatus in [gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen] then
499
          PlaySound(RES_WIN2, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
393
          PlaySound(RES_WIN2, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
500
        else
394
        else
501
          PlaySound(RES_WIN1, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
395
          PlaySound(RES_WIN1, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
502
      end
396
      end
503
      else
397
      else
504
        PlaySound(RES_LOSE, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
398
        PlaySound(RES_LOSE, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
505
    end;
399
    end;
506
    res := FinishForm.Execute(ExtractFileNameWithoutExt(LevelFile), Points, LevelTotalStones, LevelRemovedStones, CountedSeconds, GoalStatus, JumpHistory);
400
    res := FinishForm.Execute(ExtractFileNameWithoutExt(LevelFile), Points, LevelTotalStones, LevelRemovedStones, CountedSeconds, GoalStatus, JumpHistory);
507
    if (res = mrOK) and FinishForm.ReplayCheckbox.Checked then RestartLevel;
401
    if (res = mrOK) and FinishForm.ReplayCheckbox.Checked then RestartLevel;
508
  end;
402
  end;
509
  {$ENDREGION}
403
  {$ENDREGION}
510
 
404
 
511
  SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)+1);
405
  SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)+1);
512
  PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1] := CloneMatrix(PlaygroundMatrix);
406
  PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1] := PlaygroundMatrix.CloneMatrix;
513
  MUndo.Enabled := true;
407
  MUndo.Enabled := true;
514
end;
408
end;
515
 
409
 
516
function TMainForm.MayJump(SourceX, SourceY, DestX, DestY: integer): boolean;
410
function TMainForm.MayJump(SourceX, SourceY, DestX, DestY: integer): boolean;
517
begin
411
begin
518
  result := false;
412
  result := false;
519
 
413
 
520
  // Check 1: Ist das Zielfeld überhaupt leer?
414
  // Check 1: Ist das Zielfeld überhaupt leer?
521
  if FieldState(DestX, DestY) <> fsAvailable then exit;
415
  if PlayGroundMatrix.FieldState(DestX, DestY) <> fsAvailable then exit;
522
 
416
 
523
  // Check 2: Befindet sich ein Stein zwischen Source und Destination und ist der Abstand 2?
417
  // Check 2: Befindet sich ein Stein zwischen Source und Destination und ist der Abstand 2?
524
  if Level.GetGameMode = gmDiagonal then
418
  if Level.GetGameMode = gmDiagonal then
525
  begin
419
  begin
526
    if (SourceX-2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX-1, SourceY-1) = fsStone) then result := true;
420
    if (SourceX-2 = DestX) and (SourceY-2 = DestY) and (PlayGroundMatrix.FieldState(SourceX-1, SourceY-1) = fsStone) then result := true;
527
    if (SourceX-2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX-1, SourceY+1) = fsStone) then result := true;
421
    if (SourceX-2 = DestX) and (SourceY+2 = DestY) and (PlayGroundMatrix.FieldState(SourceX-1, SourceY+1) = fsStone) then result := true;
528
    if (SourceX+2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX+1, SourceY-1) = fsStone) then result := true;
422
    if (SourceX+2 = DestX) and (SourceY-2 = DestY) and (PlayGroundMatrix.FieldState(SourceX+1, SourceY-1) = fsStone) then result := true;
529
    if (SourceX+2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX+1, SourceY+1) = fsStone) then result := true;
423
    if (SourceX+2 = DestX) and (SourceY+2 = DestY) and (PlayGroundMatrix.FieldState(SourceX+1, SourceY+1) = fsStone) then result := true;
530
  end;
424
  end;
531
 
425
 
532
  if (SourceX+2 = DestX) and (SourceY   = DestY) and (FieldState(SourceX+1, SourceY  ) = fsStone) then result := true;
426
  if (SourceX+2 = DestX) and (SourceY   = DestY) and (PlayGroundMatrix.FieldState(SourceX+1, SourceY  ) = fsStone) then result := true;
533
  if (SourceX-2 = DestX) and (SourceY   = DestY) and (FieldState(SourceX-1, SourceY  ) = fsStone) then result := true;
427
  if (SourceX-2 = DestX) and (SourceY   = DestY) and (PlayGroundMatrix.FieldState(SourceX-1, SourceY  ) = fsStone) then result := true;
534
  if (SourceX   = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX  , SourceY+1) = fsStone) then result := true;
428
  if (SourceX   = DestX) and (SourceY+2 = DestY) and (PlayGroundMatrix.FieldState(SourceX  , SourceY+1) = fsStone) then result := true;
535
  if (SourceX   = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX  , SourceY-1) = fsStone) then result := true;
429
  if (SourceX   = DestX) and (SourceY-2 = DestY) and (PlayGroundMatrix.FieldState(SourceX  , SourceY-1) = fsStone) then result := true;
536
end;
430
end;
537
 
431
 
538
function TMainForm.MayJump(SourceTag, DestTag: integer): boolean;
432
function TMainForm.MayJump(SourceTag, DestTag: integer): boolean;
539
var
433
var
540
  s, d: TPoint;
434
  s, d: TPoint;
541
begin
435
begin
542
  d := LookupFieldCoordinateArray[DestTag];
436
  d := LookupFieldCoordinateArray[DestTag];
543
  s := LookupFieldCoordinateArray[SourceTag];
437
  s := LookupFieldCoordinateArray[SourceTag];
544
 
438
 
545
  result := MayJump(s.X, s.Y, d.X, d.Y);
439
  result := MayJump(s.X, s.Y, d.X, d.Y);
546
end;
440
end;
547
 
441
 
548
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
442
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
549
begin
443
begin
550
  DoJump(TComponent(Source).Tag, TComponent(Sender).Tag);
444
  DoJump(TComponent(Source).Tag, TComponent(Sender).Tag);
551
end;
445
end;
552
 
446
 
553
procedure TMainForm.StoneDragOver(Sender, Source: TObject; X,
447
procedure TMainForm.StoneDragOver(Sender, Source: TObject; X,
554
  Y: Integer; State: TDragState; var Accept: Boolean);
448
  Y: Integer; State: TDragState; var Accept: Boolean);
555
begin
449
begin
556
  Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag);
450
  Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag);
557
end;
451
end;
558
 
452
 
559
function TMainForm.DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField;
453
function TMainForm.DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField;
560
var
454
var
561
  newField: TField;
455
  newField: TField;
562
  index: integer;
456
  index: integer;
563
begin
457
begin
564
  ZeroMemory(@result, SizeOf(result));
458
  ZeroMemory(@result, SizeOf(result));
565
  if t.Typ = ftFullSpace then exit;
459
  if t.Typ = ftFullSpace then exit;
566
 
460
 
567
  index := Length(LookupFieldCoordinateArray);
461
  index := Length(LookupFieldCoordinateArray);
568
 
462
 
569
  newField.FieldType := t.Typ;
463
  newField.FieldType := t.Typ;
570
  newField.Goal := t.Goal;
464
  newField.Goal := t.Goal;
571
  newField.Panel := DrawStoneBox(x, y, index, indent, t.Goal);
465
  newField.Panel := DrawStoneBox(x, y, index, indent, t.Goal);
572
  newField.Stone := DrawStone(t.Typ, newField.Panel);
466
  newField.Stone := DrawStone(t.Typ, newField.Panel);
573
  if FieldState(t.Typ) = fsStone then Inc(LevelTotalStones);
467
  if PlayGroundMatrix.FieldState(t.Typ) = fsStone then Inc(LevelTotalStones);
574
 
468
 
575
  SetLength(LookupFieldCoordinateArray, index + 1);
469
  SetLength(LookupFieldCoordinateArray, index + 1);
576
  LookupFieldCoordinateArray[index].X := x;
470
  LookupFieldCoordinateArray[index].X := x;
577
  LookupFieldCoordinateArray[index].Y := y;
471
  LookupFieldCoordinateArray[index].Y := y;
578
 
472
 
579
  if Length(PlayGroundMatrix) < x+1 then SetLength(PlayGroundMatrix, x+1);
473
  if Length(PlayGroundMatrix.Fields) < x+1 then SetLength(PlayGroundMatrix.Fields, x+1);
580
  if Length(PlayGroundMatrix[x]) < y+1 then SetLength(PlayGroundMatrix[x], y+1);
474
  if Length(PlayGroundMatrix.Fields[x]) < y+1 then SetLength(PlayGroundMatrix.Fields[x], y+1);
581
  PlaygroundMatrix[x, y] := newField;
475
  PlaygroundMatrix.Fields[x, y] := newField;
582
 
476
 
583
  result := newField;
477
  result := newField;
584
end;
478
end;
585
 
479
 
586
function TMainForm.CloneMatrix(Source: TPlayGroundMatrix): TPlayGroundMatrix;
-
 
587
var
-
 
588
  i, j: integer;
-
 
589
begin
-
 
590
  SetLength(result, Length(Source));
-
 
591
  for i := Low(Source) to High(Source) do
-
 
592
  begin
-
 
593
    SetLength(result[i], Length(Source[i]));
-
 
594
    for j := Low(Source[i]) to High(Source[i]) do
-
 
595
    begin
-
 
596
      result[i][j].FieldType := Source[i][j].FieldType;
-
 
597
      result[i][j].Goal      := Source[i][j].Goal;
-
 
598
      result[i][j].Panel     := Source[i][j].Panel;
-
 
599
      result[i][j].Stone     := Source[i][j].Stone;
-
 
600
    end;
-
 
601
  end;
-
 
602
end;
-
 
603
 
-
 
604
procedure TMainForm.BuildPlayground(LevelArray: TLevelArray);
480
procedure TMainForm.BuildPlayground(LevelArray: TLevelArray);
605
var
481
var
606
  y, x: integer;
482
  y, x: integer;
607
  max_x, max_y: integer;
483
  max_x, max_y: integer;
608
  p: TPanel;
484
  p: TPanel;
609
begin
485
begin
610
  PlayGround.Visible := false;
486
  PlayGround.Visible := false;
611
 
487
 
612
  // Die Dimensionen ermitteln
488
  // Die Dimensionen ermitteln
613
  max_x := 0;
489
  max_x := 0;
614
  max_y := 0;
490
  max_y := 0;
615
  for y := Low(LevelArray) to High(LevelArray) do
491
  for y := Low(LevelArray) to High(LevelArray) do
616
  begin
492
  begin
617
    for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do
493
    for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do
618
    begin
494
    begin
619
      p := DrawField(x, y, LevelArray[y].Fields[x], LevelArray[y].Indent).Panel;
495
      p := DrawField(x, y, LevelArray[y].Fields[x], LevelArray[y].Indent).Panel;
620
      if Assigned(p) then
496
      if Assigned(p) then
621
      begin
497
      begin
622
        max_x := Max(max_x, p.Left + p.Width);
498
        max_x := Max(max_x, p.Left + p.Width);
623
        max_y := Max(max_y, p.Top  + p.Height);
499
        max_y := Max(max_y, p.Top  + p.Height);
624
      end;
500
      end;
625
    end;
501
    end;
626
  end;
502
  end;
627
 
503
 
628
  PlayGround.Visible := true;
504
  PlayGround.Visible := true;
629
 
505
 
630
  // Das Form an das Level anpassen
506
  // Das Form an das Level anpassen
631
  PlayGround.Top    := MET_OUTER_MARGIN;
507
  PlayGround.Top    := MET_OUTER_MARGIN;
632
  PlayGround.Left   := MET_OUTER_MARGIN;
508
  PlayGround.Left   := MET_OUTER_MARGIN;
633
  PlayGround.Width  := max_x;
509
  PlayGround.Width  := max_x;
634
  PlayGround.Height := max_y;
510
  PlayGround.Height := max_y;
635
  ClientWidth       := 2 * MET_OUTER_MARGIN + PlayGround.Width;
511
  ClientWidth       := 2 * MET_OUTER_MARGIN + PlayGround.Width;
636
  ClientHeight      := 2 * MET_OUTER_MARGIN + PlayGround.Height + Statistics.Height;
512
  ClientHeight      := 2 * MET_OUTER_MARGIN + PlayGround.Height + Statistics.Height;
637
 
513
 
638
  // If the board is too small, ClientWidth/ClientHeight will stop at a minimum value
514
  // If the board is too small, ClientWidth/ClientHeight will stop at a minimum value
639
  // in this case, we make sure that the Playground is centered
515
  // in this case, we make sure that the Playground is centered
640
  PlayGround.Left := ClientWidth div 2 - Playground.Width div 2;
516
  PlayGround.Left := ClientWidth div 2 - Playground.Width div 2;
641
  PlayGround.Top := (ClientHeight - Statistics.Height) div 2 - Playground.Height div 2;
517
  PlayGround.Top := (ClientHeight - Statistics.Height) div 2 - Playground.Height div 2;
642
 
518
 
643
  Statistics.Panels.Items[0].Width := Round(ClientWidth*MET_PERCENT_PNL_TIME);
519
  Statistics.Panels.Items[0].Width := Round(ClientWidth*MET_PERCENT_PNL_TIME);
644
  Statistics.Panels.Items[1].Width := Round(ClientWidth*MET_PERCENT_PNL_STONES);
520
  Statistics.Panels.Items[1].Width := Round(ClientWidth*MET_PERCENT_PNL_STONES);
645
 
521
 
646
  SetLength(PrevPlaygroundMatrixes,1);
522
  SetLength(PrevPlaygroundMatrixes,1);
647
  PrevPlaygroundMatrixes[0] := CloneMatrix(PlayGroundMatrix);
523
  PrevPlaygroundMatrixes[0] := PlayGroundMatrix.CloneMatrix;
648
  MUndo.Enabled := false;
524
  MUndo.Enabled := false;
649
end;
525
end;
650
 
526
 
651
procedure TMainForm.TimerTimer(Sender: TObject);
527
procedure TMainForm.TimerTimer(Sender: TObject);
652
begin
528
begin
-
 
529
  if MPauseTime.Checked then exit;
653
  if mainform.Focused then Inc(CountedSeconds);
530
  if mainform.Focused then Inc(CountedSeconds);
654
  RefreshTime;
531
  RefreshTime;
655
end;
532
end;
656
 
533
 
657
function TMainForm.LevelTime: String;
534
function TMainForm.LevelTime: String;
658
begin
535
begin
659
  result := SecondsToTimeString(CountedSeconds);
536
  result := FormatDateTime('hh:nn:ss', CountedSeconds / SecsPerDay)
660
end;
537
end;
661
 
538
 
662
procedure TMainForm.NewGame(Filename: string);
539
procedure TMainForm.NewGame(Filename: string);
-
 
540
resourcestring
-
 
541
  LNG_LVL_INVALID_NO_JUMP = 'Warning! The level is not playable. There are no jumps possible.';
663
var
542
var
664
  LevelArray: TLevelArray;
543
  LevelArray: TLevelArray;
665
begin
544
begin
666
  DestroyLevel;
545
  DestroyLevel;
-
 
546
 
-
 
547
  MPauseTime.Checked := true;
-
 
548
  MPauseTime.Enabled := true;
-
 
549
  Timer.Enabled := true;
-
 
550
  MRestartGame.Enabled := true;
-
 
551
 
667
  LevelFile := Filename;
552
  LevelFile := Filename;
668
  Level := TLevel.Create(LevelFile);
553
  Level := TLevel.Create(LevelFile);
669
  LevelArray := Level.LevelStringToLevelArray(true);
554
  LevelArray := Level.LevelStringToLevelArray(true);
670
  if Length(LevelArray) = 0 then Exit;
555
  if Length(LevelArray) = 0 then Exit;
671
  BuildPlayground(LevelArray);
556
  BuildPlayground(LevelArray);
672
  if not AreJumpsPossible then
557
  if not AreJumpsPossible then
673
  begin
558
  begin
674
    MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0);
559
    MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0);
675
  end;
560
  end;
676
  RefreshTime;
561
  RefreshTime;
677
  RefreshStonesRemoved;
562
  RefreshStonesRemoved;
678
  RefreshPoints;
563
  RefreshPoints;
679
end;
564
end;
680
 
565
 
681
procedure TMainForm.MNewGameClick(Sender: TObject);
566
procedure TMainForm.MNewGameClick(Sender: TObject);
682
begin
567
begin
683
  LevelFile := AskForLevel;
568
  LevelFile := AskForLevel;
684
  if LevelFile <> '' then
569
  if LevelFile <> '' then
685
  begin
570
  begin
686
    NewGame(LevelFile);
571
    NewGame(LevelFile);
687
  end;
572
  end;
688
end;
573
end;
689
 
574
 
690
procedure TMainForm.MAboutClick(Sender: TObject);
575
procedure TMainForm.MAboutClick(Sender: TObject);
691
begin
576
begin
692
  AboutBox.ShowModal;
577
  AboutBox.ShowModal;
693
end;
578
end;
694
 
579
 
695
function TMainForm.AskForLevel: String;
580
function TMainForm.AskForLevel: String;
696
begin
581
begin
697
  LevelChoice.ShowModal;
582
  LevelChoice.ShowModal;
698
 
583
 
699
  if LevelChoice.ModalResult <> mrOK then
584
  if LevelChoice.ModalResult <> mrOK then
700
  begin
585
  begin
701
    result := '';
586
    result := '';
702
    exit;
587
    exit;
703
  end;
588
  end;
704
 
589
 
705
  result := LevelChoice.SelectedLevel;
590
  result := LevelChoice.SelectedLevel;
706
end;
591
end;
707
 
592
 
708
procedure TMainForm.FormShow(Sender: TObject);
593
procedure TMainForm.FormShow(Sender: TObject);
709
begin
594
begin
710
  LevelFile := AskForLevel;
595
  LevelFile := AskForLevel;
711
  if LevelFile <> '' then
596
  if LevelFile <> '' then
712
  begin
597
  begin
713
    NewGame(LevelFile);
598
    NewGame(LevelFile);
714
  end
599
  end
715
  else
600
  else
716
  begin
601
  begin
717
    NoCloseQuery := true;
602
    NoCloseQuery := true;
718
    Close;
603
    Close;
719
  end;
604
  end;
720
end;
605
end;
721
 
606
 
722
function TMainForm.GoalStatus: TGoalStatus;
607
function TMainForm.GoalStatus: TGoalStatus;
723
var
608
var
724
  ft: TFieldType;
609
  ft: TFieldType;
725
begin
610
begin
726
  if not MatrixHasGoal(PlaygroundMatrix) then
611
  if not PlaygroundMatrix.MatrixHasGoal then
727
    result := gsNoGoal
612
    result := gsNoGoal
728
  else if LevelRemovedStones < LevelTotalStones-1 then
613
  else if LevelRemovedStones < LevelTotalStones-1 then
729
    Result := gsMultipleStonesRemaining
614
    Result := gsMultipleStonesRemaining
730
  else
615
  else
731
  begin
616
  begin
732
    ft := GoalFieldType(PlaygroundMatrix);
617
    ft := PlaygroundMatrix.GoalFieldType;
733
    if ft = ftRed then
618
    if ft = ftRed then
734
      result := gsLastStoneInGoalRed
619
      result := gsLastStoneInGoalRed
735
    else if ft = ftYellow then
620
    else if ft = ftYellow then
736
      result := gsLastStoneInGoalYellow
621
      result := gsLastStoneInGoalYellow
737
    else if ft = ftGreen then
622
    else if ft = ftGreen then
738
      result := gsLastStoneInGoalGreen
623
      result := gsLastStoneInGoalGreen
739
    else
624
    else
740
      result := gsUndefined;
625
      result := gsUndefined;
741
  end;
626
  end;
742
end;
627
end;
743
 
628
 
744
procedure TMainForm.FormCreate(Sender: TObject);
629
procedure TMainForm.FormCreate(Sender: TObject);
745
begin
630
begin
746
  JumpHistory := TStringList.Create;
631
  JumpHistory := TStringList.Create;
747
  LoadSettings;
632
  LoadSettings;
748
end;
633
end;
749
 
634
 
750
procedure TMainForm.FormDestroy(Sender: TObject);
635
procedure TMainForm.FormDestroy(Sender: TObject);
751
begin
636
begin
752
  DestroyLevel;
637
  DestroyLevel;
753
  JumpHistory.Free;
638
  JumpHistory.Free;
754
end;
639
end;
755
 
640
 
756
procedure TMainForm.MJumpHistoryClick(Sender: TObject);
641
procedure TMainForm.MJumpHistoryClick(Sender: TObject);
757
begin
642
begin
758
  HistoryForm.JumpMemo.Lines.Assign(JumpHistory);
643
  HistoryForm.JumpMemo.Lines.Assign(JumpHistory);
759
  HistoryForm.ShowModal;
644
  HistoryForm.ShowModal;
760
end;
645
end;
761
 
646
 
762
procedure TMainForm.RestartLevel;
647
procedure TMainForm.RestartLevel;
763
var
648
var
764
  i: Integer;
649
  i: Integer;
765
begin
650
begin
766
  MPauseTime.Enabled := false;
651
  MPauseTime.Checked := true;
767
  Timer.Enabled := false;
652
  MPauseTime.Enabled := true;
768
 
-
 
769
  MRestartGame.Enabled := false;
653
  Timer.Enabled := true;
770
 
654
 
771
  CountedSeconds := 0;
655
  CountedSeconds := 0;
772
  RefreshTime;
656
  RefreshTime;
773
 
657
 
774
  Points := 0;
658
  Points := 0;
775
  RefreshPoints;
659
  RefreshPoints;
776
 
660
 
777
  LevelRemovedStones := 0;
661
  LevelRemovedStones := 0;
778
  RefreshStonesRemoved;
662
  RefreshStonesRemoved;
779
 
663
 
780
  JumpHistory.Clear;
664
  JumpHistory.Clear;
781
 
665
 
782
  RedrawStonesFromMatrix(PrevPlaygroundMatrixes[0]);
666
  RedrawStonesFromMatrix(PrevPlaygroundMatrixes[0]);
783
  SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[0]);
667
  SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[0]);
784
  for i := 1 to Length(PrevPlaygroundMatrixes)-1 do
668
  for i := 1 to Length(PrevPlaygroundMatrixes)-1 do
785
    ClearMatrix(PrevPlaygroundMatrixes[i], false);
669
    PrevPlaygroundMatrixes[i].ClearMatrix(false);
786
  SetLength(PrevPlaygroundMatrixes, 1);
670
  SetLength(PrevPlaygroundMatrixes, 1);
787
 
671
 
788
  MUndo.Enabled := false;
672
  MUndo.Enabled := false;
789
end;
673
end;
790
 
674
 
791
procedure TMainForm.SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
675
procedure TMainForm.SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
792
begin
676
begin
793
  ClearMatrix(PlayGroundMatrix, false); // Memory Leak verhindern
677
  PlayGroundMatrix.ClearMatrix(false); // Memory Leak verhindern
794
  PlayGroundMatrix := CloneMatrix(Matrix);
678
  PlayGroundMatrix := Matrix.CloneMatrix;
795
end;
679
end;
796
 
680
 
797
procedure TMainForm.MRestartGameClick(Sender: TObject);
681
procedure TMainForm.MRestartGameClick(Sender: TObject);
798
begin
682
begin
799
  RestartLevel;
683
  RestartLevel;
800
end;
684
end;
801
 
685
 
802
procedure TMainForm.MUndoClick(Sender: TObject);
686
procedure TMainForm.MUndoClick(Sender: TObject);
803
var
687
var
804
  PrevWorth: integer;
688
  PrevWorth: integer;
805
  NewWorth: integer;
689
  NewWorth: integer;
806
begin
690
begin
807
  if Length(PrevPlaygroundMatrixes) > 1 then
691
  if Length(PrevPlaygroundMatrixes) > 1 then
808
  begin
692
  begin
809
    PrevWorth := MatrixWorth(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
693
    PrevWorth := PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].MatrixWorth;
810
 
694
 
811
    ClearMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1], false);
695
    PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].ClearMatrix(false);
812
    SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)-1);
696
    SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)-1);
813
 
697
 
814
    NewWorth := MatrixWorth(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
698
    NewWorth := PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].MatrixWorth;
815
    RedrawStonesFromMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
699
    RedrawStonesFromMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
816
    SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
700
    SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
817
 
701
 
818
    JumpHistory.Delete(JumpHistory.Count-1);
702
    JumpHistory.Delete(JumpHistory.Count-1);
819
 
703
 
820
    Dec(LevelRemovedStones);
704
    Dec(LevelRemovedStones);
821
    RefreshStonesRemoved;
705
    RefreshStonesRemoved;
822
 
706
 
823
    Dec(Points, NewWorth-PrevWorth);
707
    Dec(Points, NewWorth-PrevWorth);
824
    RefreshPoints;
708
    RefreshPoints;
825
 
709
 
826
    // Sound abspielen
710
    // Sound abspielen
827
    if MEnableSound.Checked then PlaySound(RES_UNDO, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
711
    if MEnableSound.Checked then PlaySound(RES_UNDO, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
828
  end;
712
  end;
829
 
713
 
830
  MUndo.Enabled := Length(PrevPlaygroundMatrixes) > 1;
714
  MUndo.Enabled := Length(PrevPlaygroundMatrixes) > 1;
831
end;
715
end;
832
 
716
 
833
procedure TMainForm.MHighScoresClick(Sender: TObject);
717
procedure TMainForm.MHighScoresClick(Sender: TObject);
834
begin
718
begin
835
  HighScoreForm.Execute(ExtractFileNameWithoutExt(LevelFile));
719
  HighScoreForm.Execute(ExtractFileNameWithoutExt(LevelFile));
836
end;
720
end;
837
 
721
 
838
procedure TMainForm.MPauseTimeClick(Sender: TObject);
-
 
839
begin
-
 
840
  MPauseTime.Enabled := false;
-
 
841
  Timer.Enabled := false;
-
 
842
end;
-
 
843
 
-
 
844
procedure TMainForm.LoadSettings;
722
procedure TMainForm.LoadSettings;
845
var
723
var
846
  reg: TRegistry;
724
  reg: TRegistry;
847
begin
725
begin
848
  reg := TRegistry.Create;
726
  reg := TRegistry.Create;
849
  try
727
  try
850
    reg.RootKey := HKEY_CURRENT_USER;
728
    reg.RootKey := HKEY_CURRENT_USER;
851
    if reg.OpenKeyReadOnly(REG_KEY) then
729
    if reg.OpenKeyReadOnly(REG_KEY) then
852
    begin
730
    begin
853
      if reg.ValueExists(REG_SOUND) then
731
      if reg.ValueExists(REG_SOUND) then
854
        MEnableSound.Checked := reg.ReadBool(REG_SOUND);
732
        MEnableSound.Checked := reg.ReadBool(REG_SOUND);
855
      reg.CloseKey;
733
      reg.CloseKey;
856
    end;
734
    end;
857
  finally
735
  finally
858
    reg.Free;
736
    reg.Free;
859
  end;
737
  end;
860
end;
738
end;
861
 
739
 
862
procedure TMainForm.SaveSettings;
740
procedure TMainForm.SaveSettings;
863
var
741
var
864
  reg: TRegistry;
742
  reg: TRegistry;
865
begin
743
begin
866
  reg := TRegistry.Create;
744
  reg := TRegistry.Create;
867
  try
745
  try
868
    reg.RootKey := HKEY_CURRENT_USER;
746
    reg.RootKey := HKEY_CURRENT_USER;
869
    if reg.OpenKey(REG_KEY, true) then
747
    if reg.OpenKey(REG_KEY, true) then
870
    begin
748
    begin
871
      reg.WriteBool(REG_SOUND, MEnableSound.Checked);
749
      reg.WriteBool(REG_SOUND, MEnableSound.Checked);
872
      reg.CloseKey;
750
      reg.CloseKey;
873
    end;
751
    end;
874
  finally
752
  finally
875
    reg.Free;
753
    reg.Free;
876
  end;
754
  end;
877
end;
755
end;
878
 
756
 
879
 
-
 
880
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
757
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
881
begin
758
begin
882
  SaveSettings;
759
  SaveSettings;
883
  if FinishForm.NameEdit.Text <> '' then
760
  if FinishForm.NameEdit.Text <> '' then
884
  begin
761
  begin
885
    FinishForm.SaveSettings;
762
    FinishForm.SaveSettings;
886
  end;
763
  end;
887
end;
764
end;
888
 
765
 
889
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
766
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
890
resourcestring
767
resourcestring
891
  LNG_REALLY_QUIT = 'Do you really want to quit?';
768
  LNG_REALLY_QUIT = 'Do you really want to quit?';
892
begin
769
begin
893
  CanClose := NoCloseQuery or (MessageDlg(LNG_REALLY_QUIT, mtConfirmation, mbYesNoCancel, 0) = mrYes);
770
  CanClose := NoCloseQuery or (MessageDlg(LNG_REALLY_QUIT, mtConfirmation, mbYesNoCancel, 0) = mrYes);
894
end;
771
end;
895
 
772
 
896
procedure TMainForm.MHelpClick(Sender: TObject);
773
procedure TMainForm.MHelpClick(Sender: TObject);
897
begin
774
begin
898
  HelpForm.ShowModal;
775
  HelpForm.ShowModal;
899
end;
776
end;
900
 
-
 
901
procedure TMainForm.MEnableSoundClick(Sender: TObject);
-
 
902
begin
-
 
903
  MEnableSound.Checked := not MEnableSound.Checked;
-
 
904
end;
-
 
905
 
777
 
906
end.
778
end.
907
 
779