Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations) (download) (as text)
Mon Jul 13 00:01:54 2015 UTC (8 years, 7 months ago) by yamat0jp
File MIME type: text/x-pascal
File size: 12446 byte(s)
アニメーションをつけました
1 unit Unit1;
2
3 interface
4
5 uses
6 System.SysUtils, System.Types, System.UITypes, System.Classes,
7 System.Variants,
8 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Menus,
9 System.Math, FMX.Objects, FMX.StdCtrls;
10
11 const
12 Count = 8;
13
14 type
15 TStoneType = (stNone, stWhite, stBlack, stError);
16
17 TGridData = array [0 .. Count - 1] of array [0 .. Count - 1] of TStoneType;
18
19 TPlayer = class
20 private
21 FAuto: Boolean;
22 FStone: TStoneType;
23 public
24 property Auto: Boolean read FAuto write FAuto;
25 property Stone: TStoneType read FStone write FStone;
26 end;
27
28 TStoneGrid = class
29 private
30 FStrings: TGridData;
31 FBuffer: array [0 .. Count * Count - 4] of TGridData;
32 FTurnNumber: integer;
33 FTurnIndex: integer;
34 function GetStrings(X, Y: integer): TStoneType;
35 procedure SetStrings(X, Y: integer; const Value: TStoneType);
36 procedure SetTurnNumber(const Value: integer);
37 public
38 procedure Clear;
39 procedure BackUp;
40 function CalScore(Player: TPlayer; X, Y: integer): integer;
41 function CanSetStone(Player: TPlayer; X, Y: integer; Reverse: Boolean;
42 const Visible: Boolean = false): Boolean;
43 function NextStone(Player: TPlayer): TPoint;
44 property Strings[X, Y: integer]: TStoneType read GetStrings
45 write SetStrings; default;
46 property TurnNumber: integer read FTurnNumber write SetTurnNumber;
47 property TurnIndex: integer read FTurnIndex write FTurnIndex;
48 end;
49
50 TForm1 = class(TForm)
51 Timer1: TTimer;
52 MainMenu1: TMainMenu;
53 MenuItem1: TMenuItem;
54 MenuItem2: TMenuItem;
55 MenuItem3: TMenuItem;
56 MenuItem4: TMenuItem;
57 MenuItem5: TMenuItem;
58 MenuItem6: TMenuItem;
59 MenuItem7: TMenuItem;
60 PaintBox1: TPaintBox;
61 MenuItem8: TMenuItem;
62 MenuItem9: TMenuItem;
63 MenuItem10: TMenuItem;
64 MenuItem11: TMenuItem;
65 MenuItem12: TMenuItem;
66 procedure FormCreate(Sender: TObject);
67 procedure FormDestroy(Sender: TObject);
68 procedure Timer1Timer(Sender: TObject);
69 procedure FormResize(Sender: TObject);
70 procedure MenuItem4Click(Sender: TObject);
71 procedure MenuItem2Click(Sender: TObject);
72 procedure PaintBox1Tap(Sender: TObject; const Point: TPointF);
73 procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
74 Shift: TShiftState; X, Y: Single);
75 procedure PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
76 procedure MenuItem6Click(Sender: TObject);
77 procedure PaintBox1Resize(Sender: TObject);
78 procedure MenuItem8Click(Sender: TObject);
79 procedure MenuItem10Click(Sender: TObject);
80 procedure MenuItem11Click(Sender: TObject);
81 private
82 { Private ���� }
83 StoneGrid: TStoneGrid;
84 Index: TPlayer;
85 Active: Boolean;
86 Size: integer;
87 procedure CompStone;
88 procedure GameStart;
89 procedure ChangePlayer;
90 public
91 { Public ���� }
92 end;
93
94 var
95 Player1: TPlayer;
96 Player2: TPlayer;
97
98 Form1: TForm1;
99
100 implementation
101
102 {$R *.fmx}
103 {$R *.Windows.fmx MSWINDOWS}
104
105 { TStoneGrid }
106
107 procedure TStoneGrid.BackUp;
108 begin
109 FBuffer[FTurnNumber] := FStrings;
110 if FTurnNumber < Count * Count - 4 then
111 begin
112 FTurnIndex := FTurnNumber + 1;
113 inc(FTurnNumber);
114 FBuffer[FTurnNumber] := FStrings;
115 end;
116 end;
117
118 function TStoneGrid.CalScore(Player: TPlayer; X, Y: integer): integer;
119 var
120 i, j: integer;
121 begin
122 if CanSetStone(Player, X, Y, true) = true then
123 begin
124 if Player = Player1 then
125 Player := Player2
126 else
127 Player := Player1;
128 result := 0;
129 for i := 0 to Count - 1 do
130 for j := 0 to Count - 1 do
131 if CanSetStone(Player, i, j, false) = true then
132 inc(result);
133 FStrings := FBuffer[FTurnNumber];
134 end
135 else
136 begin
137 FStrings := FBuffer[FTurnNumber];
138 result := -1;
139 end;
140 end;
141
142 function TStoneGrid.CanSetStone(Player: TPlayer; X, Y: integer;
143 Reverse: Boolean; const Visible: Boolean): Boolean;
144 var
145 i, k: integer;
146 p: Boolean;
147 q: ^TPoint;
148 list: TList;
149 procedure Method(m, n: integer);
150 var
151 s: TStoneType;
152 j: integer;
153 begin
154 if p = false then
155 Exit;
156 i := 1;
157 while true do
158 begin
159 s := GetStrings(X + m * i, Y + n * i);
160 if (s = stNone) or (s = stError) then
161 break
162 else if s = Player.Stone then
163 if i > 1 then
164 begin
165 result := true;
166 if Reverse = true then
167 begin
168 for j := 1 to i - 1 do
169 begin
170 New(q);
171 q^ := Point(X + m * j, Y + n * j);
172 list.Add(q);
173 end;
174 break;
175 end
176 else
177 begin
178 p := false;
179 break;
180 end;
181 end
182 else
183 break
184 else
185 inc(i);
186 end;
187 end;
188
189 begin
190 list := TList.Create;
191 try
192 result := false;
193 p := true;
194 if GetStrings(X, Y) = stNone then
195 begin
196 Method(-1, -1);
197 Method(-1, 0);
198 Method(-1, 1);
199 Method(0, -1);
200 Method(0, 1);
201 Method(1, -1);
202 Method(1, 0);
203 Method(1, 1);
204 end;
205 if (Reverse = true) and (result = true) then
206 begin
207 SetStrings(X, Y, Player.Stone);
208 for i := 0 to list.Count - 1 do
209 begin
210 if Visible = true then
211 begin
212 for k := 1 to 10 do
213 begin
214 Sleep(10);
215 Application.ProcessMessages;
216 end;
217 Form1.PaintBox1.Repaint;
218 end;
219 q := list[i];
220 SetStrings(q^.X, q^.Y, Player.Stone);
221 end;
222 end;
223 finally
224 for i := 0 to list.Count - 1 do
225 Dispose(list[i]);
226 list.Free;
227 end;
228 end;
229
230 procedure TStoneGrid.Clear;
231 var
232 i, j: integer;
233 begin
234 for i := 0 to Count - 1 do
235 for j := 0 to Count - 1 do
236 Strings[i, j] := stNone;
237 Strings[3, 3] := stBlack;
238 Strings[4, 4] := stBlack;
239 Strings[4, 3] := stWhite;
240 Strings[3, 4] := stWhite;
241 FTurnNumber := 0;
242 FTurnIndex := 0;
243 end;
244
245 function TStoneGrid.GetStrings(X, Y: integer): TStoneType;
246 begin
247 if (X >= 0) and (X < Count) and (Y >= 0) and (Y < Count) then
248 result := FStrings[X, Y]
249 else
250 result := stError;
251 end;
252
253 function TStoneGrid.NextStone(Player: TPlayer): TPoint;
254 var
255 i, j, m, n: integer;
256 begin
257 n := -1;
258 for i := 0 to Count - 1 do
259 for j := 0 to Count - 1 do
260 begin
261 m := CalScore(Player, i, j);
262 if (n = -1) or ((m > -1) and (n > m)) then
263 begin
264 n := m;
265 result := Point(i, j);
266 end;
267 end;
268 if n = -1 then
269 result := Point(-1, -1);
270 end;
271
272 procedure TStoneGrid.SetStrings(X, Y: integer; const Value: TStoneType);
273 begin
274 if (X >= 0) and (X < Count) and (Y >= 0) and (Y < Count) then
275 FStrings[X, Y] := Value;
276 end;
277
278 procedure TStoneGrid.SetTurnNumber(const Value: integer);
279 begin
280 if Value > FTurnIndex then
281 FTurnNumber := FTurnIndex
282 else
283 FTurnNumber := Value;
284 FStrings := FBuffer[FTurnNumber];
285 end;
286
287 { TForm1 }
288
289 procedure TForm1.ChangePlayer;
290 var
291 i, j, m, n: integer;
292 s: string;
293 procedure Main;
294 begin
295 if Index = Player1 then
296 Index := Player2
297 else
298 Index := Player1;
299 end;
300 function Execute: Boolean;
301 var
302 i, j: integer;
303 begin
304 result := false;
305 for i := 0 to Count - 1 do
306 begin
307 for j := 0 to Count - 1 do
308 if StoneGrid.CanSetStone(Index, i, j, false) = true then
309 begin
310 result := true;
311 break;
312 end;
313 if result = true then
314 break;
315 end;
316 end;
317
318 begin
319 StoneGrid.BackUp;
320 Main;
321 if Execute = false then
322 begin
323 Main;
324 if Execute = false then
325 begin
326 with StoneGrid do
327 if TurnIndex < Count * Count - 4 then
328 begin
329 TurnIndex := TurnIndex - 1;
330 TurnNumber := TurnNumber - 1;
331 end;
332 Timer1.Enabled := false;
333 Active := false;
334 m := 0;
335 n := 0;
336 for i := 0 to Count - 1 do
337 for j := 0 to Count - 1 do
338 case StoneGrid[i, j] of
339 stBlack:
340 inc(m);
341 stWhite:
342 inc(n);
343 end;
344 if m > n then
345 s := 'Player1 Win:' + #13#10
346 else if m < n then
347 s := 'Player2 Win:' + #13#10
348 else
349 s := 'Draw:' + #13#10;
350 Showmessage(s + '(Player1) ' + IntToStr(m) + #13#10 + '(Player2) ' +
351 IntToStr(n));
352 end;
353 end;
354 end;
355
356 procedure TForm1.CompStone;
357 var
358 s: TPoint;
359 begin
360 s := StoneGrid.NextStone(Index);
361 StoneGrid.CanSetStone(Index, s.X, s.Y, true, true);
362 PaintBox1.Repaint;
363 ChangePlayer;
364 end;
365
366 procedure TForm1.GameStart;
367 begin
368 StoneGrid.Clear;
369 StoneGrid.BackUp;
370 PaintBox1.Repaint;
371 Index := Player1;
372 Active := true;
373 Timer1.Enabled := true;
374 end;
375
376 procedure TForm1.MenuItem10Click(Sender: TObject);
377 begin
378 with StoneGrid do
379 begin
380 if TurnIndex > TurnNumber then
381 TurnIndex := TurnNumber;
382 end;
383 Active := true;
384 Timer1.Enabled := true;
385 end;
386
387 procedure TForm1.MenuItem11Click(Sender: TObject);
388 begin
389 if Timer1.Enabled = true then
390 Timer1.Enabled := false;
391 with StoneGrid do
392 if Sender = MenuItem11 then
393 TurnNumber := TurnNumber + 1
394 else
395 TurnNumber := TurnNumber - 1;
396 PaintBox1.Repaint;
397 end;
398
399 procedure TForm1.MenuItem2Click(Sender: TObject);
400 begin
401 GameStart;
402 end;
403
404 procedure TForm1.MenuItem4Click(Sender: TObject);
405 begin
406 Close;
407 end;
408
409 procedure TForm1.MenuItem6Click(Sender: TObject);
410 begin
411 Player1.Auto := MenuItem6.IsChecked;
412 Player2.Auto := MenuItem7.IsChecked;
413 end;
414
415 procedure TForm1.MenuItem8Click(Sender: TObject);
416 begin
417 if (Player1.Auto = true) and (Player2.Auto = true) then
418 Timer1.Enabled := false;
419 end;
420
421 procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
422 var
423 i, j: integer;
424 begin
425 Canvas.Fill.Color := TAlphaColors.White;
426 Canvas.FillRect(RectF(0, 0, Count * Size, Count * Size), 0, 0, [], 1);
427 for i := 0 to Count do
428 begin
429 Canvas.DrawLine(PointF(i * Size, 0), PointF(i * Size, Size * Count), 1);
430 for j := 0 to Count do
431 begin
432 Canvas.DrawLine(PointF(0, j * Size), PointF(Count * Size, j * Size), 1);
433 case StoneGrid.Strings[i, j] of
434 stWhite:
435 Canvas.DrawEllipse(RectF(i * Size, j * Size, (i + 1) * Size,
436 (j + 1) * Size), 1);
437 stBlack:
438 begin
439 Canvas.Fill.Color := TAlphaColors.Black;
440 Canvas.FillEllipse(RectF(i * Size, j * Size, (i + 1) * Size,
441 (j + 1) * Size), 1);
442 end;
443 end;
444 end;
445 end;
446 end;
447
448 procedure TForm1.PaintBox1Resize(Sender: TObject);
449 begin
450 Size := Min(ClientWidth, ClientHeight) div Count;
451 end;
452
453 procedure TForm1.FormCreate(Sender: TObject);
454 begin
455 StoneGrid := TStoneGrid.Create;
456 Player1 := TPlayer.Create;
457 Player2 := TPlayer.Create;
458 Player1.Stone := stBlack;
459 Player2.Stone := stWhite;
460 Player2.Auto := true;
461 with PaintBox1.Canvas do
462 begin
463 StrokeDash := TStrokeDash.Solid;
464 Stroke.Color := TAlphaColors.Black;
465 StrokeThickness := 3;
466 end;
467 PaintBox1Resize(Sender);
468 GameStart;
469 end;
470
471 procedure TForm1.FormDestroy(Sender: TObject);
472 begin
473 StoneGrid.Free;
474 Player1.Free;
475 Player2.Free;
476 end;
477
478 procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
479 Shift: TShiftState; X, Y: Single);
480 begin
481 PaintBox1Tap(Sender, PointF(X, Y));
482 end;
483
484 procedure TForm1.Timer1Timer(Sender: TObject);
485 begin
486 if (Active = true) and (Index.Auto = true) then
487 begin
488 Timer1.Enabled := false;
489 CompStone;
490 Timer1.Enabled := true;
491 end;
492 end;
493
494 procedure TForm1.FormResize(Sender: TObject);
495 begin
496 Size := Min(ClientWidth, ClientHeight) div Count;
497 PaintTo(Canvas);
498 end;
499
500 procedure TForm1.PaintBox1Tap(Sender: TObject; const Point: TPointF);
501 begin
502 if Timer1.Enabled = false then
503 Timer1.Enabled := true;
504 if (Active = false) and (StoneGrid.TurnIndex < Count * Count - 4) then
505 Active := true;
506 if (Active = true) and (Index.Auto = false) then
507 begin
508 if StoneGrid.CanSetStone(Index, Floor(Point.X / Size),
509 Floor(Point.Y / Size), true, true) = true then
510 begin
511 PaintBox1.Repaint;
512 ChangePlayer;
513 end;
514 end;
515 end;
516
517 end.

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26