Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (show annotations) (download) (as text)
Sat Jul 18 09:15:06 2015 UTC (8 years, 8 months ago) by yamat0jp
File MIME type: text/x-pascal
File size: 15366 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, stEffect);
16
17 TEffectData = record
18 X, Y: integer;
19 Left, Top: integer;
20 Stone: TStoneType;
21 end;
22
23 TGridData = array [0 .. Count - 1] of array [0 .. Count - 1] of TStoneType;
24
25 TPlayer = class
26 private
27 FAuto: Boolean;
28 FStone: TStoneType;
29 public
30 property Auto: Boolean read FAuto write FAuto;
31 property Stone: TStoneType read FStone write FStone;
32 end;
33
34 TStoneGrid = class
35 private
36 FStrings: TGridData;
37 FBuffer: array [0 .. Count * Count - 4] of TGridData;
38 FTurnNumber: integer;
39 FTurnIndex: integer;
40 FActive: Boolean;
41 List: TList;
42 FBool: Boolean;
43 FIndex_X: integer;
44 FIndex_Y: integer;
45 function GetStrings(X, Y: integer): TStoneType;
46 procedure SetStrings(X, Y: integer; const Value: TStoneType);
47 procedure SetTurnNumber(const Value: integer);
48 public
49 constructor Create;
50 destructor Destroy; override;
51 procedure Clear;
52 function CalScore(Stone: TStoneType; X, Y: integer): integer;
53 function CanSetStone(Stone: TStoneType; X, Y: integer; Reverse: Boolean;
54 const Visible: Boolean = false): Boolean;
55 function NextStone(Stone: TStoneType): TPoint;
56 procedure Start;
57 procedure Restart;
58 procedure Pause;
59 function ListExecute: Boolean;
60 procedure Paint(Canvas: TCanvas);
61 procedure ImageCount(X, Y: integer);
62 property Strings[X, Y: integer]: TStoneType read GetStrings
63 write SetStrings; default;
64 property TurnNumber: integer read FTurnNumber write SetTurnNumber;
65 property Active: Boolean read FActive;
66 end;
67
68 TForm1 = class(TForm)
69 Timer1: TTimer;
70 MainMenu1: TMainMenu;
71 MenuItem1: TMenuItem;
72 MenuItem2: TMenuItem;
73 MenuItem3: TMenuItem;
74 MenuItem4: TMenuItem;
75 MenuItem5: TMenuItem;
76 MenuItem6: TMenuItem;
77 MenuItem7: TMenuItem;
78 PaintBox1: TPaintBox;
79 MenuItem8: TMenuItem;
80 MenuItem9: TMenuItem;
81 MenuItem10: TMenuItem;
82 MenuItem11: TMenuItem;
83 MenuItem12: TMenuItem;
84 Timer2: TTimer;
85 Image1: TImage;
86 Image2: TImage;
87 Image3: TImage;
88 Image4: TImage;
89 Image5: TImage;
90 procedure FormCreate(Sender: TObject);
91 procedure FormDestroy(Sender: TObject);
92 procedure Timer1Timer(Sender: TObject);
93 procedure FormResize(Sender: TObject);
94 procedure MenuItem4Click(Sender: TObject);
95 procedure MenuItem2Click(Sender: TObject);
96 procedure PaintBox1Tap(Sender: TObject; const Point: TPointF);
97 procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
98 Shift: TShiftState; X, Y: Single);
99 procedure PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
100 procedure MenuItem6Click(Sender: TObject);
101 procedure PaintBox1Resize(Sender: TObject);
102 procedure MenuItem8Click(Sender: TObject);
103 procedure MenuItem10Click(Sender: TObject);
104 procedure MenuItem11Click(Sender: TObject);
105 procedure Timer2Timer(Sender: TObject);
106 private
107 { Private ���� }
108 StoneGrid: TStoneGrid;
109 Index: TPlayer;
110 Size: integer;
111 procedure CompStone;
112 procedure GameStart;
113 procedure ChangePlayer;
114 public
115 { Public ���� }
116 end;
117
118 var
119 Player1: TPlayer;
120 Player2: TPlayer;
121
122 Form1: TForm1;
123
124 implementation
125
126 {$R *.fmx}
127 {$R *.Windows.fmx MSWINDOWS}
128 { TStoneGrid }
129
130 function TStoneGrid.CalScore(Stone: TStoneType; X, Y: integer): integer;
131 var
132 i, j: integer;
133 begin
134 if CanSetStone(Stone, X, Y, true) = true then
135 begin
136 if Stone = stBlack then
137 Stone := stWhite
138 else
139 Stone := stBlack;
140 result := 0;
141 for i := 0 to Count - 1 do
142 for j := 0 to Count - 1 do
143 if CanSetStone(Stone, i, j, false) = true then
144 inc(result);
145 FStrings := FBuffer[FTurnIndex];
146 end
147 else
148 begin
149 FStrings := FBuffer[FTurnIndex];
150 result := -1;
151 end;
152 end;
153
154 function TStoneGrid.CanSetStone(Stone: TStoneType; X, Y: integer;
155 Reverse: Boolean; const Visible: Boolean): Boolean;
156 var
157 i: integer;
158 p: Boolean;
159 q: ^TEffectData;
160 procedure Method(m, n: integer);
161 var
162 s: TStoneType;
163 j, k: integer;
164 begin
165 if p = false then
166 Exit;
167 i := 1;
168 while true do
169 begin
170 s := GetStrings(X + m * i, Y + n * i);
171 if (s = stNone) or (s = stError) then
172 break
173 else if s = Stone then
174 if i > 1 then
175 begin
176 if (result = false) and (Reverse = true) then
177 SetStrings(X, Y, Stone);
178 result := true;
179 if Reverse = true then
180 begin
181 for j := 1 to i - 1 do
182 begin
183 Form1.PaintBox1.Repaint;
184 if Visible = true then
185 begin
186 New(q);
187 q^.Left := X + m * j;
188 q^.Top := Y + n * j;
189 q^.Stone := Stone;
190 q^.X := 0;
191 q^.Y := 0;
192 List.Add(q);
193 SetStrings(q^.Left, q^.Top, stEffect);
194 for k := 1 to 10 do
195 begin
196 Sleep(10);
197 Application.ProcessMessages;
198 end;
199 end
200 else
201 SetStrings(X + m * j, Y + n * j, Stone);
202 end;
203 break;
204 end
205 else
206 begin
207 p := false;
208 break;
209 end;
210 end
211 else
212 break
213 else
214 inc(i);
215 end;
216 end;
217
218 begin
219 result := false;
220 if Visible = true then
221 begin
222 FBool := FActive;
223 FActive := false;
224 end;
225 p := true;
226 if GetStrings(X, Y) = stNone then
227 begin
228 Method(-1, -1);
229 Method(-1, 0);
230 Method(-1, 1);
231 Method(0, -1);
232 Method(0, 1);
233 Method(1, -1);
234 Method(1, 0);
235 Method(1, 1);
236 end;
237 end;
238
239 procedure TStoneGrid.Clear;
240 var
241 i, j: integer;
242 begin
243 for i := 0 to Count - 1 do
244 for j := 0 to Count - 1 do
245 Strings[i, j] := stNone;
246 Strings[3, 3] := stBlack;
247 Strings[4, 4] := stBlack;
248 Strings[4, 3] := stWhite;
249 Strings[3, 4] := stWhite;
250 FTurnNumber := 0;
251 FTurnIndex := 0;
252 FBuffer[0] := FStrings;
253 end;
254
255 constructor TStoneGrid.Create;
256 begin
257 inherited;
258 List := TList.Create;
259 end;
260
261 destructor TStoneGrid.Destroy;
262 var
263 i: integer;
264 begin
265 for i := 0 to List.Count - 1 do
266 Dispose(List[i]);
267 List.Free;
268 inherited;
269 end;
270
271 function TStoneGrid.GetStrings(X, Y: integer): TStoneType;
272 begin
273 if (X >= 0) and (X < Count) and (Y >= 0) and (Y < Count) then
274 result := FStrings[X, Y]
275 else
276 result := stError;
277 end;
278
279 procedure TStoneGrid.ImageCount(X, Y: integer);
280 begin
281 FIndex_X := X;
282 FIndex_Y := Y;
283 end;
284
285 function TStoneGrid.ListExecute: Boolean;
286 var
287 p: ^TEffectData;
288 i: integer;
289 begin
290 if List.Count = 0 then
291 result := false
292 else
293 begin
294 for i := 0 to List.Count - 1 do
295 begin
296 p := List.List[i];
297 if p^.X < FIndex_X - 1 then
298 p^.X := p^.X + 1
299 else if p^.Y < FIndex_Y - 1 then
300 begin
301 p^.X := 0;
302 p^.Y := p^.Y + 1;
303 end
304 else
305 begin
306 SetStrings(p^.Left, p^.Top, p^.Stone);
307 Dispose(p);
308 List[i] := nil;
309 end;
310 end;
311 for i := List.Count - 1 downto 0 do
312 if List[i] = nil then
313 List.Delete(i);
314 if List.Count = 0 then
315 begin
316 FActive := FBool;
317 inc(FTurnIndex);
318 inc(FTurnNumber);
319 FBuffer[FTurnIndex] := FStrings;
320 end;
321 result := true;
322 end;
323 end;
324
325 function TStoneGrid.NextStone(Stone: TStoneType): TPoint;
326 var
327 i, j, m, n: integer;
328 begin
329 n := -1;
330 for i := 0 to Count - 1 do
331 for j := 0 to Count - 1 do
332 begin
333 m := CalScore(Stone, i, j);
334 if (n = -1) or ((m > -1) and (n > m)) then
335 begin
336 n := m;
337 result := Point(i, j);
338 end;
339 end;
340 if n = -1 then
341 result := Point(-1, -1);
342 end;
343
344 procedure TStoneGrid.Paint(Canvas: TCanvas);
345 var
346 i: integer;
347 k, m, n: integer;
348 s: TBitmap;
349 p: ^TEffectData;
350 begin
351 m := Form1.Image3.Bitmap.Width;
352 n := Form1.Image3.Bitmap.Height;
353 k := Form1.Size;
354 for i := 0 to List.Count - 1 do
355 begin
356 p := List[i];
357 if p^.Stone = stBlack then
358 s := Form1.Image1.Bitmap
359 else
360 s := Form1.Image2.Bitmap;
361 Canvas.DrawBitmap(s, RectF(p^.X * m, p^.Y * n, (p^.X + 1) * m,
362 (p^.Y + 1) * n), RectF(p^.Left * k, p^.Top * k, (p^.Left + 1) * k,
363 (p^.Top + 1) * k), 1);
364 end;
365 end;
366
367 procedure TStoneGrid.Pause;
368 begin
369 FBool := false;
370 FActive := false;
371 end;
372
373 procedure TStoneGrid.Restart;
374 begin
375 FActive := true;
376 FTurnIndex := FTurnNumber;
377 end;
378
379 procedure TStoneGrid.SetStrings(X, Y: integer; const Value: TStoneType);
380 begin
381 if (X >= 0) and (X < Count) and (Y >= 0) and (Y < Count) then
382 FStrings[X, Y] := Value;
383 end;
384
385 procedure TStoneGrid.SetTurnNumber(const Value: integer);
386 begin
387 if Value > FTurnIndex then
388 FTurnNumber := FTurnIndex
389 else if Value < 0 then
390 FTurnNumber := 0
391 else
392 FTurnNumber := Value;
393 FActive := false;
394 FStrings := FBuffer[FTurnNumber];
395 end;
396
397 procedure TStoneGrid.Start;
398 begin
399 Clear;
400 FActive := true;
401 end;
402
403 { TForm1 }
404
405 procedure TForm1.ChangePlayer;
406 var
407 i, j, m, n: integer;
408 s: string;
409 procedure Main;
410 begin
411 if Index = Player1 then
412 begin
413 Index := Player2;
414 s := '������������';
415 end
416 else
417 begin
418 Index := Player1;
419 s := '������������';
420 end;
421 end;
422 function Execute: Boolean;
423 var
424 i, j: integer;
425 m: integer;
426 n: integer;
427 begin
428 for i := 0 to Count - 1 do
429 for j := 0 to Count - 1 do
430 if StoneGrid.CanSetStone(Index.Stone, i, j, false) = true then
431 begin
432 result := true;
433 Exit;
434 end;
435 result := false;
436 end;
437
438 begin
439 Main;
440 if Execute = false then
441 begin
442 Main;
443 if Execute = false then
444 begin
445 StoneGrid.Pause;
446 m := 0;
447 n := 0;
448 for i := 0 to Count - 1 do
449 for j := 0 to Count - 1 do
450 case StoneGrid[i, j] of
451 stBlack:
452 inc(m);
453 stWhite:
454 inc(n);
455 end;
456 Caption := s;
457 if m > n then
458 s := 'Player1 Win:' + #13#10
459 else if m < n then
460 s := 'Player2 Win:' + #13#10
461 else
462 s := 'Draw:' + #13#10;
463 Showmessage(s + '(Player1) ' + IntToStr(m) + #13#10 + '(Player2) ' +
464 IntToStr(n));
465 end
466 else
467 Caption := s;
468 end
469 else
470 Caption := s;
471 end;
472
473 procedure TForm1.CompStone;
474 var
475 s: TPoint;
476 begin
477 s := StoneGrid.NextStone(Index.Stone);
478 StoneGrid.CanSetStone(Index.Stone, s.X, s.Y, true, true);
479 PaintBox1.Repaint;
480 ChangePlayer;
481 end;
482
483 procedure TForm1.GameStart;
484 begin
485 StoneGrid.Start;
486 PaintBox1.Repaint;
487 Index := Player1;
488 Caption := '�������n������';
489 Timer1.Enabled := true;
490 end;
491
492 procedure TForm1.MenuItem10Click(Sender: TObject);
493 begin
494 StoneGrid.Restart;
495 end;
496
497 procedure TForm1.MenuItem11Click(Sender: TObject);
498 var
499 i: integer;
500 begin
501 with StoneGrid do
502 begin
503 i := TurnNumber;
504 if Sender = MenuItem11 then
505 TurnNumber := TurnNumber + 1
506 else
507 TurnNumber := TurnNumber - 1;
508 if (i = TurnNumber) then
509 Exit
510 else
511 Pause;
512 end;
513 PaintBox1.Repaint;
514 ChangePlayer;
515 end;
516
517 procedure TForm1.MenuItem2Click(Sender: TObject);
518 begin
519 GameStart;
520 end;
521
522 procedure TForm1.MenuItem4Click(Sender: TObject);
523 begin
524 Close;
525 end;
526
527 procedure TForm1.MenuItem6Click(Sender: TObject);
528 begin
529 Player1.Auto := MenuItem6.IsChecked;
530 Player2.Auto := MenuItem7.IsChecked;
531 MenuItem10Click(Sender);
532 end;
533
534 procedure TForm1.MenuItem8Click(Sender: TObject);
535 begin
536 StoneGrid.Pause;
537 end;
538
539 procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
540 var
541 i, j: integer;
542 begin
543 if StoneGrid.Active = false then
544 StoneGrid.Paint(Canvas);
545 for i := 0 to Count - 1 do
546 begin
547 for j := 0 to Count - 1 do
548 begin
549 case StoneGrid.Strings[i, j] of
550 stWhite:
551 Canvas.DrawBitmap(Image4.Bitmap, RectF(0, 0, Image4.Bitmap.Width,
552 Image4.Bitmap.Height), RectF(i * Size, j * Size, (i + 1) * Size,
553 (j + 1) * Size), 1);
554 stBlack:
555 Canvas.DrawBitmap(Image3.Bitmap, RectF(0, 0, Image3.Bitmap.Width,
556 Image3.Bitmap.Height), RectF(i * Size, j * Size, (i + 1) * Size,
557 (j + 1) * Size), 1);
558 stEffect:
559 continue;
560 else
561 Canvas.DrawBitmap(Image5.Bitmap, RectF(0, 0, Image5.Bitmap.Width,
562 Image5.Bitmap.Height), RectF(i * Size, j * Size, (i + 1) * Size,
563 (j + 1) * Size), 1);
564 end;
565 Canvas.DrawLine(PointF(0, j * Size), PointF(Count * Size, j * Size), 1);
566 end;
567 Canvas.DrawLine(PointF(i * Size, 0), PointF(i * Size, Size * Count), 1);
568 end;
569 Canvas.DrawLine(PointF(Count * Size, 0),
570 PointF(Count * Size, Count * Size), 1);
571 Canvas.DrawLine(PointF(0, Count * Size),
572 PointF(Count * Size, Count * Size), 1);
573 end;
574
575 procedure TForm1.PaintBox1Resize(Sender: TObject);
576 begin
577 Size := Min(ClientWidth, ClientHeight) div Count;
578 end;
579
580 procedure TForm1.FormCreate(Sender: TObject);
581 begin
582 StoneGrid := TStoneGrid.Create;
583 StoneGrid.ImageCount(Form1.Image1.Bitmap.Width div Form1.Image3.Bitmap.Width,
584 Form1.Image1.Bitmap.Height div Form1.Image3.Bitmap.Height);
585 Player1 := TPlayer.Create;
586 Player2 := TPlayer.Create;
587 Player1.Stone := stBlack;
588 Player2.Stone := stWhite;
589 Player2.Auto := true;
590 with PaintBox1.Canvas do
591 begin
592 StrokeDash := TStrokeDash.Solid;
593 Stroke.Color := TAlphaColors.Black;
594 StrokeThickness := 3;
595 end;
596 PaintBox1Resize(Sender);
597 GameStart;
598 end;
599
600 procedure TForm1.FormDestroy(Sender: TObject);
601 begin
602 StoneGrid.Free;
603 Player1.Free;
604 Player2.Free;
605 end;
606
607 procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
608 Shift: TShiftState; X, Y: Single);
609 begin
610 PaintBox1Tap(Sender, PointF(X, Y));
611 end;
612
613 procedure TForm1.Timer1Timer(Sender: TObject);
614 begin
615 if (StoneGrid.Active = true) and (Index.Auto = true) then
616 begin
617 Timer1.Enabled := false;
618 CompStone;
619 Timer1.Enabled := true;
620 end;
621 end;
622
623 procedure TForm1.Timer2Timer(Sender: TObject);
624 begin
625 if StoneGrid.ListExecute = true then
626 PaintBox1.Repaint;
627 end;
628
629 procedure TForm1.FormResize(Sender: TObject);
630 begin
631 Size := Min(ClientWidth, ClientHeight) div Count;
632 PaintTo(Canvas);
633 end;
634
635 procedure TForm1.PaintBox1Tap(Sender: TObject; const Point: TPointF);
636 begin
637 if Index.Auto = false then
638 begin
639 MenuItem10Click(Sender);
640 if StoneGrid.CanSetStone(Index.Stone, Floor(Point.X / Size),
641 Floor(Point.Y / Size), true, true) = true then
642 begin
643 PaintBox1.Repaint;
644 ChangePlayer;
645 end;
646 end;
647 end;
648
649 end.

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