Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


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

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