Subversion Repositories jumper

Rev

Rev 26 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 26 Rev 29
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
  TMainForm = class(TForm)
10
  TMainForm = class(TForm)
11
    Playground: TPanel;
11
    Playground: TPanel;
12
    MainMenu: TMainMenu;
12
    MainMenu: TMainMenu;
13
    Help1: TMenuItem;
13
    Help1: TMenuItem;
14
    MExit: TMenuItem;
14
    MExit: TMenuItem;
15
    Statistics: TStatusBar;
15
    Statistics: TStatusBar;
16
    Timer: TTimer;
16
    Timer: TTimer;
17
    MNewGame: TMenuItem;
17
    MNewGame: TMenuItem;
18
    Help2: TMenuItem;
18
    Help2: TMenuItem;
19
    MAbout: TMenuItem;
19
    MAbout: TMenuItem;
20
    MHelp: TMenuItem;
20
    MHelp: TMenuItem;
21
    N5: TMenuItem;
21
    N5: TMenuItem;
22
    MJumpHistory: TMenuItem;
22
    MJumpHistory: TMenuItem;
23
    N2: TMenuItem;
23
    N2: TMenuItem;
24
    N4: TMenuItem;
24
    N4: TMenuItem;
25
    MHighScores: TMenuItem;
25
    MHighScores: TMenuItem;
26
    MRestartGame: TMenuItem;
26
    MRestartGame: TMenuItem;
27
    MSettings: TMenuItem;
27
    MSettings: TMenuItem;
28
    MEnableSound: TMenuItem;
28
    MEnableSound: TMenuItem;
29
    MPauseTime: TMenuItem;
29
    MPauseTime: TMenuItem;
30
    N1: TMenuItem;
30
    N1: TMenuItem;
31
    MUndo: TMenuItem;
31
    MUndo: TMenuItem;
32
    N3: TMenuItem;
32
    N3: TMenuItem;
33
    Aboutthislevel1: TMenuItem;
33
    Aboutthislevel1: TMenuItem;
34
    procedure MExitClick(Sender: TObject);
34
    procedure MExitClick(Sender: TObject);
35
    procedure TimerTimer(Sender: TObject);
35
    procedure TimerTimer(Sender: TObject);
36
    procedure MNewGameClick(Sender: TObject);
36
    procedure MNewGameClick(Sender: TObject);
37
    procedure MAboutClick(Sender: TObject);
37
    procedure MAboutClick(Sender: TObject);
38
    procedure FormShow(Sender: TObject);
38
    procedure FormShow(Sender: TObject);
39
    procedure FormCreate(Sender: TObject);
39
    procedure FormCreate(Sender: TObject);
40
    procedure FormDestroy(Sender: TObject);
40
    procedure FormDestroy(Sender: TObject);
41
    procedure MJumpHistoryClick(Sender: TObject);
41
    procedure MJumpHistoryClick(Sender: TObject);
42
    procedure MRestartGameClick(Sender: TObject);
42
    procedure MRestartGameClick(Sender: TObject);
43
    procedure MHighScoresClick(Sender: TObject);
43
    procedure MHighScoresClick(Sender: TObject);
44
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
44
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
45
    procedure MHelpClick(Sender: TObject);
45
    procedure MHelpClick(Sender: TObject);
46
    procedure MUndoClick(Sender: TObject);
46
    procedure MUndoClick(Sender: TObject);
47
    procedure Aboutthislevel1Click(Sender: TObject);
47
    procedure Aboutthislevel1Click(Sender: TObject);
48
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
48
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
49
  private
49
  private
50
    NoCloseQuery: boolean;
50
    NoCloseQuery: boolean;
51
    CountedSeconds: Integer;
51
    CountedSeconds: Integer;
52
    LevelFile: String;
52
    LevelFile: String;
53
    PrevPlaygroundMatrixes: array of TPlayGroundMatrix;
53
    PrevPlaygroundMatrixes: array of TPlayGroundMatrix;
54
    PlaygroundMatrix: TPlayGroundMatrix;
54
    PlaygroundMatrix: TPlayGroundMatrix;
55
    Points: Integer;
55
    Points: Integer;
56
    LevelTotalStones: Integer;
56
    LevelTotalStones: Integer;
57
    LevelRemovedStones: Integer;
57
    LevelRemovedStones: Integer;
58
    JumpHistory: TStringList;
58
    JumpHistory: TStringList;
59
    Level: TLevel;
59
    Level: TLevel;
60
    procedure LoadSettings;
60
    procedure LoadSettings;
61
    procedure SaveSettings;
61
    procedure SaveSettings;
62
    procedure RestartLevel;
62
    procedure RestartLevel;
63
    procedure SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
63
    procedure SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
64
    procedure RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
64
    procedure RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
65
    function AskForLevel: String;
65
    function AskForLevel: String;
66
    procedure StoneDraggingAllow(Stone: TImage; Allow: boolean);
66
    procedure StoneDraggingAllow(Stone: TImage; Allow: boolean);
67
    procedure NewGame(Filename: string);
67
    procedure NewGame(Filename: string);
68
    function LevelTime: String;
68
    function LevelTime: String;
69
    procedure DestroyLevel;
69
    procedure DestroyLevel;
70
    procedure RefreshTime;
70
    procedure RefreshTime;
71
    procedure RefreshPoints;
71
    procedure RefreshPoints;
72
    procedure RefreshStonesRemoved;
72
    procedure RefreshStonesRemoved;
73
    procedure RemoveStone(x, y: integer; count_points: boolean);
73
    procedure RemoveStone(x, y: integer; count_points: boolean);
74
    procedure DoJump(SourceTag, DestTag: integer);
74
    procedure DoJump(SourceTag, DestTag: integer);
75
    function MayJump(SourceTag, DestTag: integer): boolean; overload;
75
    function MayJump(SourceTag, DestTag: integer): boolean; overload;
76
    procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
76
    procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
77
    procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
77
    procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
78
    procedure DrawField(x, y: integer; var f: TField);
78
    procedure DrawField(x, y: integer; var f: TField);
79
    function DrawStone(f: TField): TImage;
79
    function DrawStone(f: TField): TImage;
80
    function DrawStoneBox(x, y, tag: integer; f: TField): TPanel;
80
    function DrawStoneBox(x, y, tag: integer; f: TField): TPanel;
81
    procedure LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
81
    procedure LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
82
    function GoalStatus: TGoalStatus;
82
    function GoalStatus: TGoalStatus;
83
  end;
83
  end;
84
 
84
 
85
var
85
var
86
  MainForm: TMainForm;
86
  MainForm: TMainForm;
87
 
87
 
88
implementation
88
implementation
89
 
89
 
90
uses
90
uses
91
  About, Finish, Choice, Functions, History, HighScore, Help, Constants, Math;
