Vanilla_Fury

laba_6_2_del

May 13th, 2021 (edited)
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 10.35 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. unit laba_6_2_UnitBoard;
  124.  
  125. interface
  126.  
  127. uses laba_6_2_UnitTypes;
  128.  
  129. const
  130.     SizeOfCell = 60;
  131.  
  132. procedure CreateBoard();
  133. procedure ResetBoardAndKnight();
  134.  
  135. implementation
  136.  
  137. uses laba_6_2_f1;
  138.  
  139. procedure CreateBoard();
  140. var
  141.     i, j: Integer;
  142.  
  143. begin
  144.     with Form_6_2 do
  145.     for i := 1 to 8 do
  146.         for j := 1 to 8 do
  147.         begin
  148.             Board[i][j] := TCell.Create(Form_6_2);
  149.             with Board[i][j] do
  150.             begin
  151.                 Parent := Form_6_2;
  152.                 Width := MultPixels(SizeOfCell);
  153.                 Height := Width;
  154.                 Stretch := True;
  155.                 Proportional := True;
  156.                 Top := MultPixels(SizeOfCell) * j;
  157.                 Left := MultPixels(SizeOfCell) * i;
  158.                 PosX := i;
  159.                 PosY := j;
  160.  
  161.                 OnMouseDown := CellOnMouseDown;
  162.             end;
  163.         end;
  164.  
  165.     ResetBoardAndKnight();
  166. end;
  167.  
  168. procedure ResetBoardAndKnight();
  169. var
  170.     i, j: Integer;
  171.  
  172. begin
  173.     for i := 1 to 8 do
  174.         for j := 1 to 8 do
  175.             with Board[i][j] do
  176.             begin
  177.                 SetColor(False);
  178.                 ColorOfNode := 0;
  179.             end;
  180.  
  181.     if Knight <> nil then
  182.         Knight.QuantWalkedCells := 0;
  183. end;
  184.  
  185. end.
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192. unit laba_6_2_UnitDoKnightMoves;
  193.  
  194. interface
  195.  
  196. procedure StartKnightMoves();
  197. procedure DoOneMove();
  198.  
  199. implementation
  200.  
  201. uses laba_6_2_f1, laba_6_2_UnitTypes, laba_6_2_UnitKnight, System.SysUtils, laba_6_2_UnitBoard;
  202.  
  203. function GetMovesFromCell(FromX, FromY: ShortInt) : TArrMoves; forward;
  204. procedure EndKnightMoves(); forward;
  205.  
  206. procedure StartKnightMoves();
  207. begin
  208.     ResetBoardAndKnight();
  209.     KnightIsMoving := True;
  210.  
  211.     with Form_6_2 do
  212.     begin
  213.         ButtonStart.Caption := 'Остановить';
  214.         TimerForKnightMoves.Enabled := True;
  215.         LabelHelp.Visible := False;
  216.     end;
  217. end;
  218.  
  219. procedure EndKnightMoves();
  220. begin
  221.     MyMessageBoxInfo(Form_6_2, 'Готово', 'Путь завершён. Конь посетил ' + IntToStr(Knight.QuantWalkedCells) + ' клетки.');
  222.     KnightIsMoving := False;
  223.     with Form_6_2 do
  224.     begin
  225.         LabelHelp.Visible := True;
  226.         ButtonStart.Caption := 'Начать';
  227.     end;
  228. end;
  229.  
  230. procedure DoOneMove();
  231. var
  232.     ArrMoves: TArrMoves;
  233.     i, QuantOfAvailMoves, MinAvailMoves, IndexOfMin: Byte;
  234.    
  235. begin
  236.     Form_6_2.TimerForKnightMoves.Enabled := False;
  237.  
  238.     with Knight do
  239.         ArrMoves := GetMovesFromCell(PosX, PosY);
  240.  
  241.     if Length(ArrMoves) > 0 then
  242.     begin
  243.         for i := 0 to High(ArrMoves) do
  244.         begin
  245.             with Knight do
  246.                 QuantOfAvailMoves := Length(GetMovesFromCell(PosX + ArrMoves[i][1], PosY + ArrMoves[i][2]));
  247.             if i = 0 then
  248.             begin
  249.                 MinAvailMoves := QuantOfAvailMoves;
  250.                 IndexOfMin := 0;
  251.             end
  252.             else
  253.                 if QuantOfAvailMoves < MinAvailMoves then
  254.                 begin
  255.                     MinAvailMoves := QuantOfAvailMoves;
  256.                     IndexOfMin := i;
  257.                 end;
  258.         end;
  259.  
  260.         with Knight do
  261.             MoveKnightToCell(PosX + ArrMoves[IndexOfMin][1], PosY + ArrMoves[IndexOfMin][2]);
  262.         if Knight.QuantWalkedCells = 64 then
  263.             EndKnightMoves()
  264.         else
  265.             Form_6_2.TimerForKnightMoves.Enabled := True;
  266.     end
  267.     else
  268.     begin
  269.         MyMessageBoxInfo(Form_6_2, 'Ошибка', 'Путь не найден', True);
  270.         EndKnightMoves();
  271.     end;
  272. end;
  273.  
  274. function GetMovesFromCell(FromX, FromY: ShortInt) : TArrMoves;
  275. const
  276.     AllowedMoves: Array [1..8] of TVector = ((-2, 1), (2, -1), (-2, -1), (-1, -2), (2, 1),
  277.       (1, 2), (-1, 2), (1, -2));
  278.  
  279. var
  280.     i, QuantOfMoves: Byte;
  281.     ArrMoves: TArrMoves;
  282.  
  283. begin
  284.     QuantOfMoves := 0;
  285.     SetLength(ArrMoves, 8);
  286.     for i := 1 to 8 do
  287.         if (FromX + AllowedMoves[i][1] < 9) and (FromX + AllowedMoves[i][1] > 0) and
  288.         (FromY + AllowedMoves[i][2] < 9) and
  289.         (FromY + AllowedMoves[i][2] > 0) and
  290.         (Board[FromX + AllowedMoves[i][1]][FromY + AllowedMoves[i][2]].ColorOfNode = 0) then
  291.         begin
  292.             ArrMoves[QuantOfMoves] := AllowedMoves[i];
  293.             Inc(QuantOfMoves);
  294.         end;
  295.  
  296.     SetLength(ArrMoves, QuantOfMoves);
  297.  
  298.     Result := ArrMoves;
  299. end;
  300.  
  301. end.
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310. unit laba_6_2_UnitKnight;
  311.  
  312. interface
  313.  
  314. uses
  315.     laba_6_2_UnitTypes;
  316.  
  317. procedure SetKnight();
  318. procedure MoveKnightToCell(ToX, ToY: Byte);
  319.  
  320. implementation
  321. uses laba_6_2_f1, laba_6_2_UnitBoard;
  322.  
  323. procedure SetKnight();
  324. begin
  325.     with Form_6_2 do
  326.         with Knight do
  327.         begin
  328.             Knight := TKnight.Create(Form_6_2);
  329.             Parent := Form_6_2;
  330.  
  331.             QuantWalkedCells := 0;
  332.  
  333.             Width := Board[1][1].Width;
  334.             Height := Width;
  335.             Picture := ImageKnight.Picture;
  336.             Proportional := True;
  337.             Stretch := True;
  338.  
  339.             MoveKnightToCell(1, 1);
  340.  
  341.             BringToFront();
  342.         end;
  343. end;
  344.  
  345. procedure MoveKnightToCell(ToX, ToY: Byte);
  346. begin
  347.     with Knight do
  348.         begin
  349.             if KnightIsMoving and (QuantWalkedCells = 0) then
  350.             begin
  351.                 Board[PosX][PosY].ColorOfNode := 2;
  352.                 Board[PosX][PosY].SetColor(True);
  353.                 Inc(QuantWalkedCells);
  354.             end;
  355.  
  356.             PosX := ToX;
  357.             PosY := ToY;
  358.             Top := Board[PosX][PosY].Top;
  359.             Left := Board[PosX][PosY].Left;
  360.  
  361.             BringToFront();
  362.  
  363.             if KnightIsMoving then
  364.             begin
  365.                 Board[PosX][PosY].ColorOfNode := 2;
  366.                 Board[PosX][PosY].SetColor(True);
  367.                 Inc(QuantWalkedCells);
  368.             end;
  369.         end;
  370. end;
  371.  
  372. end.
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380. unit laba_6_2_UnitTypes;
  381.  
  382. interface
  383.  
  384. uses Vcl.ExtCtrls, System.Classes, Vcl.Controls;
  385.  
  386. type
  387.     TVector = Array [1..2] of ShortInt;
  388.     TArrMoves = Array of TVector;
  389.  
  390.     TCell = Class(TImage)
  391.     public
  392.         ColorOfNode: Byte;  // 0 - was not ; 1 - temp was; 2 - was
  393.         PosX, PosY: Byte;
  394.     published
  395.         procedure SetColor(IsWalked: Boolean);
  396.     End;
  397.  
  398.     TBoard = Array [1 .. 8, 1 .. 8] of TCell;
  399.  
  400.     TKnight = Class (TImage)
  401.     public
  402.         PosX, PosY, QuantWalkedCells: Byte;
  403.     End;
  404.  
  405. implementation
  406.  
  407. uses laba_6_2_f1, laba_6_2_UnitKnight;
  408.  
  409. procedure TCell.SetColor(IsWalked: Boolean);
  410. begin
  411.     with Form_6_2 do
  412.         if (PosX + PosY) mod 2 = 1 then
  413.             if IsWalked then
  414.                 Picture := ImageDark2.Picture
  415.             else
  416.                 Picture := ImageDark1.Picture
  417.         else
  418.             if IsWalked then
  419.                 Picture := ImageLight2.Picture
  420.             else
  421.                 Picture := ImageLight1.Picture
  422. end;
  423.  
  424. end.
  425.  
  426.  
Add Comment
Please, Sign In to add comment