diff --git a/Занимательное программирование/7/1_minesweeper/assets/imagelist.png b/Занимательное программирование/7/1_minesweeper/assets/imagelist.png
new file mode 100644
index 0000000..8395c7e
Binary files /dev/null and b/Занимательное программирование/7/1_minesweeper/assets/imagelist.png differ
diff --git a/Занимательное программирование/7/1_minesweeper/assets/imagelist.xcf b/Занимательное программирование/7/1_minesweeper/assets/imagelist.xcf
new file mode 100644
index 0000000..31cd679
Binary files /dev/null and b/Занимательное программирование/7/1_minesweeper/assets/imagelist.xcf differ
diff --git a/Занимательное программирование/7/1_minesweeper/minesweeper.ico b/Занимательное программирование/7/1_minesweeper/minesweeper.ico
new file mode 100644
index 0000000..86b1038
Binary files /dev/null and b/Занимательное программирование/7/1_minesweeper/minesweeper.ico differ
diff --git a/Занимательное программирование/7/1_minesweeper/minesweeper.lpi b/Занимательное программирование/7/1_minesweeper/minesweeper.lpi
new file mode 100644
index 0000000..76cc09c
--- /dev/null
+++ b/Занимательное программирование/7/1_minesweeper/minesweeper.lpi
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
diff --git a/Занимательное программирование/7/1_minesweeper/minesweeper.lpr b/Занимательное программирование/7/1_minesweeper/minesweeper.lpr
new file mode 100644
index 0000000..48f2730
--- /dev/null
+++ b/Занимательное программирование/7/1_minesweeper/minesweeper.lpr
@@ -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.
+
diff --git a/Занимательное программирование/7/1_minesweeper/minesweeper.lps b/Занимательное программирование/7/1_minesweeper/minesweeper.lps
new file mode 100644
index 0000000..d33f426
--- /dev/null
+++ b/Занимательное программирование/7/1_minesweeper/minesweeper.lps
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Занимательное программирование/7/1_minesweeper/unit1.lfm b/Занимательное программирование/7/1_minesweeper/unit1.lfm
new file mode 100644
index 0000000..faf10a6
--- /dev/null
+++ b/Занимательное программирование/7/1_minesweeper/unit1.lfm
@@ -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
diff --git a/Занимательное программирование/7/1_minesweeper/unit1.pas b/Занимательное программирование/7/1_minesweeper/unit1.pas
new file mode 100644
index 0000000..d20aa7a
--- /dev/null
+++ b/Занимательное программирование/7/1_minesweeper/unit1.pas
@@ -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.
+