91
  About, Finish, Choice, Functions, History, HighScore, Help, Constants, Math;
92
 
92
 
93
{$R *.dfm}
93
{$R *.dfm}
94
 
94
 
95
type
95
type
96
  TFieldVclData = class(TObject)
96
  TFieldVclData = class(TObject)
97
  public
97
  public
98
    Panel: TPanel;
98
    Panel: TPanel;
99
    Stone: TImage;
99
    Stone: TImage;
100
    destructor Destroy; override;
100
    destructor Destroy; override;
101
  end;
101
  end;
102
 
102
 
103
{ TMainForm }
103
{ TMainForm }
104
 
104
 
105
procedure TMainForm.RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
105
procedure TMainForm.RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
106
var
106
var
107
  x, y: integer;
107
  x, y: integer;
108
begin
108
begin
109
  for x := Low(Matrix.Fields) to High(Matrix.Fields) do
109
  for x := Low(Matrix.Fields) to High(Matrix.Fields) do
110
  begin
110
  begin
111
    for y := Low(Matrix.Fields[x]) to High(Matrix.Fields[x]) do
111
    for y := Low(Matrix.Fields[x]) to High(Matrix.Fields[x]) do
112
    begin
112
    begin
113
      if Assigned(Matrix.Fields[x,y].Data) and
113
      if Assigned(Matrix.Fields[x,y].Data) and
114
         Assigned(TFieldVclData(Matrix.Fields[x,y].Data).Stone) then
114
         Assigned(TFieldVclData(Matrix.Fields[x,y].Data).Stone) then
115
      begin
115
      begin
116
        LoadPictureForType(Matrix.Fields[x,y].FieldType,
116
        LoadPictureForType(Matrix.Fields[x,y].FieldType,
117
                           TFieldVclData(Matrix.Fields[x,y].Data).Stone.Picture);
117
                           TFieldVclData(Matrix.Fields[x,y].Data).Stone.Picture);
118
        StoneDraggingAllow(TFieldVclData(Matrix.Fields[x,y].Data).Stone,
118
        StoneDraggingAllow(TFieldVclData(Matrix.Fields[x,y].Data).Stone,
119
                           Matrix.Fields[x,y].FieldState <> fsAvailable);
119
                           Matrix.Fields[x,y].FieldState <> fsAvailable);
120
      end;
120
      end;
121
    end;
121
    end;
122
  end;
122
  end;
123
end;
123
end;
124
 
124
 
125
procedure TMainForm.DestroyLevel;
125
procedure TMainForm.DestroyLevel;
126
var
126
var
127
  i: Integer;
127
  i: Integer;
128
begin
128
begin
129
  MPauseTime.Checked := false;
129
  MPauseTime.Checked := false;
130
  MPauseTime.Enabled := false;
130
  MPauseTime.Enabled := false;
131
  Timer.Enabled := false;
131
  Timer.Enabled := false;
132
 
132
 
133
  MRestartGame.Enabled := false;
133
  MRestartGame.Enabled := false;
134
 
134
 
135
  LevelFile := '';
135
  LevelFile := '';
136
 
136
 
137
  CountedSeconds := 0;
137
  CountedSeconds := 0;
138
  RefreshTime;
138
  RefreshTime;
139
 
139
 
140
  Points := 0;
140
  Points := 0;
141
  RefreshPoints;
141
  RefreshPoints;
142
 
142
 
143
  LevelRemovedStones := 0;
143
  LevelRemovedStones := 0;
144
  LevelTotalStones := 0;
144
  LevelTotalStones := 0;
145
  RefreshStonesRemoved;
145
  RefreshStonesRemoved;
146
 
146
 
147
  JumpHistory.Clear;
147
  JumpHistory.Clear;
148
 
148
 
149
  PlayGroundMatrix.ClearMatrix(true);
149
  PlayGroundMatrix.ClearMatrix(true);
150
  for i := 0 to Length(PrevPlaygroundMatrixes)-1 do
150
  for i := 0 to Length(PrevPlaygroundMatrixes)-1 do
151
    PrevPlaygroundMatrixes[i].ClearMatrix(false);
151
    PrevPlaygroundMatrixes[i].ClearMatrix(false);
152
  SetLength(PrevPlaygroundMatrixes, 0);
152
  SetLength(PrevPlaygroundMatrixes, 0);
153
  MUndo.Enabled := false;
153
  MUndo.Enabled := false;
154
 
154
 
155
  if Assigned(Level) then FreeAndNil(Level);
155
  if Assigned(Level) then FreeAndNil(Level);
156
end;
156
end;
157
 
157
 
158
procedure TMainForm.LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
158
procedure TMainForm.LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
159
begin
159
begin
160
  case FieldType of
160
  case FieldType of
161
    ftEmpty:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_EMPTY);
161
    ftEmpty:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_EMPTY);
162
    ftGreen:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_GREEN);
162
    ftGreen:  Picture.Bitmap.LoadFromResourceName(HInstance, RES_GREEN);
163
    ftYellow: Picture.Bitmap.LoadFromResourceName(HInstance, RES_YELLOW);
163
    ftYellow: Picture.Bitmap.LoadFromResourceName(HInstance, RES_YELLOW);
164
    ftRed:    Picture.Bitmap.LoadFromResourceName(HInstance, RES_RED);
164
    ftRed:    Picture.Bitmap.LoadFromResourceName(HInstance, RES_RED);
165
  end;
165
  end;
166
end;
166
end;
167
 
167
 
168
function TMainForm.DrawStone(f: TField): TImage;
168
function TMainForm.DrawStone(f: TField): TImage;
169
var
169
var
170
  panel: TPanel;
170
  panel: TPanel;
171
begin
171
begin
172
  panel := TFieldVclData(f.Data).Panel;
172
  panel := TFieldVclData(f.Data).Panel;
173
 
173
 
174
  result := TImage.Create(panel);
174
  result := TImage.Create(panel);
175
  result.Parent := panel;
175
  result.Parent := panel;
176
  LoadPictureForType(f.FieldType, result.Picture);
176
  LoadPictureForType(f.FieldType, result.Picture);
177
  result.Width := panel.Width - 2*MET_SHAPE_MARGIN;
177
  result.Width := panel.Width - 2*MET_SHAPE_MARGIN;
178
  result.Height := panel.Height - 2*MET_SHAPE_MARGIN;
178
  result.Height := panel.Height - 2*MET_SHAPE_MARGIN;
179
  result.Left := MET_SHAPE_MARGIN;
179
  result.Left := MET_SHAPE_MARGIN;
180
  result.Top := MET_SHAPE_MARGIN;
180
  result.Top := MET_SHAPE_MARGIN;
181
  result.Center := true;
181
  result.Center := true;
182
  result.Transparent := true;
182
  result.Transparent := true;
