Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


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

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