Vanilla_Fury

laba_6_2_del_v2

May 30th, 2021
547
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 10.38 KB | None | 0 0
  1. unit laba_6_2_f1;
  2.  
  3. interface
  4.  
  5. uses
  6.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  7.         System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  8.         laba_6_2_UnitTypes, Vcl.ExtCtrls, Vcl.Imaging.pngimage, laba_6_2_UnitBoard,
  9.   Vcl.StdCtrls, laba_6_2_UnitKnight, laba_6_2_UnitDoKnightMoves, Vcl.ComCtrls, Math,
  10.   Vcl.Menus;
  11.  
  12. type
  13.   TForm_6_2 = class(TForm)
  14.     ImageDark2: TImage;
  15.     ImageLight2: TImage;
  16.     LabelToMeasureScreenOfUser: TLabel;
  17.     ImageKnight: TImage;
  18.     TimerForKnightMoves: TTimer;
  19.     ImageLight1: TImage;
  20.     ImageDark1: TImage;
  21.     ButtonStart: TButton;
  22.     LabelHelp: TLabel;
  23.     TrackBar1: TTrackBar;
  24.     LabelSpeedOfKnight: TLabel;
  25.     MainMenu1: TMainMenu;
  26.     NHelp: TMenuItem;
  27.     NTask: TMenuItem;
  28.     NAuthor: TMenuItem;
  29.     procedure FormCreate(Sender: TObject);
  30.     procedure TimerForKnightMovesTimer(Sender: TObject);
  31.     procedure ButtonStartClick(Sender: TObject);
  32.     procedure TrackBar1Change(Sender: TObject);
  33.     procedure NTaskClick(Sender: TObject);
  34.     procedure NAuthorClick(Sender: TObject);
  35.   private
  36.     MultPix: Single;
  37.   public
  38.     function MultPixels(PixQuant: Integer): Integer;
  39.  
  40.     procedure CellOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  41.   end;
  42.  
  43. procedure MyMessageBoxInfo(Form: TForm; CaptionWindow, TextMessage: String; IsWarning: Boolean = False); external 'Dll_MyMessageBox.dll';
  44. function MyMessageBoxYesNo(Form: TForm; CaptionWindow, TextMessage: String; IsWarning: Boolean = False) : Boolean; external 'Dll_MyMessageBox.dll';
  45.  
  46. var
  47.     Form_6_2: TForm_6_2;
  48.     Board: TBoard;
  49.     Knight: TKnight;
  50.     KnightIsMoving: Boolean;
  51.  
  52. implementation
  53.  
  54. {$R *.dfm}
  55.  
  56. procedure TForm_6_2.FormCreate(Sender: TObject);
  57. begin
  58.     MultPix := LabelToMeasureScreenOfUser.Width / 100;
  59.     KnightIsMoving := False;
  60.  
  61.     CreateBoard();
  62.     SetKnight();
  63. end;
  64.  
  65. function TForm_6_2.MultPixels(PixQuant: Integer): Integer;
  66. begin
  67.     Result := Round(PixQuant * MultPix);
  68. end;
  69.  
  70. procedure TForm_6_2.NAuthorClick(Sender: TObject);
  71. begin
  72.     MyMessageBoxInfo(Form_6_2, 'Автор', 'Панев Александр, гр. 051007' + #10#13 + 'Минск, 2021');
  73. end;
  74.  
  75. procedure TForm_6_2.NTaskClick(Sender: TObject);
  76. begin
  77.     MyMessageBoxInfo(Form_6_2, 'Задание', 'Обойти шахматную доску ходом коня так, чтобы все клетки были пройдены по одному разу.');
  78. end;
  79.  
  80. procedure TForm_6_2.TimerForKnightMovesTimer(Sender: TObject);
  81. begin
  82.     DoOneMove();
  83. end;
  84.  
  85. procedure TForm_6_2.TrackBar1Change(Sender: TObject);
  86. begin
  87.     TimerForKnightMoves.Interval := 20 * (6 - TrackBar1.Position) * (6 - TrackBar1.Position) * (5 - TrackBar1.Position);
  88.     TimerForKnightMoves.Interval := Min(TimerForKnightMoves.Interval, 1500);
  89.     TimerForKnightMoves.Interval := Max(TimerForKnightMoves.Interval, 20);
  90. end;
  91.  
  92. procedure TForm_6_2.ButtonStartClick(Sender: TObject);
  93. begin
  94.     if KnightIsMoving then
  95.         if ButtonStart.Caption = 'Продолжить' then
  96.         begin
  97.             TimerForKnightMoves.Enabled := True;
  98.             ButtonStart.Caption := 'Остановить'
  99.         end
  100.         else
  101.         begin
  102.             TimerForKnightMoves.Enabled := False;
  103.             ButtonStart.Caption := 'Продолжить'
  104.         end
  105.     else
  106.         StartKnightMoves();
  107. end;
  108.  
  109. procedure TForm_6_2.CellOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  110. begin
  111.     if not KnightIsMoving then
  112.         with Sender as TCell do
  113.             MoveKnightToCell(PosX, PosY);
  114. end;
  115.  
  116. end.
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125. unit laba_6_2_UnitBoard;
  126.  
  127. interface
  128.  
  129. uses laba_6_2_UnitTypes;
  130.  
  131. const
  132.     SizeOfCell = 60;
  133.  
  134. procedure CreateBoard();
  135. procedure ResetBoardAndKnight();
  136.  
  137. implementation
  138.  
  139. uses laba_6_2_f1;
  140.  
  141. procedure CreateBoard();
  142. var
  143.     i, j: Integer;
  144.  
  145. begin
  146.     with Form_6_2 do
  147.     for i := 1 to 8 do
  148.         for j := 1 to 8 do
  149.         begin
  150.             Board[i][j] := TCell.Create(Form_6_2);
  151.             with Board[i][j] do
  152.             begin
  153.                 Parent := Form_6_2;
  154.                 Width := MultPixels(SizeOfCell);
  155.                 Height := Width;
  156.                 Stretch := True;
  157.                 Proportional := True;
  158.                 Top := MultPixels(SizeOfCell) * j;
  159.                 Left := MultPixels(SizeOfCell) * i;
  160.                 PosX := i;
  161.                 PosY := j;
  162.  
  163.                 OnMouseDown := CellOnMouseDown;
  164.             end;
  165.         end;
  166.  
  167.     ResetBoardAndKnight();
  168. end;
  169.  
  170. procedure ResetBoardAndKnight();
  171. var
  172.     i, j: Integer;
  173.  
  174. begin
  175.     for i := 1 to 8 do
  176.         for j := 1 to 8 do
  177.             with Board[i][j] do
  178.             begin
  179.                 SetColor(False);
  180.                 ColorOfNode := 0;
  181.             end;
  182.  
  183.     if Knight <> nil then
  184.         Knight.QuantWalkedCells := 0;
  185. end;
  186.  
  187. end.
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197. unit laba_6_2_UnitDoKnightMoves;
  198.  
  199. interface
  200.  
  201. procedure StartKnightMoves();
  202. procedure DoOneMove();
  203.  
  204. implementation
  205.  
  206. uses laba_6_2_f1, laba_6_2_UnitTypes, laba_6_2_UnitKnight, System.SysUtils, laba_6_2_UnitBoard;
  207.  
  208. function GetMovesFromCell(FromX, FromY: ShortInt) : TArrMoves; forward;
  209. procedure EndKnightMoves(); forward;
  210.  
  211. procedure StartKnightMoves();
  212. begin
  213.     ResetBoardAndKnight();
  214.     KnightIsMoving := True;
  215.  
  216.     with Form_6_2 do
  217.     begin
  218.         ButtonStart.Caption := 'Остановить';
  219.         TimerForKnightMoves.Enabled := True;
  220.         LabelHelp.Visible := False;
  221.     end;
  222. end;
  223.  
  224. procedure EndKnightMoves();
  225. begin
  226.     MyMessageBoxInfo(Form_6_2, 'Готово', 'Путь завершён. Конь посетил ' + IntToStr(Knight.QuantWalkedCells) + ' клетки.');
  227.     KnightIsMoving := False;
  228.     with Form_6_2 do
  229.     begin
  230.         LabelHelp.Visible := True;
  231.         ButtonStart.Caption := 'Начать';
  232.     end;
  233. end;
  234.  
  235. procedure DoOneMove();
  236. var
  237.     ArrMoves: TArrMoves;
  238.     i, QuantOfAvailMoves, MinAvailMoves, IndexOfMin: Byte;
  239.    
  240. begin
  241.     Form_6_2.TimerForKnightMoves.Enabled := False;
  242.  
  243.     with Knight do
  244.         ArrMoves := GetMovesFromCell(PosX, PosY);
  245.  
  246.     if Length(ArrMoves) > 0 then
  247.     begin
  248.         for i := 0 to High(ArrMoves) do
  249.         begin
  250.             with Knight do
  251.                 QuantOfAvailMoves := Length(GetMovesFromCell(PosX + ArrMoves[i][1], PosY + ArrMoves[i][2]));
  252.             if i = 0 then
  253.             begin
  254.                 MinAvailMoves := QuantOfAvailMoves;
  255.                 IndexOfMin := 0;
  256.             end
  257.             else
  258.                 if QuantOfAvailMoves < MinAvailMoves then
  259.                 begin
  260.                     MinAvailMoves := QuantOfAvailMoves;
  261.                     IndexOfMin := i;
  262.                 end;
  263.         end;
  264.  
  265.         with Knight do
  266.             MoveKnightToCell(PosX + ArrMoves[IndexOfMin][1], PosY + ArrMoves[IndexOfMin][2]);
  267.         if Knight.QuantWalkedCells = 64 then
  268.             EndKnightMoves()
  269.         else
  270.             Form_6_2.TimerForKnightMoves.Enabled := True;
  271.     end
  272.     else
  273.     begin
  274.         MyMessageBoxInfo(Form_6_2, 'Ошибка', 'Путь не найден', True);
  275.         EndKnightMoves();
  276.     end;
  277. end;
  278.  
  279. function GetMovesFromCell(FromX, FromY: ShortInt) : TArrMoves;
  280. const
  281.     AllowedMoves: Array [1..8] of TVector = ((-2, 1), (2, -1), (-2, -1), (-1, -2), (2, 1),
  282.       (1, 2), (-1, 2), (1, -2));
  283.  
  284. var
  285.     i, QuantOfMoves: Byte;
  286.     ArrMoves: TArrMoves;
  287.  
  288. begin
  289.     QuantOfMoves := 0;
  290.     SetLength(ArrMoves, 8);
  291.     for i := 1 to 8 do
  292.         if (FromX + AllowedMoves[i][1] < 9) and (FromX + AllowedMoves[i][1] > 0) and
  293.         (FromY + AllowedMoves[i][2] < 9) and
  294.         (FromY + AllowedMoves[i][2] > 0) and
  295.         (Board[FromX + AllowedMoves[i][1]][FromY + AllowedMoves[i][2]].ColorOfNode = 0) then
  296.         begin
  297.             ArrMoves[QuantOfMoves] := AllowedMoves[i];
  298.             Inc(QuantOfMoves);
  299.         end;
  300.  
  301.     SetLength(ArrMoves, QuantOfMoves);
  302.  
  303.     Result := ArrMoves;
  304. end;
  305.  
  306. end.
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320. unit laba_6_2_UnitKnight;
  321.  
  322. interface
  323.  
  324. uses
  325.     laba_6_2_UnitTypes;
  326.  
  327. procedure SetKnight();
  328. procedure MoveKnightToCell(ToX, ToY: Byte);
  329.  
  330. implementation
  331. uses laba_6_2_f1, laba_6_2_UnitBoard;
  332.  
  333. procedure SetKnight();
  334. begin
  335.     with Form_6_2 do
  336.         with Knight do
  337.         begin
  338.             Knight := TKnight.Create(Form_6_2);
  339.             Parent := Form_6_2;
  340.  
  341.             QuantWalkedCells := 0;
  342.  
  343.             Width := Board[1][1].Width;
  344.             Height := Width;
  345.             Picture := ImageKnight.Picture;
  346.             Proportional := True;
  347.             Stretch := True;
  348.  
  349.             MoveKnightToCell(1, 1);
  350.  
  351.             BringToFront();
  352.         end;
  353. end;
  354.  
  355. procedure MoveKnightToCell(ToX, ToY: Byte);
  356. begin
  357.     with Knight do
  358.         begin
  359.             if KnightIsMoving and (QuantWalkedCells = 0) then
  360.             begin
  361.                 Board[PosX][PosY].ColorOfNode := 2;
  362.                 Board[PosX][PosY].SetColor(True);
  363.                 Inc(QuantWalkedCells);
  364.             end;
  365.  
  366.             PosX := ToX;
  367.             PosY := ToY;
  368.             Top := Board[PosX][PosY].Top;
  369.             Left := Board[PosX][PosY].Left;
  370.  
  371.             BringToFront();
  372.  
  373.             if KnightIsMoving then
  374.             begin
  375.                 Board[PosX][PosY].ColorOfNode := 2;
  376.                 Board[PosX][PosY].SetColor(True);
  377.                 Inc(QuantWalkedCells);
  378.             end;
  379.         end;
  380. end;
  381.  
  382. end.
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396. unit laba_6_2_UnitTypes;
  397.  
  398. interface
  399.  
  400. uses Vcl.ExtCtrls, System.Classes, Vcl.Controls;
  401.  
  402. type
  403.     TVector = Array [1..2] of ShortInt;
  404.     TArrMoves = Array of TVector;
  405.  
  406.     TCell = Class(TImage)
  407.     public
  408.         ColorOfNode: Byte;  // 0 - was not ; 1 - temp was; 2 - was
  409.         PosX, PosY: Byte;
  410.     published
  411.         procedure SetColor(IsWalked: Boolean);
  412.     End;
  413.  
  414.     TBoard = Array [1 .. 8, 1 .. 8] of TCell;
  415.  
  416.     TKnight = Class (TImage)
  417.     public
  418.         PosX, PosY, QuantWalkedCells: Byte;
  419.     End;
  420.  
  421. implementation
  422.  
  423. uses laba_6_2_f1, laba_6_2_UnitKnight;
  424.  
  425. procedure TCell.SetColor(IsWalked: Boolean);
  426. begin
  427.     with Form_6_2 do
  428.         if (PosX + PosY) mod 2 = 1 then
  429.             if IsWalked then
  430.                 Picture := ImageDark2.Picture
  431.             else
  432.                 Picture := ImageDark1.Picture
  433.         else
  434.             if IsWalked then
  435.                 Picture := ImageLight2.Picture
  436.             else
  437.                 Picture := ImageLight1.Picture
  438. end;
  439.  
  440. end.
Advertisement
Add Comment
Please, Sign In to add comment