183
 
183
 
184
  result.Tag := panel.Tag;
184
  result.Tag := panel.Tag;
185
  result.OnDragOver := panel.OnDragOver;
185
  result.OnDragOver := panel.OnDragOver;
186
  result.OnDragDrop := panel.OnDragDrop;
186
  result.OnDragDrop := panel.OnDragDrop;
187
 
187
 
188
  StoneDraggingAllow(result, f.FieldState <> fsAvailable);
188
  StoneDraggingAllow(result, f.FieldState <> fsAvailable);
189
end;
189
end;
190
 
190
 
191
procedure TMainForm.StoneDraggingAllow(Stone: TImage; Allow: boolean);
191
procedure TMainForm.StoneDraggingAllow(Stone: TImage; Allow: boolean);
192
begin
192
begin
193
  if Allow then
193
  if Allow then
194
  begin
194
  begin
195
    Stone.DragMode := dmAutomatic;
195
    Stone.DragMode := dmAutomatic;
196
    (Stone.Parent as TPanel).DragMode := dmAutomatic;
196
    (Stone.Parent as TPanel).DragMode := dmAutomatic;
197
  end
197
  end
198
  else
198
  else
199
  begin
199
  begin
200
    Stone.DragMode := dmManual;
200
    Stone.DragMode := dmManual;
201
    (Stone.Parent as TPanel).DragMode := dmManual;
201
    (Stone.Parent as TPanel).DragMode := dmManual;
202
  end;
202
  end;
203
end;
203
end;
204
 
204
 
205
function TMainForm.DrawStoneBox(x, y, tag: integer; f: TField): TPanel;
205
function TMainForm.DrawStoneBox(x, y, tag: integer; f: TField): TPanel;
206
begin
206
begin
207
  result := TPanel.Create(Playground);
207
  result := TPanel.Create(Playground);
208
  result.Parent := Playground;
208
  result.Parent := Playground;
209
  if f.Goal then
209
  if f.Goal then
210
  begin
210
  begin
211
    result.BevelInner := bvLowered;
211
    result.BevelInner := bvLowered;
212
  end;
212
  end;
213
  result.Color := Playground.Color;
213
  result.Color := Playground.Color;
214
  result.BevelOuter := bvLowered;
214
  result.BevelOuter := bvLowered;
215
  result.Width := MET_FIELD_SIZE;
215
  result.Width := MET_FIELD_SIZE;
216
  result.Height := MET_FIELD_SIZE;
216
  result.Height := MET_FIELD_SIZE;
217
  result.Left := x * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE + (f.Indent*MET_HALFTAB_SIZE);
217
  result.Left := x * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE + (f.Indent*MET_HALFTAB_SIZE);
218
  result.Top := y * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE;
218
  result.Top := y * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE;
219
 
219
 
220
  result.Tag := tag;
220
  result.Tag := tag;
221
  result.OnDragOver := StoneDragOver;
221
  result.OnDragOver := StoneDragOver;
222
  result.OnDragDrop := StoneDragDrop;
222
  result.OnDragDrop := StoneDragDrop;
223
end;
223
end;
224
 
224
 
225
procedure TMainForm.MExitClick(Sender: TObject);
225
procedure TMainForm.MExitClick(Sender: TObject);
226
begin
226
begin
227
  Close;
227
  Close;
228
end;
228
end;
229
 
229
 
230
procedure TMainForm.RefreshTime;
230
procedure TMainForm.RefreshTime;
231
begin
231
begin
232
  Statistics.Panels.Items[0].Text := Format(LNG_TIME, [LevelTime]);
232
  Statistics.Panels.Items[0].Text := Format(LNG_TIME, [LevelTime]);
233
end;
233
end;
234
 
234
 
235
procedure TMainForm.RefreshStonesRemoved;
235
procedure TMainForm.RefreshStonesRemoved;
236
resourcestring
236
resourcestring
237
  LNG_STONES_REMOVED = '%d of %d stones removed'; // Jumping stone not counted
237
  LNG_STONES_REMOVED = '%d of %d stones removed'; // Jumping stone not counted
238
begin
238
begin
239
  Statistics.Panels.Items[1].Text := Format(LNG_STONES_REMOVED, [LevelRemovedStones, LevelTotalStones-1]);
239
  Statistics.Panels.Items[1].Text := Format(LNG_STONES_REMOVED, [LevelRemovedStones, LevelTotalStones-1]);
240
end;
240
end;
241
 
241
 
242
procedure TMainForm.RefreshPoints;
242
procedure TMainForm.RefreshPoints;
243
begin
243
begin
244
  Statistics.Panels.Items[2].Text := Format(LNG_POINTS, [Points]);
244
  Statistics.Panels.Items[2].Text := Format(LNG_POINTS, [Points]);
245
end;
245
end;
246
 
246
 
247
procedure TMainForm.RemoveStone(x, y: integer; count_points: boolean);
247
procedure TMainForm.RemoveStone(x, y: integer; count_points: boolean);
248
begin
248
begin
249
  if count_points then
249
  if count_points then
250
  begin
250
  begin
251
    Inc(Points, FieldTypeWorth(PlayGroundMatrix.Fields[x,y].FieldType));
251
    Inc(Points, FieldTypeWorth(PlayGroundMatrix.Fields[x,y].FieldType));
252
    RefreshPoints;
252
    RefreshPoints;
253
 
253
 
254
    Inc(LevelRemovedStones);
254
    Inc(LevelRemovedStones);
255
    RefreshStonesRemoved;
255
    RefreshStonesRemoved;
256
  end;
256
  end;
257
 
257
 
258
  PlayGroundMatrix.Fields[x,y].FieldType := ftEmpty;
258
  PlayGroundMatrix.Fields[x,y].FieldType := ftEmpty;
259
  LoadPictureForType(PlayGroundMatrix.Fields[x,y].FieldType,
259
  LoadPictureForType(PlayGroundMatrix.Fields[x,y].FieldType,
260
                     TFieldVclData(PlayGroundMatrix.Fields[x,y].Data).Stone.Picture);
260
                     TFieldVclData(PlayGroundMatrix.Fields[x,y].Data).Stone.Picture);
261
  StoneDraggingAllow(TFieldVclData(PlayGroundMatrix.Fields[x,y].Data).Stone, false);
261
  StoneDraggingAllow(TFieldVclData(PlayGroundMatrix.Fields[x,y].Data).Stone, false);
262
end;
262
end;
263
 
263
 
264
procedure TMainForm.Aboutthislevel1Click(Sender: TObject);
264
procedure TMainForm.Aboutthislevel1Click(Sender: TObject);
265
var
265
var
266
  mode: string;
266
  mode: string;
267
  goalYeSNo: string;
267
  goalYeSNo: string;
268
resourcestring
268
resourcestring
269
  LNG_BOARD = 'Board: %s';
