Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


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

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