Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


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

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