269
  LNG_BOARD = 'Board: %s';
270
  LNG_MODE = 'Mode: %s';
270
  LNG_MODE = 'Mode: %s';
271
  LNG_STONES_TOTAL = 'Stones: %d';
271
  LNG_STONES_TOTAL = 'Stones: %d';
272
  LNG_GOAL_AVAILABLE = 'Target field defined';
272
  LNG_GOAL_AVAILABLE = 'Target field defined';
273
  LNG_NO_GOAL = 'No target field';
273
  LNG_NO_GOAL = 'No target field';
274
begin
274
begin
275
  case Level.GameMode of
275
  case Level.GameMode of
276
    gmNormal:    mode := 'Diagonal';
276
    gmNormal:    mode := 'Diagonal';
277
    gmDiagonal:  mode := 'Normal';
277
    gmDiagonal:  mode := 'Normal';
278
    gmUndefined: mode := '?';
278
    gmUndefined: mode := '?';
279
  end;
279
  end;
280
 
280
 
281
  if GoalStatus = gsNoGoal then
281
  if GoalStatus = gsNoGoal then
282
    goalYeSNo := LNG_NO_GOAL
282
    goalYeSNo := LNG_NO_GOAL
283
  else
283
  else
284
    goalYeSNo := LNG_GOAL_AVAILABLE;
284
    goalYeSNo := LNG_GOAL_AVAILABLE;
285
 
285
 
286
  ShowMessage(Format(LNG_BOARD, [ExtractFileNameWithoutExt(LevelFile)]) + #13#10 +
286
  ShowMessage(Format(LNG_BOARD, [ExtractFileNameWithoutExt(LevelFile)]) + #13#10 +
287
              #13#10 +
287
              #13#10 +
288
              Format(LNG_MODE, [mode]) + #13#10 +
288
              Format(LNG_MODE, [mode]) + #13#10 +
289
              Format(LNG_STONES_TOTAL, [LevelTotalStones]) + #13#10 +
289
              Format(LNG_STONES_TOTAL, [LevelTotalStones]) + #13#10 +
290
              goalYesNo);
290
              goalYesNo);
291
end;
291
end;
292
 
292
 
293
procedure TMainForm.DoJump(SourceTag, DestTag: integer);
293
procedure TMainForm.DoJump(SourceTag, DestTag: integer);
294
resourcestring
294
resourcestring
295
  LNG_JUMP_LOG = '[%d, %d] -> [%d, %d];';
295
  LNG_JUMP_LOG = '[%d, %d] -> [%d, %d];';
296
var
296
var
297
  d, s: TCoord;
297
  d, s: TCoord;
298
  old_fieldtype: TFieldType;
298
  old_fieldtype: TFieldType;
299
  res: Integer;
299
  res: Integer;
300
begin
300
begin
301
  if not MayJump(SourceTag, DestTag) then exit;
301
  if not MayJump(SourceTag, DestTag) then exit;
302
 
302
 
303
  s := PlaygroundMatrix.IndexToCoord(SourceTag);
303
  s := PlaygroundMatrix.IndexToCoord(SourceTag);
304
  d := PlaygroundMatrix.IndexToCoord(DestTag);
304
  d := PlaygroundMatrix.IndexToCoord(DestTag);
305
 
305
 
306
  JumpHistory.Add(Format(LNG_JUMP_LOG, [s.x+1, s.y+1, d.x+1, d.y+1]));
306
  JumpHistory.Add(Format(LNG_JUMP_LOG, [s.x+1, s.y+1, d.x+1, d.y+1]));
307
 
307
 
308
  {$REGION 'Stein entfernen und Punkte vergeben'}
308
  {$REGION 'Stein entfernen und Punkte vergeben'}
309
  if Level.GameMode = gmDiagonal then
309
  if Level.GameMode = gmDiagonal then
310
  begin
310
  begin
311
    if (s.X-2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y-1) = fsOccupied) then RemoveStone(s.X-1, s.Y-1, true);
311
    if (s.X-2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y-1) = fsOccupied) then RemoveStone(s.X-1, s.Y-1, true);
312
    if (s.X-2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y+1) = fsOccupied) then RemoveStone(s.X-1, s.Y+1, true);
312
    if (s.X-2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y+1) = fsOccupied) then RemoveStone(s.X-1, s.Y+1, true);
313
    if (s.X+2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y-1) = fsOccupied) then RemoveStone(s.X+1, s.Y-1, true);
313
    if (s.X+2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y-1) = fsOccupied) then RemoveStone(s.X+1, s.Y-1, true);
314
    if (s.X+2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y+1) = fsOccupied) then RemoveStone(s.X+1, s.Y+1, true);
314
    if (s.X+2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y+1) = fsOccupied) then RemoveStone(s.X+1, s.Y+1, true);
315
  end;
315
  end;
316
 
316
 
317
  if (s.X+2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y  ) = fsOccupied) then RemoveStone(s.X+1, s.Y, true);
317
  if (s.X+2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y  ) = fsOccupied) then RemoveStone(s.X+1, s.Y, true);
318
  if (s.X-2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y  ) = fsOccupied) then RemoveStone(s.X-1, s.Y, true);
318
  if (s.X-2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y  ) = fsOccupied) then RemoveStone(s.X-1, s.Y, true);
319
  if (s.X = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X  , s.Y+1) = fsOccupied) then RemoveStone(s.X, s.Y+1, true);
319
  if (s.X = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X  , s.Y+1) = fsOccupied) then RemoveStone(s.X, s.Y+1, true);
320
  if (s.X = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X  , s.Y-1) = fsOccupied) then RemoveStone(s.X, s.Y-1, true);
320
  if (s.X = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X  , s.Y-1) = fsOccupied) then RemoveStone(s.X, s.Y-1, true);
321
  {$ENDREGION}
321
  {$ENDREGION}
322
 
322
 
323
  // Den Timer erst nach dem ersten Zug starten
323
  // Den Timer erst nach dem ersten Zug starten
324
  // oder nach einer Pause neustarten
324
  // oder nach einer Pause neustarten
325
  MPauseTime.Checked := false;
325
  MPauseTime.Checked := false;
326
  MPauseTime.Enabled := true;
326
  MPauseTime.Enabled := true;
327
  Timer.Enabled := true;
327
  Timer.Enabled := true;
328
 
328
 
329
  // Sound abspielen
329
  // Sound abspielen
