Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


Revision 37 - (show annotations) (download) (as text)
Sun Aug 30 08:32:57 2015 UTC (8 years, 6 months ago) by yamat0jp
File MIME type: text/x-pascal
File size: 17795 byte(s)
HardモードをシンプルなAIに手直ししました。
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 inc(Score)
189 else
190 dec(Score);
191 case Stone of
192 stBlack:
193 Stone := stWhite;
194 stWhite:
195 Stone := stBlack;
196 end;
197 Hard;
198 if loop > 1 then
199 begin
200 Easy;
201 FStrings := FBuffer[FTurnIndex + loop];
202 end
203 else
204 FBuffer[FTurnIndex + loop] := FStrings;
205 end;
206 end;
207 dec(loop);
208 end;
209
210 begin
211 if CanSetStone(Stone, X, Y, true) = true then
212 begin
213 Score := 0;
214 result := true;
215 if FTurnIndex < 50 then
216 inc(Score, AddScore(X, Y, waste));
217 dec(Score, AddScore(X, Y, worth));
218 case Stone of
219 stBlack:
220 Stone := stWhite;
221 stWhite:
222 Stone := stBlack;
223 end;
224 if (Form1.MenuItem14.IsChecked = true) and (FTurnIndex + 2 <= 60) then
225 begin
226 loop := 0;
227 Hard;
228 end
229 else
230 Easy;
231 end
232 else
233 result := false;
234 FStrings := FBuffer[FTurnIndex];
235 end;
236
237 function TStoneGrid.CanSetStone(Stone: TStoneType; X, Y: integer;
238 Reverse: Boolean; const Visible: Boolean): Boolean;
239 var
240 i: integer;
241 p: Boolean;
242 q: TEffectData;
243 procedure Method(m, n: integer);
244 var
245 s: TStoneType;
246 j: integer;
247 k: integer;
248 begin
249 if p = false then
250 Exit;
251 i := 1;
252 while true do
253 begin
254 s := GetStrings(X + m * i, Y + n * i);
255 if s = stEffect then
256 s := FEffectStone;
257 if (s = stNone) or (s = stError) then
258 break
259 else if s = Stone then
260 if i > 1 then
261 begin
262 if (result = false) and (Reverse = true) then
263 SetStrings(X, Y, Stone);
264 result := true;
265 if Reverse = true then
266 begin
267 Form1.PaintBox1.Repaint;
268 for j := 1 to i - 1 do
269 begin
270 if Visible = true then
271 begin
272 FEffectStone := Stone;
273 q.Left := X + m * j;
274 q.Top := Y + n * j;
275 q.X := 0;
276 q.Y := 0;
277 FList.Add(q);
278 SetStrings(q.Left, q.Top, stEffect);
279 for k := 1 to 10 do
280 begin
281 Sleep(15);
282 Application.ProcessMessages;
283 end;
284 end
285 else
286 SetStrings(X + m * j, Y + n * j, Stone);
287 end;
288 break;
289 end
290 else
291 begin
292 p := false;
293 break;
294 end;
295 end
296 else
297 break
298 else
299 inc(i);
300 end;
301 end;
302
303 begin
304 result := false;
305 p := true;
306 if GetStrings(X, Y) = stNone then
307 begin
308 Method(-1, -1);
309 Method(-1, 0);
310 Method(-1, 1);
311 Method(0, -1);
312 Method(0, 1);
313 Method(1, -1);
314 Method(1, 0);
315 Method(1, 1);
316 end;
317 end;
318
319 procedure TStoneGrid.Clear;
320 var
321 i, j: integer;
322 begin
323 FList.Clear;
324 for i := 0 to bmp_count - 1 do
325 for j := 0 to bmp_count - 1 do
326 Strings[i, j] := stNone;
327 Strings[3, 3] := stBlack;
328 Strings[4, 4] := stBlack;
329 Strings[4, 3] := stWhite;
330 Strings[3, 4] := stWhite;
331 FTurnNumber := 0;
332 FTurnIndex := 0;
333 FBuffer[0] := FStrings;
334 end;
335
336 constructor TStoneGrid.Create;
337 begin
338 inherited;
339 FList := TList<TEffectData>.Create;
340 end;
341
342 destructor TStoneGrid.Destroy;
343 begin
344 FList.Free;
345 inherited;
346 end;
347
348 procedure TStoneGrid.GameOver;
349 begin
350 FGameOver := true;
351 FActive := false;
352 end;
353
354 function TStoneGrid.GetActive: Boolean;
355 begin
356 if (FActive = true) and (FList.Count = 0) then
357 result := true
358 else
359 result := false;
360 end;
361
362 function TStoneGrid.GetStrings(X, Y: integer): TStoneType;
363 begin
364 if (X >= 0) and (X < bmp_count) and (Y >= 0) and (Y < bmp_count) then
365 result := FStrings[X, Y]
366 else
367 result := stError;
368 end;
369
370 procedure TStoneGrid.ImageCount(X, Y: integer);
371 begin
372 FIndex_X := X;
373 FIndex_Y := Y;
374 end;
375
376 function TStoneGrid.ListExecute: Boolean;
377 var
378 i: integer;
379 s: TEffectData;
380 begin
381 if FList.Count = 0 then
382 result := false
383 else
384 begin
385 i := 0;
386 while i < FList.Count do
387 begin
388 s := FList[i];
389 if s.X < FIndex_X - 1 then
390 s.X := s.X + 1
391 else if s.Y < FIndex_Y - 1 then
392 begin
393 s.X := 0;
394 s.Y := s.Y + 1;
395 end
396 else
397 begin
398 SetStrings(s.Left, s.Top, FEffectStone);
399 FList.Delete(i);
400 inc(i);
401 continue;
402 end;
403 FList[i] := s;
404 inc(i);
405 end;
406 if FList.Count = 0 then
407 begin
408 inc(FTurnIndex);
409 inc(FTurnNumber);
410 FBuffer[FTurnIndex] := FStrings;
411 Form1.PaintBox1.Repaint;
412 Form1.ChangePlayer;
413 if FGameOver = false then
414 FActive := true
415 end;
416 result := true;
417 end;
418 end;
419
420 function TStoneGrid.NextStone(Stone: TStoneType; var Pos: TPoint): Boolean;
421 var
422 i, j, m, n: integer;
423 begin
424 result := false;
425 n := 0;
426 for i := 0 to bmp_count - 1 do
427 for j := 0 to bmp_count - 1 do
428 if (CalScore(Stone, i, j, m) = true) and ((result = false) or (m < n))
429 then
430 begin
431 if result = false then
432 result := true;
433 n := m;
434 Pos := Point(i, j);
435 end;
436 end;
437
438 procedure TStoneGrid.Paint(Canvas: TCanvas);
439 var
440 k: integer;
441 s: TBitmap;
442 p: TEffectData;
443 begin
444 k := Form1.Size;
445 if FEffectStone = stBlack then
446 s := Form1.Image1.Bitmap
447 else
448 s := Form1.Image2.Bitmap;
449 for p in FList do
450 begin
451 Canvas.DrawBitmap(s, RectF(p.X * 50, p.Y * 50, (p.X + 1) * 50,
452 (p.Y + 1) * 50), RectF(p.Left * k, p.Top * k, (p.Left + 1) * k,
453 (p.Top + 1) * k), 1);
454 end;
455 end;
456
457 procedure TStoneGrid.Pause;
458 begin
459 FActive := false;
460 end;
461
462 procedure TStoneGrid.Restart;
463 begin
464 FActive := true;
465 FGameOver := false;
466 FTurnIndex := FTurnNumber;
467 end;
468
469 procedure TStoneGrid.SetActive(const Value: Boolean);
470 begin
471 if (FGameOver = false) or (Value = false) then
472 FActive := Value;
473 end;
474
475 procedure TStoneGrid.SetStrings(X, Y: integer; const Value: TStoneType);
476 begin
477 if (X >= 0) and (X < bmp_count) and (Y >= 0) and (Y < bmp_count) then
478 FStrings[X, Y] := Value;
479 end;
480
481 procedure TStoneGrid.SetTurnNumber(const Value: integer);
482 begin
483 if Value > FTurnIndex then
484 FTurnNumber := FTurnIndex
485 else if Value < 0 then
486 FTurnNumber := 0
487 else
488 FTurnNumber := Value;
489 FStrings := FBuffer[FTurnNumber];
490 end;
491
492 procedure TStoneGrid.Start;
493 begin
494 Clear;
495 FActive := true;
496 FGameOver := false;
497 end;
498
499 { TForm1 }
500
501 procedure TForm1.ChangePlayer;
502 var
503 i, j, m, n: integer;
504 s: string;
505 procedure Main;
506 begin
507 if Index = Player1 then
508 begin
509 Index := Player2;
510 s := '������������';
511 end
512 else
513 begin
514 Index := Player1;
515 s := '������������';
516 end;
517 end;
518 function Execute: Boolean;
519 var
520 i, j: integer;
521 begin
522 for i := 0 to bmp_count - 1 do
523 for j := 0 to bmp_count - 1 do
524 if StoneGrid.CanSetStone(Index.Stone, i, j, false) = true then
525 begin
526 result := true;
527 Exit;
528 end;
529 result := false;
530 end;
531
532 begin
533 Main;
534 if Execute = false then
535 begin
536 Main;
537 if Execute = false then
538 begin
539 m := 0;
540 n := 0;
541 for i := 0 to bmp_count - 1 do
542 for j := 0 to bmp_count - 1 do
543 case StoneGrid[i, j] of
544 stBlack:
545 inc(m);
546 stWhite:
547 inc(n);
548 end;
549 Caption := s;
550 if m > n then
551 s := 'Player1 Win:' + #13#10
552 else if m < n then
553 s := 'Player2 Win:' + #13#10
554 else
555 s := 'Draw:' + #13#10;
556 StoneGrid.GameOver;
557 Showmessage(s + '(Player1) ' + m.ToString + #13#10 + '(Player2) ' +
558 n.ToString);
559 end
560 else
561 Caption := s;
562 end
563 else
564 Caption := s;
565 end;
566
567 procedure TForm1.CompStone;
568 var
569 s: TPoint;
570 begin
571 StoneGrid.Active := false;
572 if StoneGrid.NextStone(Index.Stone, s) = true then
573 begin
574 StoneGrid.CanSetStone(Index.Stone, s.X, s.Y, true, true);
575 PaintBox1.Repaint;
576 end
577 else
578 ChangePlayer;
579 end;
580
581 procedure TForm1.GameStart;
582 begin
583 Index := Player1;
584 StoneGrid.Start;
585 PaintBox1.Repaint;
586 Caption := '�������n������';
587 end;
588
589 procedure TForm1.MenuItem10Click(Sender: TObject);
590 begin
591 StoneGrid.Restart;
592 end;
593
594 procedure TForm1.MenuItem11Click(Sender: TObject);
595 var
596 i: integer;
597 begin
598 with StoneGrid do
599 begin
600 i := TurnNumber;
601 if Sender = MenuItem11 then
602 TurnNumber := TurnNumber + 1
603 else
604 TurnNumber := TurnNumber - 1;
605 if (i = TurnNumber) then
606 Exit
607 else
608 Pause;
609 end;
610 PaintBox1.Repaint;
611 ChangePlayer;
612 end;
613
614 procedure TForm1.MenuItem2Click(Sender: TObject);
615 begin
616 Timer1.Enabled := false;
617 Timer2.Enabled := false;
618 GameStart;
619 Timer1.Enabled := true;
620 Timer2.Enabled := true;
621 end;
622
623 procedure TForm1.MenuItem4Click(Sender: TObject);
624 begin
625 Close;
626 end;
627
628 procedure TForm1.MenuItem6Click(Sender: TObject);
629 begin
630 Player1.Auto := MenuItem6.IsChecked;
631 Player2.Auto := MenuItem7.IsChecked;
632 end;
633
634 procedure TForm1.MenuItem8Click(Sender: TObject);
635 begin
636 StoneGrid.Pause;
637 end;
638
639 procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
640 var
641 i, j: integer;
642 begin
643 if StoneGrid.Active = false then
644 StoneGrid.Paint(Canvas);
645 for i := 0 to bmp_count - 1 do
646 begin
647 for j := 0 to bmp_count - 1 do
648 begin
649 case StoneGrid.Strings[i, j] of
650 stWhite:
651 Canvas.DrawBitmap(Image3.Bitmap, RectF(100, 0, 150, 50),
652 RectF(i * Size, j * Size, (i + 1) * Size, (j + 1) * Size), 1);
653 stBlack:
654 Canvas.DrawBitmap(Image3.Bitmap, RectF(50, 0, 100, 50),
655 RectF(i * Size, j * Size, (i + 1) * Size, (j + 1) * Size), 1);
656 stEffect:
657 continue;
658 else
659 Canvas.DrawBitmap(Image3.Bitmap, RectF(0, 0, 50, 50),
660 RectF(i * Size, j * Size, (i + 1) * Size, (j + 1) * Size), 1);
661 end;
662 Canvas.DrawLine(PointF(0, j * Size), PointF(bmp_count * Size,
663 j * Size), 1);
664 end;
665 Canvas.DrawLine(PointF(i * Size, 0), PointF(i * Size, Size * bmp_count), 1);
666 end;
667 Canvas.DrawLine(PointF(bmp_count * Size, 0), PointF(bmp_count * Size,
668 bmp_count * Size), 1);
669 Canvas.DrawLine(PointF(0, bmp_count * Size), PointF(bmp_count * Size,
670 bmp_count * Size), 1);
671 end;
672
673 procedure TForm1.PaintBox1Resize(Sender: TObject);
674 begin
675 Size := Min(ClientWidth, ClientHeight) div bmp_count;
676 end;
677
678 procedure TForm1.FormCreate(Sender: TObject);
679 begin
680 ClientWidth := 400;
681 ClientHeight := 400;
682 StoneGrid := TStoneGrid.Create;
683 StoneGrid.ImageCount(6, 5);
684 Player1 := TPlayer.Create;
685 Player2 := TPlayer.Create;
686 Player1.Stone := stBlack;
687 Player2.Stone := stWhite;
688 Player2.Auto := true;
689 with PaintBox1.Canvas do
690 begin
691 StrokeDash := TStrokeDash.Solid;
692 Stroke.Color := TAlphaColors.Black;
693 StrokeThickness := 3;
694 end;
695 PaintBox1Resize(Sender);
696 GameStart;
697 end;
698
699 procedure TForm1.FormDestroy(Sender: TObject);
700 begin
701 StoneGrid.Free;
702 Player1.Free;
703 Player2.Free;
704 end;
705
706 procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
707 Shift: TShiftState; X, Y: Single);
708 begin
709 PaintBox1Tap(Sender, PointF(X, Y));
710 end;
711
712 procedure TForm1.Timer1Timer(Sender: TObject);
713 begin
714 if (StoneGrid.Active = true) and (Index.Auto = true) then
715 CompStone;
716 end;
717
718 procedure TForm1.Timer2Timer(Sender: TObject);
719 begin
720 if (StoneGrid.Active = false) and (StoneGrid.ListExecute = true) then
721 PaintBox1.Repaint;
722 end;
723
724 procedure TForm1.FormResize(Sender: TObject);
725 begin
726 Size := Min(ClientWidth, ClientHeight) div bmp_count;
727 PaintTo(Canvas);
728 end;
729
730 procedure TForm1.PaintBox1Tap(Sender: TObject; const Point: TPointF);
731 begin
732 if Index.Auto = false then
733 begin
734 MenuItem10Click(Sender);
735 StoneGrid.Active := false;
736 if StoneGrid.CanSetStone(Index.Stone, Floor(Point.X / Size),
737 Floor(Point.Y / Size), true, true) = true then
738 PaintBox1.Repaint;
739 StoneGrid.Active := true;
740 end;
741 end;
742
743 end.

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