Develop and Download Open Source Software

Browse Subversion Repository

Contents of /Unit1.pas

Parent Directory Parent Directory | Revision Log Revision Log


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

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