330
  if MEnableSound.Checked then PlaySound(RES_JUMP, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
330
  if MEnableSound.Checked then PlaySound(RES_JUMP, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
331
 
331
 
332
  {$REGION 'Nun den Stein springen lassen'}
332
  {$REGION 'Nun den Stein springen lassen'}
333
  old_fieldtype := PlayGroundMatrix.Fields[s.X, s.Y].FieldType; // Steinfarbe merken
333
  old_fieldtype := PlayGroundMatrix.Fields[s.X, s.Y].FieldType; // Steinfarbe merken
334
  RemoveStone(s.X, s.Y, false); // Eigenen Stein entfernen. Keine Punkte zählen, da das unser eigener Stein ist, der springt
334
  RemoveStone(s.X, s.Y, false); // Eigenen Stein entfernen. Keine Punkte zählen, da das unser eigener Stein ist, der springt
335
  PlayGroundMatrix.Fields[d.X, d.Y].FieldType := old_fieldtype; // Farbe wiederherstellen
335
  PlayGroundMatrix.Fields[d.X, d.Y].FieldType := old_fieldtype; // Farbe wiederherstellen
336
  LoadPictureForType(PlayGroundMatrix.Fields[d.X, d.Y].FieldType,
336
  LoadPictureForType(PlayGroundMatrix.Fields[d.X, d.Y].FieldType,
337
                     TFieldVclData(PlayGroundMatrix.Fields[d.X, d.Y].Data).Stone.Picture); // Stein an neue Position malen
337
                     TFieldVclData(PlayGroundMatrix.Fields[d.X, d.Y].Data).Stone.Picture); // Stein an neue Position malen
338
  StoneDraggingAllow(TFieldVclData(PlayGroundMatrix.Fields[d.X, d.Y].Data).Stone, true); // Und die Drag-Eigenschaft erneuern
338
  StoneDraggingAllow(TFieldVclData(PlayGroundMatrix.Fields[d.X, d.Y].Data).Stone, true); // Und die Drag-Eigenschaft erneuern
339
  {$ENDREGION}
339
  {$ENDREGION}
340
 
340
 
341
  {$REGION 'Sind weitere Sprünge möglich oder ist das Spiel vorbei?'}
341
  {$REGION 'Sind weitere Sprünge möglich oder ist das Spiel vorbei?'}
342
  if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
342
  if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
343
  begin
343
  begin
344
    MPauseTime.Checked := false;
344
    MPauseTime.Checked := false;
345
    MPauseTime.Enabled := false;
345
    MPauseTime.Enabled := false;
346
    Timer.Enabled := false;
346
    Timer.Enabled := false;
347
    RefreshTime;
347
    RefreshTime;
348
    if MEnableSound.Checked then
348
    if MEnableSound.Checked then
349
    begin
349
    begin
350
      if LevelRemovedStones = LevelTotalStones-1 then
350
      if LevelRemovedStones = LevelTotalStones-1 then
351
      begin
351
      begin
352
        if GoalStatus in [gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen] then
352
        if GoalStatus in [gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen] then
353
          PlaySound(RES_WIN2, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
353
          PlaySound(RES_WIN2, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
354
        else
354
        else
355
          PlaySound(RES_WIN1, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
355
          PlaySound(RES_WIN1, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE)
356
      end
356
      end
357
      else
357
      else
358
        PlaySound(RES_LOSE, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
358
        PlaySound(RES_LOSE, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
359
    end;
359
    end;
360
    res := FinishForm.Execute(ExtractFileNameWithoutExt(LevelFile), Points, LevelTotalStones, LevelRemovedStones, CountedSeconds, GoalStatus, JumpHistory);
360
    res := FinishForm.Execute(ExtractFileNameWithoutExt(LevelFile), Points, LevelTotalStones, LevelRemovedStones, CountedSeconds, GoalStatus, JumpHistory);
361
    if (res = mrOK) and FinishForm.ReplayCheckbox.Checked then RestartLevel;
361
    if (res = mrOK) and FinishForm.ReplayCheckbox.Checked then RestartLevel;
362
  end;
362
  end;
363
  {$ENDREGION}
363
  {$ENDREGION}
364
 
364
 
365
  SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)+1);
365
  SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)+1);
366
  PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1] := PlaygroundMatrix.CloneMatrix;
366
  PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1] := PlaygroundMatrix.CloneMatrix;
367
  MUndo.Enabled := true;
367
  MUndo.Enabled := true;
368
end;
368
end;
369
 
369
 
370
function TMainForm.MayJump(SourceTag, DestTag: integer): boolean;
370
function TMainForm.MayJump(SourceTag, DestTag: integer): boolean;
371
var
371
var
372
  s, d: TCoord;
372
  s, d: TCoord;
373
begin
373
begin
374
  s := PlayGroundMatrix.IndexToCoord(SourceTag);
374
  s := PlayGroundMatrix.IndexToCoord(SourceTag);
375
  d := PlayGroundMatrix.IndexToCoord(DestTag);
375
  d := PlayGroundMatrix.IndexToCoord(DestTag);
376
 
376
 
377
  result := PlaygroundMatrix.CanJump(s, d, Level.GameMode = gmDiagonal);
377
  result := PlaygroundMatrix.CanJump(s, d, Level.GameMode = gmDiagonal);
378
end;
378
end;
379
 
379
 
380
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
380
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
381
begin
381
begin
382
  DoJump(TComponent(Source).Tag, TComponent(Sender).Tag);
382
  DoJump(TComponent(Source).Tag, TComponent(Sender).Tag);
383
end;
383
end;
384
 
384
 
385
procedure TMainForm.StoneDragOver(Sender, Source: TObject; X,
385
procedure TMainForm.StoneDragOver(Sender, Source: TObject; X,
386
  Y: Integer; State: TDragState; var Accept: Boolean);
386
  Y: Integer; State: TDragState; var Accept: Boolean);
387
begin
387
begin
388
  Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag);
388
  Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag);
389
end;
389
end;
390
 
390
 
391
procedure TMainForm.DrawField(x, y: integer; var f: TField);
391
procedure TMainForm.DrawField(x, y: integer; var f: TField);
392
var
392
var
393
  index: integer;
393
  index: integer;
394
begin
394
begin
395
  if f.FieldType = ftFullSpace then exit;
395
  if f.FieldType = ftFullSpace then exit;
396
 
396
 
397
  index := PlaygroundMatrix.CoordToIndex(x, y);
397
  index := PlaygroundMatrix.CoordToIndex(x, y);
398
 
398
 
399
  if not Assigned(f.Data) then f.Data := TFieldVclData.Create;
399
  if not Assigned(f.Data) then f.Data := TFieldVclData.Create;
400
  TFieldVclData(f.Data).Panel := DrawStoneBox(x, y, index, f);
400
  TFieldVclData(f.Data).Panel := DrawStoneBox(x, y, index, f);
401
  TFieldVclData(f.Data).Stone := DrawStone(f);
401
  TFieldVclData(f.Data).Stone := DrawStone(f);
402
end;
402
end;
403
 
403
 
