Advertisement
ksyshshot

7.1

Jun 7th, 2023
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 15.47 KB | Source Code | 0 0
  1. Unit UnitMain;
  2.  
  3. Interface
  4.  
  5. Uses
  6.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.     Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus,
  8.     Vcl.Samples.Spin, Vcl.Grids, Vcl.ExtCtrls;
  9.  
  10. Type
  11.     TPoint = Record
  12.         CenterX, CenterY: Integer;
  13.         Color: TColor;
  14.     End;
  15.  
  16.     PQueue = ^TQueue;
  17.     TQueue = Record
  18.         Data: Integer;
  19.         Next: PQueue;
  20.     End;
  21.  
  22.     TBoolArr = Array of Boolean;
  23.     TMatrix = Array of Array of Integer;
  24.     TPointsArr = Array of TPoint;
  25.  
  26.     TFormMain = class(TForm)
  27.         HeaderLabel: TLabel;
  28.         MainMenu: TMainMenu;
  29.         FileMenu: TMenuItem;
  30.         OpenFileMenu: TMenuItem;
  31.         SaveToFileBFSMenu: TMenuItem;
  32.         InfoAboutDeveloper: TMenuItem;
  33.         TaskInfo: TMenuItem;
  34.         SaveToFile: TSaveDialog;
  35.         OpenFromFile: TOpenDialog;
  36.         AskLabel: TLabel;
  37.         VerticeEdit: TSpinEdit;
  38.         MatrixLabel: TLabel;
  39.         sgMatrix: TStringGrid;
  40.         StartPointEdit: TSpinEdit;
  41.         StartButton: TButton;
  42.         VisualButton: TButton;
  43.         BFSLabel: TLabel;
  44.         FromLabel: TLabel;
  45.     OrderLabel: TLabel;
  46.         Procedure FormCreate(Sender: TObject);
  47.         Procedure VerticeEditChange(Sender: TObject);
  48.         Procedure sgMatrixKeyPress(Sender: TObject; Var Key: Char);
  49.         Procedure sgMatrixSetEditText(Sender: TObject; ACol, ARow: Integer; Const Value: String);
  50.         Procedure StartButtonClick(Sender: TObject);
  51.         Procedure StartPointEditChange(Sender: TObject);
  52.         Procedure VisualButtonClick(Sender: TObject);
  53.         Procedure OpenFileMenuClick(Sender: TObject);
  54.         Procedure SaveToFileBFSMenuClick(Sender: TObject);
  55.         Procedure InfoAboutDeveloperClick(Sender: TObject);
  56.         Procedure TaskInfoClick(Sender: TObject);
  57.         Procedure FormCloseQuery(Sender: TObject; Var CanClose: Boolean);
  58.     Private
  59.         { Private declarations }
  60.         Function CreateMatrix(): TMatrix;
  61.         Function CheckFull(): Boolean;
  62.     Public
  63.         { Public declarations }
  64.     End;
  65.  
  66. Var
  67.     FormMain: TFormMain;
  68.     Head, Tail: PQueue;
  69.  
  70. Implementation
  71.  
  72. {$R *.dfm}
  73.  
  74. Uses
  75.     UnitVisualisation, UnitAbout, UnitExit, UnitInstruction_7_1, UnitError;
  76.  
  77. Const
  78.     StartX = 300;
  79.     StartY = 300;
  80.     AreaRadius = 200;
  81.     NodeRadius = 40;
  82.  
  83. Procedure AddToQueue(Value: Integer);
  84. Var
  85.     PElem, Last: PQueue;
  86. Begin
  87.     New(PElem);
  88.     PElem^.Data := Value;
  89.     PElem^.Next := Nil;
  90.     If (Head = Nil) then
  91.     Begin
  92.         Head := PElem;
  93.     End;
  94.     If (Tail <> Nil) then
  95.     Begin
  96.         Last := Tail;
  97.         Tail := PElem;
  98.         Last^.Next := PElem;
  99.     End;
  100.     Tail := PElem;
  101. End;
  102.  
  103. Procedure RemoveFromQueue();
  104. Var
  105.     PElem: PQueue;
  106. Begin
  107.     PElem := Head;
  108.     If (PElem^.Next = Nil) then
  109.     Begin
  110.         Tail := Nil;
  111.         Head := Nil;
  112.     End
  113.     Else
  114.         Head :=  PElem^.Next;
  115.     Dispose(PElem);
  116. End;
  117.  
  118. Function BFSGraph(Matrix: TMatrix; N: Integer; StartPoint: Integer; Var Output: String): TPointsArr;
  119. Var
  120.     BoolArr: TBoolArr;
  121.     ResultArr: TPointsArr;
  122.     Color: TColor;
  123.     I: Integer;
  124. Begin
  125.     Color := RGB(0,255,255);
  126.     SetLength(BoolArr, N);
  127.     SetLength(ResultArr, N);
  128.     For I := 0 to High(BoolArr) do
  129.         BoolArr[I] := False;
  130.     AddToQueue(StartPoint - 1);
  131.     BoolArr[StartPoint - 1] := True;
  132.     While (Head <> Nil) do
  133.     Begin
  134.         Output := Output + IntToStr(Head^.Data + 1) + ' ';
  135.         ResultArr[Head^.Data].Color := Color;
  136.         Color := Color - RGB(0,17,17);
  137.         For I := 0 to (N - 1) do
  138.         Begin
  139.             If (Not BoolArr[I]) and (Matrix[Head^.Data, I] = 1) then
  140.             Begin
  141.                 AddToQueue(I);
  142.                 BoolArr[I] := True;
  143.             End;
  144.         End;
  145.         RemoveFromQueue();
  146.     End;
  147.     Result := ResultArr;
  148. End;
  149.  
  150. Procedure DrawGraph(Canvas: TCanvas; N: Integer; Matrix: TMatrix; Var PointsArr: TPointsArr);
  151. Var
  152.     Alfa: Real;
  153.     I, J: Integer;
  154.     CenterX, CenterY: Integer;
  155.     Str: String;
  156. Begin
  157.     Alfa := 2*Pi/N;
  158.     With Canvas do
  159.     Begin
  160.         Font.Color := clWhite;
  161.         Font.Size := 12;
  162.         Font.Style := [fsBold];
  163.  
  164.         For I := 0 to (N - 1) do
  165.         Begin
  166.             CenterX := Round(AreaRadius * Sin(Alfa * I)) + StartX;
  167.             CenterY := Round(AreaRadius * Cos(Alfa * I)) + StartY;
  168.             PointsArr[I].CenterX := CenterX;
  169.             PointsArr[I].CenterY := CenterY;
  170.         End;
  171.  
  172.         Pen.Color := clBlack;
  173.         Pen.Width := 3;
  174.         For I := 0 to (N - 2) do
  175.         Begin
  176.             For J := I to (N - 1) do
  177.             Begin
  178.                 If (Matrix[I, J] = 1) then
  179.                 Begin
  180.                     MoveTo(PointsArr[I].CenterX, PointsArr[I].CenterY);
  181.                     LineTo(PointsArr[J].CenterX, PointsArr[J].CenterY);
  182.                 End;
  183.             End;
  184.         End;
  185.         For I := 0 to (N - 1) do
  186.         Begin
  187.             Brush.Color := PointsArr[I].Color;
  188.             Ellipse(PointsArr[I].CenterX - NodeRadius div 2,
  189.                         PointsArr[I].CenterY - NodeRadius div 2, PointsArr[I].CenterX + NodeRadius div 2,
  190.                         PointsArr[I].CenterY + NodeRadius div 2);
  191.             Str := IntToStr(I + 1);
  192.             TextOut(PointsArr[I].CenterX - (TextWidth(Str) div 2), PointsArr[I].CenterY - (TextHeight(Str) div 2), Str);
  193.         End;
  194.     End;
  195.  
  196. End;
  197.  
  198. Procedure TFormMain.StartButtonClick(Sender: TObject);
  199. Var
  200.     Output: String;
  201.     Matrix: TMatrix;
  202.     ResultArr: TPointsArr;
  203.     N: Integer;
  204. Begin
  205.     Matrix := CreateMatrix();
  206.     N := VerticeEdit.Value;
  207.     ResultArr := BFSGraph(Matrix, N, StartPointEdit.Value, Output);
  208.     BFSLabel.Caption := Output;
  209.     VisualButton.Enabled := True;
  210.     SaveToFileBFSMenu.Enabled := True;
  211. End;
  212.  
  213. Procedure TFormMain.VisualButtonClick(Sender: TObject);
  214. Var
  215.     ResultArr: TPointsArr;
  216.     Matrix: TMatrix;
  217.     N: Integer;
  218.     Output: String;
  219.     Visual: TFormVisualisation;
  220. Begin
  221.     Matrix := CreateMatrix();
  222.     N := VerticeEdit.Value;
  223.     ResultArr := BFSGraph(Matrix, N, StartPointEdit.Value, Output);
  224.     Try
  225.         Visual := TFormVisualisation.Create(Self);
  226.         DrawGraph(Visual.PaintArea.Canvas, VerticeEdit.Value, Matrix, ResultArr);
  227.         Visual.ShowModal();
  228.     Finally
  229.         Visual.Free();
  230.     End;
  231. End;
  232.  
  233. Function IsFileCorrect(Path: String): Boolean;
  234. Var
  235.     FileToCheck: TextFile;
  236.     N: Integer;
  237.     IsCorrect: Boolean;
  238.     Null: String;
  239. Begin
  240.     AssignFile(FileToCheck, Path);
  241.     Reset(FileToCheck);
  242.     IsCorrect := True;
  243.     Try
  244.         Readln(FileToCheck, N);
  245.         Readln(FileToCheck, Null);
  246.     Except
  247.         IsCorrect := False;
  248.     End;
  249.     If (N < 1) or (N > 15) then
  250.     Begin
  251.         IsCorrect := False;
  252.     End;
  253.     If (Null = '') then
  254.         IsCorrect := False;
  255.     CloseFile(FileToCheck);
  256.     IsFileCorrect := IsCorrect;
  257. End;
  258.  
  259. Function CheckFileMatrix(Matrix: TMatrix; N: Integer): Boolean;
  260. Var
  261.     I, J: Integer;
  262.     IsCorrect: Boolean;
  263. Begin
  264.     IsCorrect := True;
  265.     I := 0;
  266.     While ((IsCorrect) and (I < N)) do
  267.     Begin
  268.         J := 0;
  269.         While ((IsCorrect) and (J < N)) do
  270.         Begin
  271.             If (I = J) and (Matrix[I][J] = 1) then
  272.                 IsCorrect := False
  273.             Else If (I <> J) and (Matrix[I][J] <> 0) and (Matrix[I][J] <> 1) then
  274.                 IsCorrect := False;
  275.             Inc(J);
  276.         End;
  277.         Inc(I);
  278.     End;
  279.     Result := IsCorrect;
  280. End;
  281.  
  282. Function GetMatrixFromFile(Path: String; N: Integer; Var IsCorrect: Boolean): TMatrix;
  283. Var
  284.     I, J: Integer;
  285.     InputFile: TextFile;
  286.     Matrix: TMatrix;
  287. Begin
  288.     SetLength(Matrix, N, N);
  289.     I := 0;
  290.     AssignFile(InputFile, Path);
  291.     Reset(InputFile);
  292.     Readln(InputFile);
  293.     While ((IsCorrect) and (I < N)) do
  294.     Begin
  295.         J := 0;
  296.         While ((IsCorrect) and (J < N)) do
  297.         Begin
  298.             Try
  299.                 Read(InputFile, Matrix[I, J]);
  300.             Except
  301.                 IsCorrect := False;
  302.             End;
  303.             Inc(J);
  304.         End;
  305.         Inc(I);
  306.     End;
  307.     If (IsCorrect) then
  308.         IsCorrect := CheckFileMatrix(Matrix, N);
  309.     CloseFile(InputFile);
  310.     GetMatrixFromFile := Matrix;
  311. End;
  312.  
  313. Procedure GetDataFromFile(Path: String; Var N: Integer; Var Matrix: TMatrix;
  314.   Var IsCorrect: Boolean);
  315. Var
  316.     InputFile: TextFile;
  317.     Null: String;
  318.     I: Integer;
  319. Begin
  320.     IsCorrect := True;
  321.     Try
  322.         AssignFile(InputFile, Path);
  323.         Reset(InputFile);
  324.     Except
  325.         UnitError.FormError.LabelError.Caption := 'Ошибка получения данных из файла!';
  326.         UnitError.FormError.ShowModal;
  327.         UnitError.FormError.LabelError.Caption := '';
  328.     End;
  329.     If (IsCorrect) then
  330.     Begin
  331.         Try
  332.             Reset(InputFile);
  333.             Readln(InputFile, N);
  334.         Except
  335.             IsCorrect := False;
  336.         End;
  337.     End;
  338.     If (IsCorrect) then
  339.         Matrix := GetMatrixFromFile(Path, N, IsCorrect);
  340. End;
  341.  
  342. Procedure TFormMain.OpenFileMenuClick(Sender: TObject);
  343. Var
  344.     N: Integer;
  345.     I, J: Integer;
  346.     IsCorrect: Boolean;
  347.     Matrix: TMatrix;
  348. Begin
  349.     If OpenFromFile.Execute() Then
  350.         If IsFileCorrect(OpenFromFile.FileName) Then
  351.         Begin
  352.             GetDataFromFile(OpenFromFile.FileName, N, Matrix, IsCorrect);
  353.             If (IsCorrect) Then
  354.             Begin
  355.                 BFSLabel.Caption := '';
  356.                 StartButton.Enabled := True;
  357.                 VerticeEdit.Value := N;
  358.                 sgMatrix.ColCount := VerticeEdit.Value + 1;
  359.                 sgMatrix.RowCount := VerticeEdit.Value + 1;
  360.                 For I := 2 to N do
  361.                     sgMatrix.Cells[0, I] := '  ' + IntToStr(I);
  362.                 For J := 2 to N do
  363.                     sgMatrix.Cells[J, 0] := '  ' + IntToStr(J);
  364.                 For I := 1 to N do
  365.                 Begin
  366.                     For J := 1 to N do
  367.                     Begin
  368.                         sgMatrix.Cells[J, I] := IntToStr(Matrix[J - 1, I - 1]);
  369.                     End;
  370.                 End;
  371.                 If (CheckFull()) then
  372.                 Begin
  373.                     StartButton.Enabled := True;
  374.                 End
  375.                 Else
  376.                 Begin
  377.                     StartButton.Enabled := False;
  378.                 End;
  379.                 SaveToFileBFSMenu.Enabled := False;
  380.             End
  381.             Else
  382.             Begin
  383.                 UnitError.FormError.LabelError.Caption := 'Ошибка получения данных из файла!';
  384.                 UnitError.FormError.ShowModal;
  385.                 UnitError.FormError.LabelError.Caption := '';
  386.             End;
  387.         End
  388.         Else
  389.         Begin
  390.             UnitError.FormError.LabelError.Caption := 'Ошибка получения данных из файла!';
  391.             UnitError.FormError.ShowModal;
  392.             UnitError.FormError.LabelError.Caption := '';
  393.         End;
  394. End;
  395.  
  396. Procedure TFormMain.SaveToFileBFSMenuClick(Sender: TObject);
  397. Var
  398.     OutputFile: TextFile;
  399.     I, J, N: Integer;
  400.     S: String;
  401. Begin
  402.     If ((SaveToFile.Execute()) and FileExists(SaveToFile.FileName)) then
  403.     Begin
  404.         AssignFile(OutputFile, SaveToFile.FileName);
  405.         Try
  406.             Rewrite(OutputFile);
  407.         Except
  408.             UnitError.FormError.LabelError.Caption := 'Ошибка доступа к файлу!';
  409.             UnitError.FormError.ShowModal;
  410.             UnitError.FormError.LabelError.Caption := '';
  411.         End;
  412.         N := VerticeEdit.Value;
  413.         Writeln(OutputFile,'Количество вершин в графе:  ', N);
  414.         Writeln(OutputFile,'Матрица смежности: ');
  415.         For I := 1 to N do
  416.         Begin
  417.             For J := 1 to N do
  418.             Begin
  419.                 Write(OutputFile, sgMatrix.Cells[J, I],' ');
  420.             End;
  421.             Writeln(OutputFile);
  422.         End;
  423.         S := 'Обход графа в ширину: ' + BFSLabel.Caption;
  424.         Writeln(OutputFile, S);
  425.         CloseFile(OutputFile);
  426.     End
  427. End;
  428.  
  429. Function TFormMain.CreateMatrix(): TMatrix;
  430. Var
  431.     Matrix: TMatrix;
  432.     N, I, J: Integer;
  433. Begin
  434.     N := VerticeEdit.Value;
  435.     SetLength(Matrix, N, N);
  436.     For I := 0 to (N - 1) do
  437.         For J := 0 to (N - 1) do
  438.         Begin
  439.             Matrix[I, J] := StrToInt(sgMatrix.Cells[J + 1, I + 1]);
  440.         End;
  441.     Result := Matrix;
  442. End;
  443.  
  444. Function TFormMain.CheckFull: Boolean;
  445. Var
  446.     I, J: Integer;
  447.     IsFull: Boolean;
  448. Begin
  449.     IsFull := True;
  450.     For I := 1 to VerticeEdit.Value do
  451.     Begin
  452.         For J := 1 to VerticeEdit.Value do
  453.         Begin
  454.             If (sgMatrix.Cells[J,I] = '') then
  455.                 IsFull := False;
  456.         End;
  457.     End;
  458.     Result := IsFull;
  459. End;
  460.  
  461. Procedure TFormMain.VerticeEditChange(Sender: TObject);
  462. Var
  463.     I, J: Integer;
  464. Begin
  465.     sgMatrix.ColCount := VerticeEdit.Value + 1;
  466.     sgMatrix.RowCount := VerticeEdit.Value + 1;
  467.     sgMatrix.Cells[VerticeEdit.Value,0] := '  ' + IntToStr(VerticeEdit.Value);
  468.     sgMatrix.Cells[0,VerticeEdit.Value] := '  ' + IntToStr(VerticeEdit.Value);
  469.     sgMatrix.Cells[VerticeEdit.Value, VerticeEdit.Value] := '0';
  470.     For I := 1 to VerticeEdit.Value do
  471.     Begin
  472.         sgMatrix.Cells[VerticeEdit.Value + 1, I] := '';
  473.     End;
  474.     For J := 1 to VerticeEdit.Value do
  475.     Begin
  476.         sgMatrix.Cells[J, VerticeEdit.Value + 1] := '';
  477.     End;
  478.     sgMatrix.Cells[VerticeEdit.Value + 1, VerticeEdit.Value + 1] := '';
  479.     SaveToFileBFSMenu.Enabled := False;
  480.     StartPointEdit.MaxValue := VerticeEdit.Value;
  481.     If (StartPointEdit.Value > VerticeEdit.Value) then
  482.         StartPointEdit.Value := VerticeEdit.Value;
  483.     If CheckFull then
  484.     Begin
  485.         StartButton.Enabled := True;
  486.     End
  487.     Else
  488.     Begin
  489.         StartButton.Enabled := False;
  490.     End;
  491.     VisualButton.Enabled := False;
  492.  
  493.     BFSLabel.Caption := '';
  494. End;
  495.  
  496. Procedure TFormMain.StartPointEditChange(Sender: TObject);
  497. Begin
  498.     If (StartPointEdit.Value > VerticeEdit.Value) then
  499.         StartPointEdit.Value := VerticeEdit.Value;
  500.     BFSLabel.Caption := '';
  501.     VisualButton.Enabled := False;
  502.     SaveToFileBFSMenu.Enabled := False;
  503. End;
  504.  
  505. Procedure TFormMain.FormCreate(Sender: TObject);
  506. Begin
  507.     sgMatrix.Cells[1,0] := '  1';
  508.     sgMatrix.Cells[0,1] := '  1';
  509.     sgMatrix.Cells[1,1] := '0';
  510.     Head := Nil;
  511.     Tail := Nil;
  512. End;
  513.  
  514. Procedure TFormMain.sgMatrixKeyPress(Sender: TObject; var Key: Char);
  515. Var
  516.     C, R: Byte;
  517. Begin
  518.     C := sgMatrix.Col;
  519.     R := sgMatrix.Row;
  520.     If Not (Key in ['0','1', #08]) then
  521.         Key := #0;
  522.     If (Length(sgMatrix.Cells[C, R]) = 1) and (Key <> #08) then
  523.         Key := #0;
  524.     If (C = R) then
  525.         Key := #0;
  526. End;
  527.  
  528. Procedure TFormMain.sgMatrixSetEditText(Sender: TObject; ACol, ARow: Integer; Const Value: String);
  529. Begin
  530.     If (ACol <> ARow) then
  531.         sgMatrix.Cells[ARow, ACol] := Value;
  532.     If CheckFull then
  533.     Begin
  534.         StartButton.Enabled := True;
  535.     End
  536.     Else
  537.     Begin
  538.         StartButton.Enabled := False;
  539.     End;
  540.     BFSLabel.Caption := '';
  541.     VisualButton.Enabled := False;
  542.     SaveToFileBFSMenu.Enabled := False;
  543. End;
  544.  
  545. Procedure TFormMain.InfoAboutDeveloperClick(Sender: TObject);
  546. Begin
  547.     UnitAbout.FormAbout.ShowModal;
  548. End;
  549.  
  550. Procedure TFormMain.TaskInfoClick(Sender: TObject);
  551. Begin
  552.     UnitInstruction_7_1.FormInstruction.ShowModal;
  553. End;
  554.  
  555. Procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  556. Begin
  557.     CanClose := UnitExit.FormExit.ShowModal = mrOk;
  558. End;
  559.  
  560. End.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement