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 |