404
procedure TMainForm.TimerTimer(Sender: TObject);
404
procedure TMainForm.TimerTimer(Sender: TObject);
405
begin
405
begin
406
  if MPauseTime.Checked then exit;
406
  if MPauseTime.Checked then exit;
407
  if mainform.Focused then Inc(CountedSeconds);
407
  if mainform.Focused then Inc(CountedSeconds);
408
  RefreshTime;
408
  RefreshTime;
409
end;
409
end;
410
 
410
 
411
function TMainForm.LevelTime: String;
411
function TMainForm.LevelTime: String;
412
begin
412
begin
413
  result := FormatDateTime('hh:nn:ss', CountedSeconds / SecsPerDay)
413
  result := FormatDateTime('hh:nn:ss', CountedSeconds / SecsPerDay)
414
end;
414
end;
415
 
415
 
416
procedure TMainForm.NewGame(Filename: string);
416
procedure TMainForm.NewGame(Filename: string);
417
resourcestring
417
resourcestring
418
  LNG_LVL_INVALID_NO_JUMP = 'Warning! The level is not playable. There are no jumps possible.';
418
  LNG_LVL_INVALID_NO_JUMP = 'Warning! The level is not playable. There are no jumps possible.';
419
var
419
var
420
  y, x: integer;
420
  y, x: integer;
421
  max_x, max_y: integer;
421
  max_x, max_y: integer;
422
  p: TPanel;
422
  p: TPanel;
423
begin
423
begin
424
  DestroyLevel;
424
  DestroyLevel;
425
 
425
 
426
  MPauseTime.Checked := true;
426
  MPauseTime.Checked := true;
427
  MPauseTime.Enabled := true;
427
  MPauseTime.Enabled := true;
428
  Timer.Enabled := true;
428
  Timer.Enabled := true;
429
  MRestartGame.Enabled := true;
429
  MRestartGame.Enabled := true;
430
 
430
 
431
  LevelFile := Filename;
431
  LevelFile := Filename;
432
  Level := TLevel.Create(LevelFile);
432
  Level := TLevel.Create(LevelFile);
433
 
433
 
434
  Level.FillPlaygroundMatrix(PlaygroundMatrix, true);
434
  Level.FillPlaygroundMatrix(PlaygroundMatrix, true);
435
  if Length(PlaygroundMatrix.Fields) = 0 then Exit;
435
  if Length(PlaygroundMatrix.Fields) = 0 then Exit;
436
 
436
 
437
  PlayGround.Visible := false;
437
  PlayGround.Visible := false;
438
 
438
 
439
  max_x := 0;
439
  max_x := 0;
440
  max_y := 0;
440
  max_y := 0;
441
  for x := Low(PlaygroundMatrix.Fields) to High(PlaygroundMatrix.Fields) do
441
  for x := Low(PlaygroundMatrix.Fields) to High(PlaygroundMatrix.Fields) do
442
  begin
442
  begin
443
    for y := Low(PlaygroundMatrix.Fields[x]) to High(PlaygroundMatrix.Fields[x]) do
443
    for y := Low(PlaygroundMatrix.Fields[x]) to High(PlaygroundMatrix.Fields[x]) do
444
    begin
444
    begin
445
      if PlaygroundMatrix.Fields[x,y].FieldState = fsOccupied then
445
      if PlaygroundMatrix.Fields[x,y].FieldState = fsOccupied then
446
        Inc(LevelTotalStones);
446
        Inc(LevelTotalStones);
447
      DrawField(x, y, PlaygroundMatrix.Fields[x,y]);
447
      DrawField(x, y, PlaygroundMatrix.Fields[x,y]);
-
 
448
      if Assigned(PlaygroundMatrix.Fields[x,y].Data) then
-
 
449
      begin
448
      p := TFieldVclData(PlaygroundMatrix.Fields[x,y].Data).Panel;
450
        p := TFieldVclData(PlaygroundMatrix.Fields[x,y].Data).Panel;
449
      if Assigned(p) then
451
        if Assigned(p) then
450
      begin
452
        begin
451
        max_x := Max(max_x, p.Left + p.Width);
453
          max_x := Max(max_x, p.Left + p.Width);
452
        max_y := Max(max_y, p.Top  + p.Height);
454
          max_y := Max(max_y, p.Top  + p.Height);
453
      end;
455
        end;
-
 
456
      end;
454
    end;
457
    end;
455
  end;
458
  end;
456
 
459
 
457
  PlayGround.Visible := true;
460
  PlayGround.Visible := true;
458
 
461
 
459
  // Das Form an das Level anpassen
462
  // Das Form an das Level anpassen
460
  PlayGround.Top    := MET_OUTER_MARGIN;
463
  PlayGround.Top    := MET_OUTER_MARGIN;
461
  PlayGround.Left   := MET_OUTER_MARGIN;
464
  PlayGround.Left   := MET_OUTER_MARGIN;
462
  PlayGround.Width  := max_x;
465
  PlayGround.Width  := max_x;
463
  PlayGround.Height := max_y;
466
  PlayGround.Height := max_y;
464
  ClientWidth       := 2 * MET_OUTER_MARGIN + PlayGround.Width;
467
  ClientWidth       := 2 * MET_OUTER_MARGIN + PlayGround.Width;
465
  ClientHeight      := 2 * MET_OUTER_MARGIN + PlayGround.Height + Statistics.Height;
468
  ClientHeight      := 2 * MET_OUTER_MARGIN + PlayGround.Height + Statistics.Height;
466
 
469
 
467
  // If the board is too small, ClientWidth/ClientHeight will stop at a minimum value
470
  // If the board is too small, ClientWidth/ClientHeight will stop at a minimum value
468
  // in this case, we make sure that the Playground is centered
471
  // in this case, we make sure that the Playground is centered
469
  PlayGround.Left := ClientWidth div 2 - Playground.Width div 2;
472
  PlayGround.Left := ClientWidth div 2 - Playground.Width div 2;
470
  PlayGround.Top := (ClientHeight - Statistics.Height) div 2 - Playground.Height div 2;
473
  PlayGround.Top := (ClientHeight - Statistics.Height) div 2 - Playground.Height div 2;
471
 
474
 
472
  Statistics.Panels.Items[0].Width := Round(ClientWidth * MET_PERCENT_PNL_TIME);
475
  Statistics.Panels.Items[0].Width := Round(ClientWidth * MET_PERCENT_PNL_TIME);
473
  Statistics.Panels.Items[1].Width := Round(ClientWidth * MET_PERCENT_PNL_STONES);
476
  Statistics.Panels.Items[1].Width := Round(ClientWidth * MET_PERCENT_PNL_STONES);
474
 
477
 
475
  SetLength(PrevPlaygroundMatrixes,1);
478
  SetLength(PrevPlaygroundMatrixes,1);
476
  PrevPlaygroundMatrixes[0] := PlayGroundMatrix.CloneMatrix;
