1
0

Добавил сапера из седьмой главы

This commit is contained in:
2026-03-11 14:44:08 +01:00
parent 1c52c7d560
commit e87eaf26d5
8 changed files with 633 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<General>
<SessionStorage Value="InProjectDir"/>
<Title Value="minesweeper"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="minesweeper.lpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<Target>
<Filename Value="minesweeper"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>

View File

@@ -0,0 +1,28 @@
program minesweeper;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF}
{$IFDEF HASAMIGA}
athreads,
{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, Unit1
{ you can add units after this };
{$R *.res}
begin
RequireDerivedFormResource:=True;
Application.Scaled:=True;
{$PUSH}{$WARN 5044 OFF}
Application.MainFormOnTaskbar:=True;
{$POP}
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<Version Value="12"/>
<BuildModes Active="Default"/>
<Units>
<Unit>
<Filename Value="minesweeper.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="36"/>
</Unit>
<Unit>
<Filename Value="unit1.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="Unit1"/>
<IsVisibleTab Value="True"/>
<TopLine Value="117"/>
<CursorPos Y="152"/>
<UsageCount Value="36"/>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
</Unit>
</Units>
<JumpHistory HistoryIndex="25">
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="37" Column="14"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="38" Column="3"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="16" Column="46"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="8" Column="65"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="22" Column="77"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="48" Column="5"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="88" Column="21" TopLine="31"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="71" Column="24" TopLine="31"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="50" Column="26" TopLine="2"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="63" Column="3" TopLine="34"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="36" Column="22"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="80" Column="5" TopLine="39"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="110" Column="28" TopLine="65"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="23" Column="15"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="24" Column="16" TopLine="4"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="23" Column="71"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="123" TopLine="92"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="125" Column="11" TopLine="85"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="22" Column="19"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="158" Column="36" TopLine="115"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="20" Column="42" TopLine="7"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="129" Column="38" TopLine="79"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="20" Column="14"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="23" Column="22"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="140" Column="19" TopLine="105"/>
</Position>
<Position>
<Filename Value="unit1.pas"/>
<Caret Line="28" Column="73"/>
</Position>
</JumpHistory>
<RunParams>
<FormatVersion Value="2"/>
<Modes ActiveMode=""/>
</RunParams>
</ProjectSession>
</CONFIG>

View File

@@ -0,0 +1,136 @@
object Form1: TForm1
Left = 3160
Height = 758
Top = 657
Width = 480
Caption = 'Form1'
ClientHeight = 758
ClientWidth = 480
DesignTimePPI = 144
LCLVersion = '4.6.0.0'
OnCreate = FormCreate
OnDestroy = FormDestroy
object Button1: TButton
AnchorSideLeft.Control = Owner
AnchorSideRight.Control = Status
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 104
Height = 61
Top = 672
Width = 168
Anchors = [akTop, akBottom]
BorderSpacing.Bottom = 25
Caption = 'Новая игра'
TabOrder = 0
OnClick = Button1Click
end
object Status: TLabel
AnchorSideLeft.Control = Button1
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrCenter
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 335
Height = 1
Top = 717
Width = 1
Anchors = [akBottom]
BorderSpacing.Bottom = 40
end
object ImageList: TImageList
Height = 24
Width = 24
Left = 224
Top = 608
Bitmap = {
4C7A0B00000018000000180000009F0A00000000000078DAED9C678814491BC7
45CE2F1EC2C1C1E2895F14943B110F1605454411443CF14C28B2E899C58C0123
8A398B6B4451319D59CC0A663DB3675AB3EEBA6B58735CE31AB7DEF9D5F1B4B3
63F7CC7475F7CBADD77F282654D57F7AAAAB9E7A52B55221BCE0E5CB976ADDBA
75AA63C78EAA4A952AAA71E3C66AC68C192A3B3BDB33F7C3870F55BD7AF554B1
62C554A3468DD4C4891355DFBE7DF567CAE1C3878DB90B0A0A54AF5EBD340FD7
FFE9D327AB8E6B4F4D4D55292929EAC1830746FC972F5FD6DCFC06BF158B9D3B
77EAFAC58B171BF12F5FBE5CF7DFBB77AF6DFDD3A74F757DDDBA75D5E7CF9F5D
F3F7EFDF5FF7BF7EFDBA631BB869F3E4C913D7FCD5AA554BD8B75FBF7EBA4D66
66A62B6EFEAFCC9157AF5E39B61B33668C6E73EEDC3957FCEFDFBFB7F8DFBE7D
EBD86EF2E4C9BACDE9D3A703BDFEF3E7CFBB1EFFEAD5ABEBBE8F1F3F766C236B
2D2B2BCB35FFA04183E2DE3BD644CD9A35759B67CF9EB9E65FB3668DEECB3AB2
03EB96FAA64D9BDAAEBF4460DED3BF73E7CEB6EB67FDFAF5BA7EEDDAB5C63268
E8D0A19A63D5AA5585E4CFA54B9754D9B26555A54A95545E5E9E313FE3DABC79
73FD1BC8E549932659320F7EB7F3DE0E6FDEBCD163D1A143077DBD8CF7BC79F3
D4DDBB77C3CD31C47F06478E1C51E5CB97D76B8BBDD72FB0D72C58B0C0DA0FFC
E447F6230F90055C3FFA9B9FFCC801E4CE8D1B37F467BFF9F7ECD9A35EBC7861
7DF69B3F16217FC81FF2170DFEE7CF9FAB61C386152AA54A95D2FCD815D1DFD3
D6447646CBE478259E8E1D224451063E9A65CB96A9366DDAA88A152B6A9FC088
1123B43E61E2778806F689E8540D1A3450A3468D52DDBA75B3D6D5B871E3D4C7
8F1F8DE583C89B6DDBB615B2BFD057C43E3E78F0A011FF8E1D3B74FFD1A347DB
D68BFF67ECD8B146FCB76FDFD6639C939313D7FFD4A54B9740EEFBC993273D5D
7F22886F83FFE837B8A770F7ECD9D378FEC4E3669F69D8B0A1915FCC09F830F0
5372DD2D5BB6548F1E3DF2D5C6983E7DBAB53746EBD45EF1EEDD3B3564C810CD
9D9E9EAE7FCB2F70EF649E2C59B2C4B3BC89059C7063C798F89092F12FB56DDB
567DF8F0C1F7393E6DDA34CBFF15AB07C5167CF86E41BF64F51F13FF5E881045
01B76EDD52F3E7CFD732195D05FD67E4C8913A36E5756FD9B76F9FB5865AB56A
A5655DD7AE5DADEFF01F9BCAD3DCDC5CBD4F11E38A8D4FA05BD4A95347FFC6EE
DDBB8DF8253EB57AF56ADB7A78A947A733C1CD9B37B50EE2645B9D3973C6137F
222C5AB448F36FDAB4C9D77D98B8C5CA952B3577F7EEDDE3C697920531846879
CC1CDABF7FBF6FFB0E312AF4066200AC01E6D5E0C183751CC36FB0C767646458
718D03070E04B6AEE1270E8C0E1304EAD7AFAF7F83B9EC5617C47E206EE4141F
A28DD8376EF981C819649093FD21F3E9F5EBD7AEF9918FF4E51A2F5EBCF8954D
C9DCA79E5C02537D19B92CD7C87CC12E259E277E20DE9BE83ED1608ECF9C3953
F333F76BD5AAA5E53271793F75DD10218A02900BE814AC2F7C107E82FD8A352B
6BDA6F7EC929484B4BF39D9F1C0A38E7CC9963C5F3FCE2CFCFCFD7FA213E0764
B1DFFCA2EB889CF6931FCED83C28BFF8190BC684FBC918F9CD3F6BD62CDB1C29
3FF84F9D3A65E5A6C5C22B3F3A03FB549F3E7D6C6D14AFFCB2B7275B962E5DEA
8A9F9C22AED1A9B46EDDDAD2FDF97CECD8315FE584DFEB2BE40F11A26801B999
8C6C3B7BF6ACF1DE457F6C8A78BE5BB7B9B1026213F063B307813B77EE687EF2
408380F8CFC9090F02172E5CD0FC73E7CE0D84FFC489139A1FDD0A1F06E3444E
347147DEF39D17FF21FE9DE879883D4DFE27F75BBE232E63EADBC02FD0A2450B
EDE7E15E478398A4F867880D07812B57AE687E6C0D3F7C6476FE037C3FFC861F
6719EC40CC1C7EFE8BC9F5E177738A7911CF163B2CF6FE2403E252F172D725FE
8B9F383A769E2C243E8E0F2CD63F85EF0DBD9DFA5DBB7619CB676483CC75F206
C8C7EFDDBBB7F51D7A8A979821F700FB65EAD4A97ABCC87FE09C0A71CE589F56
8810DF2A905F53A64CD1393AD89503060CD0FB971FF185AD5BB7EAB58ACF16BF
2AF9342297BDE4FF44FB1EB017F1390B90ABD8C65ECF98890FDDCEFF8E8C23CE
839E6102CE5704A95F498ECC962D5B02E197F820FB08BA28FE1FF409CE9090B3
C47D8FF6D9B885E4B3C0834ED5AE5D3B9DC7810E24E78ED81338BF6202E69EE8
1FDBB76F2FB48FE05F91B36BA6E7FB264C98A0FB730ECF2EF744E22FE4EE9BE8
70B367CF4E787E49D619B162B7D8B871A375B6C909DC1353FD8ADCC078F9678C
19FB316D4CCE7032F7247E66D7FFEAD5ABBA0E7967AA43886C630D479FF32337
51FCDCB4F162A332DF258EC97B7208645C183BAF390AFC7772F4B0255857AC35
DE1F3A74C8482F0C11A22880B51364FE1B723351DE9ED8777EE66BC6EA46A6FB
5722D9CA5ECFD97E93DC8144903CD9207287C9BB65CFE5DC9CDFF9A6807C07AE
9DFDC56F88CEC8DC0902C4364DCFA327023A15F39DF38441EC2B928FB661C386
40C646F4C1207C49E80E70A33B073136220B060E1C18C8D8787D164622E08384
1F9D34C879EFF42C821021BE5570568A184974FE337177F65EAFB2486432BE1F
6C1774226C7879EECCF0E1C38D73ECEEDFBF6FC5D762FD33C413381B443DB6BD
09389B4E7FFC1076387EFCB8AEC757E6656C38A36207895FB1EF98807D4ACE8F
D9DDC7CD9B37EB7A72A6BCCA4DEE297A15B6287B19F91AD8A8CC292FBA2DFA19
7E2C79865474612E79D59B99FBF890989FE3C78FD7FE3CFC2AC434B083F19D99
9E1BC21FC918C013EB7F617E4A6CC334FF5C72639DF2FBB159A8E71A4CE26B12
678CA7EFC83AC697E5169C6BA2EFB56BD71CDBC87D773A23998C7F8F3855BCF1
A198E410CBF904EE6F6C7C0E7F1E39C5D4135B32C58A152B2CF929F313598D0E
2DB17FAF6B00DF3F735EF29F8907E2FF41FE0595371FE2DB043111E60DAF4180
671432EF79F56A9F1333E27D7489DE5FA2BFE7DC017B19B91289FE9B9BBC49BB
C29A0F923FD1790CA73188373E4D9A3431E24FB62EFAB7FFCDFCA233F2EA969F
7925F25E0A6780F9CE6ECEA13713A345876ED6AC99D5A772E5CA5A678D3D5724
7104BB429DDDFE58BB766DDBF6254B96FC2A2F2E68FE64C647EA79753B3EFF85
F9E9377FD0F22108F9297B8849C12E4824FF659EC68E0DA574E9D29A87D7D83A
A775EE06721E91D72070F4E851BD96790DF1FF07A628A61C8FBBA2F8F1E81338
11853CEE9354968859A97EF841A93265C8D135B5DB79BE965219194A91FE1711
D3AA5D3BA57EFE99F5FDA5C431FD1C71EF1EFE6015D1C594FAED37A5BEFFBE30
A7577E8E23C7E3FC52DEABCC4CF7FE31D2317FFF5D45F6B87F78BEFBCE89FF73
84DFBDEF81F9F1F7DF3CBB58456C39E7EB4F49C98FDC5FF3FC2ED21DFEFA8BE7
FC28F5EBAF5FF357A9F24265677BCBEB657E338F7844F61F7F2855A2C417FED4
D43C9593E34FDE30BF830B9154F49F7E2AD0FC3FFE98AFB2B23EF8BA76F3F20A
54FBF6B911FED7EA975F9E45C6C75FFB1A3F5F7A3A67DA46A9B4B43F556EEE23
DFF9E5B9349D3AB5F7FD19C1F8FBC8BDFD87BF5364ADDF3318E702ADFBA15F72
B6823C77E252E4CD10F3AD51A386E647F72456481BDAD22791AF0F7F08E7FA7A
F4E8A1AA56ADAAF38B2A54A810919565B48FA678F1E296AE50223259CB952BA7
DBD0963EF48DE753214F09BF95E42DB929F4A16FBC5C29FE1FFF15DF3E7EC785
0B17EA679D90C72EB962926BC477D4D186B6F4A16FB2FE50E60AB979E406E21F
C387C7585378CF77D4D126CC3332C7FF00F01A02FB
}
end
end

View File

@@ -0,0 +1,248 @@
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons, StdCtrls;
const
FieldWidth = 20; { Ширина поля }
FieldHeight = 25; { Высота поля }
CellsPerMine = 6; { Среднее значение количества клеток на одну мину }
type
{ "Доработанная" кнопка }
MySpeedButton = class(TSpeedButton)
public
x, y: Integer; { Её положение на игровом поле }
Uncovered: Boolean; { Нажата или нет }
IsMine: Boolean; { Находится ли в ней мина }
Flagged: Boolean; { Помечена флажком }
Clicked: Boolean;
procedure Uncover;
procedure Flag;
{ Обработчик события Click }
procedure MouseLeave; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; ax, ay: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; ax, ay: Integer); override;
end;
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
ImageList: TImageList;
Status: TLabel;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
public
end;
var
{ Игровое поле (двумерный массив кнопок) }
Field: array[0..FieldWidth - 1, 0..FieldHeight - 1] of MySpeedButton;
GameOver: Boolean = false; { Индикатор конца игры }
Mines: Integer; { Количество мин }
Opened: Integer; { Количество открытых клеток }
Form1: TForm1;
{ Создание игрового поля }
procedure MakeButtons;
procedure StartGame;
implementation
{$R *.lfm}
{ MySpeedButton }
{ Обработка щелчка на кнопке }
procedure MySpeedButton.Uncover;
var
c: Integer;
i, j: Integer;
dx, dy: Integer;
begin
{ Теперь кнопка точно нажата }
Uncovered := true;
{ Если в ней оказалась мина }
if IsMine then
begin
GameOver := true;
Form1.Status.Caption := 'Поражения!';
{ Выводим изображение мины (9) }
Form1.ImageList.GetBitmap(9, Glyph)
end
else
begin
c := 0;
for dx := -1 to 1 do
for dy := -1 to 1 do
{ Клетка сама себе не сосед }
if not ((dx = 0) and (dy = 0)) then
begin
{ Координаты текущего соседа }
i := x + dx;
j := y + dy;
{ Если сосед не за пределами поля, учитываем его }
{ Integer(Field[i, j].IsMine) = 1, если есть мина. }
{ Integer(Field[i, j].IsMine) = 0 в противном случае }
if (i >= 0) and (j >= 0) and (i < FieldWidth) and (j < FieldHeight) then
c := c + Integer(Field[i, j].IsMine);
end;
Form1.ImageList.GetBitmap(c, Glyph); { Рисуем требуемую картинку }
{ Мы открыли еще одну клетку }
Opened := Opened + 1;
{ Открыты все безопасные клетки }
if Opened + Mines = FieldWidth * FieldHeight then
begin
{ Конец игры }
GameOver := true;
Form1.Status.Caption := 'Победа!'
end;
if c = 0 then
for dx := -1 to 1 do
for dy := -1 to 1 do
{ Клетка сама себе не сосед }
if not ((dx = 0) and (dy = 0)) then
begin
{ Координаты текущего соседа }
i := x + dx;
j := y + dy;
if (i >= 0) and (j >= 0) and (i < FieldWidth) and (j < FieldHeight) and not Field[i, j].Uncovered then
Field[i, j].Uncover
end
end;
end;
procedure MySpeedButton.Flag;
begin
if Flagged then
begin
Flagged := false;
Glyph := nil
end
else
begin
Flagged := true;
Form1.ImageList.GetBitmap(10, Glyph)
end
end;
procedure MySpeedButton.MouseLeave;
begin
Clicked := false
end;
procedure MySpeedButton.MouseDown(Button: TMouseButton; Shift: TShiftState; ax, ay: Integer);
begin
if (Button = mbLeft) or (Button = mbRight) then
Clicked := true
end;
procedure MySpeedButton.MouseUp(Button: TMouseButton; Shift: TShiftState; ax, ay: Integer);
begin
{ Если кнопка уже нажата или игра закончена, не обрабатываем }
if GameOver or Uncovered or not Clicked then Exit;
if (Button = mbLeft) and not Flagged then
Uncover
else if Button = mbRight then
Flag
end;
procedure StartGame;
var
i, j: Integer;
begin
{ Строка статуса изначально пуста }
Form1.Status.Caption := '';
{ Счетчик мин }
Mines := 0;
{ Счетчик открытых клеток }
Opened := 0;
{ Еще не конец игры }
GameOver := false;
for i := 0 to FieldWidth - 1 do
for j := 0 to FieldHeight - 1 do
begin
{ Пока на кнопках нет картинок }
Field[i, j].Glyph := nil;
{ и ни одна из них не нажата }
Field[i, j].Uncovered := false;
{ и не помечена }
Field[i, j].Flagged := false;
Field[i, j].Clicked := false;
{ С вероятностью 1/CellsPerMine }
if Random(CellsPerMine) = 0 then
begin
{ Размещаем мину }
Field[i, j].IsMine := true;
Mines := Mines + 1
end
else
begin
{ иначе клетка безопасна }
Field[i, j].IsMine := false
end
end
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
{ При запуске программы создаем кнопки }
MakeButtons;
StartGame;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
StartGame;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i, j: Integer;
begin
for i := 0 to FieldWidth - 1 do
for j := 0 to FieldHeight - 1 do
Field[i, j].Free;
end;
procedure MakeButtons;
var
i, j: Integer;
begin
for i := 0 to FieldWidth - 1 do
for j := 0 to FieldHeight - 1 do
begin
Field[i, j] := MySpeedButton.Create(nil); { Создать кнопку }
with Field[i, j] do
begin
{ Указываем координаты кнопки }
Left := i * 24;
Top := j * 24;
{ Указываем размеры кнопки }
Width := 24;
Height := 24;
Parent := Form1; { а также родительскую форму }
{ x, y - Позиция кнопки на игровом поле }
x := i;
y := j
end
end;
end;
end.