479
  PrevPlaygroundMatrixes[0] := PlayGroundMatrix.CloneMatrix;
477
  MUndo.Enabled := false;
480
  MUndo.Enabled := false;
478
 
481
 
479
  if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
482
  if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
480
  begin
483
  begin
481
    MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0);
484
    MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0);
482
  end;
485
  end;
483
  RefreshTime;
486
  RefreshTime;
484
  RefreshStonesRemoved;
487
  RefreshStonesRemoved;
485
  RefreshPoints;
488
  RefreshPoints;
486
end;
489
end;
487
 
490
 
488
procedure TMainForm.MNewGameClick(Sender: TObject);
491
procedure TMainForm.MNewGameClick(Sender: TObject);
489
begin
492
begin
490
  LevelFile := AskForLevel;
493
  LevelFile := AskForLevel;
491
  if LevelFile <> '' then
494
  if LevelFile <> '' then
492
  begin
495
  begin
493
    NewGame(LevelFile);
496
    NewGame(LevelFile);
494
  end;
497
  end;
495
end;
498
end;
496
 
499
 
497
procedure TMainForm.MAboutClick(Sender: TObject);
500
procedure TMainForm.MAboutClick(Sender: TObject);
498
begin
501
begin
499
  AboutBox.ShowModal;
502
  AboutBox.ShowModal;
500
end;
503
end;
501
 
504
 
502
function TMainForm.AskForLevel: String;
505
function TMainForm.AskForLevel: String;
503
begin
506
begin
504
  LevelChoice.ShowModal;
507
  LevelChoice.ShowModal;
505
 
508
 
506
  if LevelChoice.ModalResult <> mrOK then
509
  if LevelChoice.ModalResult <> mrOK then
507
  begin
510
  begin
508
    result := '';
511
    result := '';
509
    exit;
512
    exit;
510
  end;
513
  end;
511
 
514
 
512
  result := LevelChoice.SelectedLevel;
515
  result := LevelChoice.SelectedLevel;
513
end;
516
end;
514
 
517
 
515
procedure TMainForm.FormShow(Sender: TObject);
518
procedure TMainForm.FormShow(Sender: TObject);
516
begin
519
begin
517
  LevelFile := AskForLevel;
520
  LevelFile := AskForLevel;
518
  if LevelFile <> '' then
521
  if LevelFile <> '' then
519
  begin
522
  begin
520
    NewGame(LevelFile);
523
    NewGame(LevelFile);
521
  end
524
  end
522
  else
525
  else
523
  begin
526
  begin
524
    NoCloseQuery := true;
527
    NoCloseQuery := true;
525
    Close;
528
    Close;
526
  end;
529
  end;
527
end;
530
end;
528
 
531
 
529
function TMainForm.GoalStatus: TGoalStatus;
532
function TMainForm.GoalStatus: TGoalStatus;
530
begin
533
begin
531
  result := PlaygroundMatrix.GoalStatus(LevelTotalStones - LevelRemovedStones);
534
  result := PlaygroundMatrix.GoalStatus(LevelTotalStones - LevelRemovedStones);
532
end;
535
end;
533
 
536
 
534
procedure TMainForm.FormCreate(Sender: TObject);
537
procedure TMainForm.FormCreate(Sender: TObject);
535
begin
538
begin
536
  JumpHistory := TStringList.Create;
539
  JumpHistory := TStringList.Create;
537
  LoadSettings;
540
  LoadSettings;
538
end;
541
end;
539
 
542
 
540
procedure TMainForm.FormDestroy(Sender: TObject);
543
procedure TMainForm.FormDestroy(Sender: TObject);
541
begin
544
begin
542
  DestroyLevel;
545
  DestroyLevel;
543
  JumpHistory.Free;
546
  JumpHistory.Free;
544
end;
547
end;
545
 
548
 
546
procedure TMainForm.MJumpHistoryClick(Sender: TObject);
549
procedure TMainForm.MJumpHistoryClick(Sender: TObject);
547
begin
550
begin
548
  HistoryForm.JumpMemo.Lines.Assign(JumpHistory);
551
  HistoryForm.JumpMemo.Lines.Assign(JumpHistory);
549
  HistoryForm.ShowModal;
552
  HistoryForm.ShowModal;
550
end;
553
end;
551
 
554
 
552
procedure TMainForm.RestartLevel;
555
procedure TMainForm.RestartLevel;
553
var
556
var
554
  i: Integer;
557
  i: Integer;
555
begin
558
begin
556
  MPauseTime.Checked := true;
559
  MPauseTime.Checked := true;
557
  MPauseTime.Enabled := true;
560
  MPauseTime.Enabled := true;
558
  Timer.Enabled := true;
561
  Timer.Enabled := true;
559
 
562
 
560
  CountedSeconds := 0;
563
  CountedSeconds := 0;
561
  RefreshTime;
564
  RefreshTime;
562
 
565
 
563
  Points := 0;
566
  Points := 0;
564
  RefreshPoints;
567
  RefreshPoints;
565
 
568
 
566
  LevelRemovedStones := 0;
569
  LevelRemovedStones := 0;
567
  RefreshStonesRemoved;
570
  RefreshStonesRemoved;
568
 
571
 
569
  JumpHistory.Clear;
572
  JumpHistory.Clear;
570
 
573
 
571
  RedrawStonesFromMatrix(PrevPlaygroundMatrixes[0]);
574
  RedrawStonesFromMatrix(PrevPlaygroundMatrixes[0]);
572
  SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[0]);
575
  SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[0]);
573
  for i := 1 to Length(PrevPlaygroundMatrixes)-1 do
576
  for i := 1 to Length(PrevPlaygroundMatrixes)-1 do
574
    PrevPlaygroundMatrixes[i].ClearMatrix(false);
577
    PrevPlaygroundMatrixes[i].ClearMatrix(false);
575
  SetLength(PrevPlaygroundMatrixes, 1);
578
  SetLength(PrevPlaygroundMatrixes, 1);
576
 
579
 
577
  MUndo.Enabled := false;
580
  MUndo.Enabled := false;
578
end;
581
end;
579
 
582
 
580
procedure TMainForm.SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
583
procedure TMainForm.SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
581
begin
584
begin
582
  PlayGroundMatrix.ClearMatrix(false); // Memory Leak verhindern
585
  PlayGroundMatrix.ClearMatrix(false); // Memory Leak verhindern
583
  PlayGroundMatrix := Matrix.CloneMatrix;
586
  PlayGroundMatrix := Matrix.CloneMatrix;
584
end;
587
end;
585
 
588
 
586
procedure TMainForm.MRestartGameClick(Sender: TObject);
589
procedure TMainForm.MRestartGameClick(Sender: TObject);
587
begin
590
begin
588
  RestartLevel;
591
  RestartLevel;
589
end;
592
end;
590
 
593
 
591
procedure TMainForm.MUndoClick(Sender: TObject);
594
procedure TMainForm.MUndoClick(Sender: TObject);
592
var
595
var
593
  PrevWorth: integer;
596
  PrevWorth: integer;
594
  NewWorth: integer;
597
  NewWorth: integer;
595
begin
598
begin
596
  if Length(PrevPlaygroundMatrixes) > 1 then
599
  if Length(PrevPlaygroundMatrixes) > 1 then
597
  begin
600
  begin
598
    PrevWorth := PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].MatrixWorth;
601
    PrevWorth := PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].MatrixWorth;
599
 
602
 
600
    PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].ClearMatrix(false);
603
    PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].ClearMatrix(false);
601
    SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)-1);
604
    SetLength(PrevPlaygroundMatrixes, Length(PrevPlaygroundMatrixes)-1);
602
 
605
 
603
    NewWorth := PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].MatrixWorth;
606
    NewWorth := PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1].MatrixWorth;
604
    RedrawStonesFromMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
607
    RedrawStonesFromMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
605
    SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
608
    SetNewPlayGroundMatrix(PrevPlaygroundMatrixes[Length(PrevPlaygroundMatrixes)-1]);
606
 
609
 
607
    JumpHistory.Delete(JumpHistory.Count-1);
610
    JumpHistory.Delete(JumpHistory.Count-1);
608
 
611
 
609
    Dec(LevelRemovedStones);
612
    Dec(LevelRemovedStones);
610
    RefreshStonesRemoved;
613
    RefreshStonesRemoved;
611
 
614
 
612
    Dec(Points, NewWorth-PrevWorth);
615
    Dec(Points, NewWorth-PrevWorth);
613
    RefreshPoints;
616
    RefreshPoints;
614
 
617
 
615
    // Sound abspielen
618
    // Sound abspielen
616
    if MEnableSound.Checked then PlaySound(RES_UNDO, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
619
    if MEnableSound.Checked then PlaySound(RES_UNDO, HInstance, SND_ASYNC or SND_NOWAIT or SND_RESOURCE);
617
  end;
620
  end;
618
 
621
 
619
  MUndo.Enabled := Length(PrevPlaygroundMatrixes) > 1;
622
  MUndo.Enabled := Length(PrevPlaygroundMatrixes) > 1;
620
end;
623
end;
621
 
624
 
622
procedure TMainForm.MHighScoresClick(Sender: TObject);
625
procedure TMainForm.MHighScoresClick(Sender: TObject);
623
begin
626
begin
624
  HighScoreForm.Execute(ExtractFileNameWithoutExt(LevelFile));
627
  HighScoreForm.Execute(ExtractFileNameWithoutExt(LevelFile));
625
end;
628
end;
626
 
629
 
627
procedure TMainForm.LoadSettings;
630
procedure TMainForm.LoadSettings;
628
var
631
var
629
  reg: TRegistry;
632
  reg: TRegistry;
630
begin
633
begin
631
  reg := TRegistry.Create;
634
  reg := TRegistry.Create;
632
  try
635
  try
633
    reg.RootKey := HKEY_CURRENT_USER;
636
    reg.RootKey := HKEY_CURRENT_USER;
634
    if reg.OpenKeyReadOnly(REG_KEY) then
637
    if reg.OpenKeyReadOnly(REG_KEY) then
635
    begin
638
    begin
636
      if reg.ValueExists(REG_SOUND) then
639
      if reg.ValueExists(REG_SOUND) then
637
        MEnableSound.Checked := reg.ReadBool(REG_SOUND);
640
        MEnableSound.Checked := reg.ReadBool(REG_SOUND);
638
      reg.CloseKey;
641
      reg.CloseKey;
639
    end;
642
    end;
640
  finally
643
  finally
641
    reg.Free;
644
    reg.Free;
642
  end;
645
  end;
643
end;
646
end;
644
 
647
 
645
procedure TMainForm.SaveSettings;
648
procedure TMainForm.SaveSettings;
646
var
649
var
647
  reg: TRegistry;
650
  reg: TRegistry;
648
begin
651
begin
649
  reg := TRegistry.Create;
652
  reg := TRegistry.Create;
650
  try
653
  try
651
    reg.RootKey := HKEY_CURRENT_USER;
654
    reg.RootKey := HKEY_CURRENT_USER;
652
    if reg.OpenKey(REG_KEY, true) then
655
    if reg.OpenKey(REG_KEY, true) then
653
    begin
656
    begin
654
      reg.WriteBool(REG_SOUND, MEnableSound.Checked);
657
      reg.WriteBool(REG_SOUND, MEnableSound.Checked);
655
      reg.CloseKey;
658
      reg.CloseKey;
656
    end;
659
    end;
657
  finally
660
  finally
658
    reg.Free;
661
    reg.Free;
659
  end;
662
  end;
660
end;
663
end;
661
 
664
 
662
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
665
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
663
begin
666
begin
664
  SaveSettings;
667
  SaveSettings;
665
  if FinishForm.NameEdit.Text <> '' then
668
  if FinishForm.NameEdit.Text <> '' then
666
  begin
669
  begin
667
    FinishForm.SaveSettings;
670
    FinishForm.SaveSettings;
668
  end;
671
  end;
669
end;
672
end;
670
 
673
 
671
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
674
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
672
resourcestring
675
resourcestring
673
  LNG_REALLY_QUIT = 'Do you really want to quit?';
676
  LNG_REALLY_QUIT = 'Do you really want to quit?';
674
begin
677
begin
675
  CanClose := NoCloseQuery or (MessageDlg(LNG_REALLY_QUIT, mtConfirmation, mbYesNoCancel, 0) = mrYes);
678
  CanClose := NoCloseQuery or (MessageDlg(LNG_REALLY_QUIT, mtConfirmation, mbYesNoCancel, 0) = mrYes);
676
end;
679
end;
677
 
680
 
678
procedure TMainForm.MHelpClick(Sender: TObject);
681
procedure TMainForm.MHelpClick(Sender: TObject);
679
begin
682
begin
680
  HelpForm.ShowModal;
683
  HelpForm.ShowModal;
681
end;
684
end;
682
 
685
 
683
{ TFieldVclData }
686
{ TFieldVclData }
684
 
687
 
685
destructor TFieldVclData.Destroy;
688
destructor TFieldVclData.Destroy;
686
begin
689
begin
687
  if Assigned(Stone) then Stone.Free;
690
  if Assigned(Stone) then Stone.Free;
688
  if Assigned(Panel) then Panel.Free;
691
  if Assigned(Panel) then Panel.Free;
689
  inherited;
692
  inherited;
690
end;
693
end;
691
 
694
 
692
end.
695
end.
693
 
696