{"id":318786,"date":"2021-03-01T03:00:13","date_gmt":"2021-03-01T03:00:13","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=318786"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=318786","title":{"rendered":"\u0417\u043c\u0435\u0439\u043a\u0430, \u043c\u044b\u0448\u044c \u0438 \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\u0414\u043e\u0431\u0440\u044b\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0443\u0447\u0438\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0438\u0433\u0440\u0430\u0442\u044c \u0432 \u0437\u043c\u0435\u0439\u043a\u0443.<\/p>\n<p>  \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u043a\u0443. \u0421\u043a\u0430\u0436\u0435\u043c \u0442\u0430\u043a \u0440\u0430\u0437\u043c\u0438\u043d\u043e\u0447\u043d\u0430\u044f, \u043f\u0435\u0440\u0435\u0434 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0431\u043e\u0435\u043c.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xo\/ex\/ma\/xoexmae9mrj2ec2zqoi2ttc0i3w.jpeg\"><\/div>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0421 \u0447\u0435\u0433\u043e \u0432\u0441\u0451 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c<\/h2>\n<p>  \u0414\u0430\u0431\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u043a\u0440\u043e\u0432\u0435\u043d\u043d\u044b\u043c, \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0441 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0432\u0438\u0434\u0435\u043e \u0447\u0443\u0432\u0430\u043a\u0430 \u0438\u0437 \u0410\u0432\u0441\u0442\u0440\u0430\u043b\u0438 \u0438\u043c\u0435\u043d\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0435\u0431\u044f &quot;<a href=\"https:\/\/www.youtube.com\/channel\/UC0e3QhIYukixgh5VVpKHH9Q\" rel=\"nofollow noopener noreferrer\">Code Bullet<\/a>&quot;<br \/>  \u041e\u043d \u0432 \u043d\u0435\u043c \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0448\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 AI \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0438\u0433\u0440\u0443 \u0432 \u0437\u043c\u0435\u0439\u043a\u0443.<br \/>  \u0423 \u043d\u0435\u0433\u043e \u0442\u043e\u043b\u043a\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0438 \u0432\u043e\u0442 \u043f\u043e\u0447\u0435\u043c\u0443\u2026 \u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e AI \u0440\u0435\u0448\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0432\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043b\u0438\u0431\u043e \u041a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043b\u0438\u0431\u043e \u0420\u0435\u0433\u0440\u0435\u0441\u0441\u0438\u0438 (\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u044f). \u0410 \u0432\u043e\u0442 \u0437\u043c\u0435\u0439\u043a\u0430 \u043d\u0438 \u0442\u0443\u0434\u0430 \u043d\u0438 \u0442\u0443\u0434\u0430 \u043d\u0435 \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u0418\u0431\u043e \u0438\u0434\u0435\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u044a\u0435\u0441\u0442\u044c \u043c\u044b\u0448\u044c \u2013 \u044d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e, \u0430 \u0432\u0440\u0435\u0437\u0430\u0442\u044c\u0441\u044f \u2014 \u043f\u043b\u043e\u0445\u043e. \u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431 \u0445\u0432\u043e\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0441\u0442\u0435\u0442 \u0438 \u0440\u0430\u0441\u0442\u0435\u0442 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0439\u043c\u0435\u0442 \u0432\u0441\u0451 \u043f\u043e\u043b\u0435. \u0422\u0430\u043a \u0432\u043e\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0441\u0430\u043c\u043e\u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0439 AI \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u2013 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043a\u043e\u043b\u044c\u043d\u043e\u0439 \u0438\u0434\u0435\u0439, \u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u043c\u044f\u0442\u044c\u0441\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0448\u0430\u043b \u0431\u044b \u0437\u0430\u0434\u0430\u0447\u043a\u0443 \u0432 \u043b\u043e\u0431, \u0431\u0435\u0437 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e \u0442\u0430\u043a\u043e\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0435 \u0438 \u043f\u043e\u0439\u0434\u0451\u0442 \u0440\u0435\u0447\u044c.<\/p>\n<p>  \u041f.\u0421. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u043b\u0438\u043a\u0438\u0445 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0439, \u0441\u043a\u043e\u0440\u0435\u0435 \u00ab\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043d\u044b\u0435\u00bb \u0438\u0434\u0435\u0438 \u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u0438 \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u0437\u044f\u043b\u043e\u0441\u044c.<\/p>\n<h2>\u041f\u0438\u0448\u0435\u043c \u0438\u0433\u0440\u0443<\/h2>\n<p>  \u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a, \u0438\u0433\u0440\u0430\u0442\u044c, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0430\u043c\u0443 \u0438\u0433\u0440\u0443. <\/p>\n<p>  \u0412\u0441\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0437\u043c\u0435\u0439\u043a\u0443 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435, \u0430 \u0438\u043d\u0444\u043e\u0439 \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 WebSocket (SignalR).<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0421\u043a\u0443\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/b>                         <\/p>\n<div class=\"spoiler_text\">\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c Store \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0437\u043c\u0435\u0438 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0435 \u043f\u043e\u043b\u044f \u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0438\u0433\u0440\u044b.<\/p>\n<pre><code class=\"javascript\">    isLife: boolean,     isWin: boolean,     xSize: number,     ySize: number,     mouse: Vector2,     piton: Vector2[]<\/code><\/pre>\n<p>  snake.ts<\/p>\n<pre><code class=\"javascript\">import { HubConnection, HubConnectionBuilder } from &quot;@microsoft\/signalr&quot;; import { observable } from &quot;mobx&quot;; import { start } from &quot;repl&quot;;  export enum Cell {     None = &quot;None&quot;,     Mouse = &quot;Mouse&quot;,     Snake = &quot;Snake&quot; }  export interface Vector2 {     x: number,     y: number }  interface StateBoard {     isLife: boolean,     isWin: boolean,     xSize: number,     ySize: number,     mouse: Vector2,     piton: Vector2[]     hamiltonPath: Vector2[] }  class Snake {     @observable     public state?: StateBoard;      private connection: HubConnection;      constructor() {         this.connection = new HubConnectionBuilder()             .withUrl(&quot;http:\/\/localhost:5000\/snake&quot;)             .withAutomaticReconnect()             .build();         this.start();     }      private start = async () =&gt; {         await this.connection.start();         this.connection.on(&quot;newState&quot;, (board: string) =&gt; {             var state = JSON.parse(board) as StateBoard;             if (state.isLife) {                 this.state = state;             } else {                 this.state!.isLife = false;                 this.state!.isWin = state.isWin;                 if (this.state!.isWin) {                     this.state = state;                 }             }         });     } } export const snake = new Snake();<\/code><\/pre>\n<p>  \u0418 React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u0440\u0438\u0441\u0443\u0435\u0442.<\/p>\n<p>  App.tsx<\/p>\n<pre><code class=\"javascript\">import { snake } from '.\/shores\/snake'; import { useObserver } from 'mobx-react-lite'; import cs from 'classnames';  const App = (): JSX.Element =&gt; {    const cellRender = (indexRow: number, indexColumn: number): JSX.Element =&gt; {     const state = snake.state!;     const isMouse = state.mouse.x == indexColumn &amp;&amp; state.mouse.y == indexRow;     if (isMouse) {       return &lt;div key={`${indexRow}_${indexColumn}`} className='cell mouse'&gt;&lt;\/div&gt;;     }     const indexCellSnake = state.piton.findIndex(p =&gt; p.x == indexColumn &amp;&amp; p.y == indexRow);     if (indexCellSnake == -1) {       return &lt;div key={`${indexRow}_${indexColumn}`} className='cell'&gt;&lt;\/div&gt;;     }     const prewIndexCellSnake = indexCellSnake - 1;     const prewCellPiton = 0 &lt;= prewIndexCellSnake ? state.piton[prewIndexCellSnake] : null;     const cellPiton = state.piton[indexCellSnake];     const nextIndexCellSnake = indexCellSnake + 1;     const nextCellPiton = nextIndexCellSnake &lt; state.piton.length ? state.piton[nextIndexCellSnake] : null;     let up = false, left = false, down = false, rigth = false;     if (!!prewCellPiton) {       if (prewCellPiton.x &lt; cellPiton.x) {         left = true;       }       if (prewCellPiton.y &lt; cellPiton.y) {         up = true;       }       if (cellPiton.x &lt; prewCellPiton.x) {         rigth = true;       }       if (cellPiton.y &lt; prewCellPiton.y) {         down = true;       }     }     if (!!nextCellPiton) {       if (cellPiton.x &lt; nextCellPiton.x) {         rigth = true;       }       if (cellPiton.y &lt; nextCellPiton.y) {         down = true;       }       if (nextCellPiton.x &lt; cellPiton.x) {         left = true;       }       if (nextCellPiton.y &lt; cellPiton.y) {         up = true;       }     }     return &lt;div key={`${indexRow}_${indexColumn}`} className='cell'&gt;       &lt;table className='shake'&gt;         &lt;tbody&gt;           &lt;tr&gt;             &lt;td width=&quot;10%&quot; height=&quot;10%&quot; \/&gt;             &lt;td height=&quot;10%&quot; className={cs({               'shake-segment': up             })} \/&gt;             &lt;td width=&quot;10%&quot; height=&quot;10%&quot; \/&gt;           &lt;\/tr&gt;           &lt;tr&gt;             &lt;td width=&quot;10%&quot; className={cs({               'shake-segment': left             })} \/&gt;             &lt;td className='shake-segment' \/&gt;             &lt;td width=&quot;10%&quot; className={cs({               'shake-segment': rigth             })} \/&gt;           &lt;\/tr&gt;           &lt;tr&gt;             &lt;td width=&quot;10%&quot; height=&quot;10%&quot; \/&gt;             &lt;td height=&quot;10%&quot; className={cs({               'shake-segment': down             })} \/&gt;             &lt;td width=&quot;10%&quot; height=&quot;10%&quot; \/&gt;           &lt;\/tr&gt;         &lt;\/tbody&gt;       &lt;\/table&gt;     &lt;\/div&gt;;   }    const rowRender = (indexRow: number): JSX.Element =&gt; {     const state = snake.state!;     const cells: JSX.Element[] = [];     for (let j = 0; j &lt; state.ySize; j++) {       cells.push(cellRender(indexRow, j));     }     return (&lt;&gt;{cells}&lt;\/&gt;);   }    const tableRender = (): JSX.Element =&gt; {     const state = snake.state!;     const rows: JSX.Element[] = [];     for (let i = 0; i &lt; state.ySize; i++) {       rows.push(         (&lt;div key={i.toString()} className=&quot;row&quot;&gt;           {rowRender(i)}         &lt;\/div&gt;)       );     }     return (&lt;&gt;{rows}&lt;\/&gt;);   }    return useObserver(() =&gt; {     console.log(snake.state);     if (!snake.state) {       return &lt;div \/&gt;     }     let state: string = &quot;\u0438\u0434\u0435\u0442 \u0438\u0433\u0440\u0430&quot;;     if (snake.state.isLife == false) {       state = snake.state.isWin ? &quot;\u041f\u043e\u0431\u0435\u0434\u0430&quot; : &quot;\u041f\u043e\u0440\u0430\u0436\u0435\u043d\u0438\u0435&quot;     }     return (&lt;&gt;       &lt;span className=&quot;state&quot;&gt;{state}&lt;\/span&gt;       &lt;div className=&quot;table&quot;&gt;         {tableRender()}       &lt;\/div&gt;     &lt;\/&gt;);   }); }  export default App;<\/code><\/pre>\n<p>  \u0421 \u0431\u0435\u043a\u043e\u043c \u0442\u043e\u0436\u0435 \u043c\u0443\u0434\u0440\u0438\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c:<\/p>\n<pre><code class=\"cs\">    public class SnakeSender     {         class Vector2         {             public int X { get; set; }             public int Y { get; set; }             public Vector2(int x, int y)             {                 this.X = x;                 this.Y = y;             }         }          class Vector2Comparer : IEqualityComparer&lt;Vector2&gt;         {             public bool Equals([AllowNull] Vector2 value1, [AllowNull] Vector2 value2)             {                 return value1.X == value2.X &amp;&amp; value1.Y == value2.Y;             }              public int GetHashCode([DisallowNull] Vector2 obj)             {                 return 0;             }         }          private readonly static Vector2Comparer vector2Comparer = new Vector2Comparer();           [JsonConverter(typeof(StringEnumConverter))]         enum Cell         {             None,             Mouse,             Snake         }          enum Directions         {             Up,             Left,             Down,             Rigth         }          class StateBoard         {             public bool IsLife { get; set; }             public bool IsWin { get; set; }             public int XSize { get; set; }             public int YSize { get; set; }             public Vector2 Mouse { get; set; }             public List&lt;Vector2&gt; Piton { get; set; }             public List&lt;Vector2&gt; HamiltonPath { get; set; }         }          const int xSize = 12, ySize = 12;        ... private void CheckDead()         {             Vector2 head = this.Piton.Last();             if (head.X &lt; 0              || head.Y &lt; 0              || xSize &lt;= head.X              || ySize &lt;= head.Y              || this.Piton.SkipLast(1).Contains(head, vector2Comparer))             {                 this.IsLife = false;                 this.IsWin = false;                 return;             }         }  private void Render()         {             var hubContext = (IHubContext&lt;SnakeHub&gt;)this.ServiceProvider.GetService(typeof(IHubContext&lt;SnakeHub&gt;));             var piton = this.Piton.ToList();             piton.Reverse();             hubContext.Clients?.All.SendAsync(&quot;newState&quot;, JsonConvert.SerializeObject(new StateBoard()             {                 IsLife = this.IsLife,                 IsWin = this.IsWin,                 XSize = xSize,                 YSize = ySize,                 Mouse = this.Mouse,                 Piton = piton,                 HamiltonPath = HamiltonPath             }));         } private List&lt;Vector2&gt; GetEmptyCells()         {             List&lt;Vector2&gt; emptyCells = new List&lt;Vector2&gt;(xSize * ySize);             for (int i = 0; i &lt; ySize; i++)             {                 for (int j = 0; j &lt; xSize; j++)                 {                     if (!this.Piton.Contains(new Vector2(j, i), vector2Comparer))                     {                         emptyCells.Add(new Vector2(j, i));                     }                 }             }              return emptyCells;         } }<\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u0438\u0433\u0440\u044b \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u0430 \u043a\u0440\u0430\u0441\u043d\u0430\u044f \u043c\u044b\u0448\u044c \u0438 \u043e\u0434\u043d\u043e\u043a\u043b\u0435\u0442\u043e\u0447\u043d\u0430\u044f \u0437\u043c\u0435\u044f.<\/p>\n<p>  \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c, \u043a\u0430\u043a-\u0442\u043e \u043d\u0430\u0434\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0433\u0440\u0430\u0442\u044c.<\/p>\n<p>  \u0412\u043e\u043e\u0431\u0449\u0435 \u0438\u0433\u0440\u0430\u0442\u044c \u0432 \u0437\u043c\u0435\u0439\u043a\u0443 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u2013 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043b\u0435\u0442\u043e\u0447\u043a\u0435 \u0432 \u043c\u0430\u0442\u0440\u0438\u0446\u0435. \u0418 \u0432\u0441\u0451 \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0448\u0435\u043d\u0430 \u2013 Happy End.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u044b\u043c, \u043d\u0430\u0448\u0435 \u043f\u043e\u043b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u00ab\u0421\u0432\u044f\u0437\u043d\u044b\u0439 \u0433\u0440\u0430\u0444\u00bb. \u0422.\u0435. \u043a\u0430\u0436\u0434\u0430\u044f \u043a\u043b\u0435\u0442\u043e\u0447\u043a\u0430 \u043d\u0430 \u0434\u043e\u0441\u043a\u0435 \u2013 \u044d\u0442\u043e \u0432\u0435\u0440\u0448\u0438\u043d\u0430. \u0418\u0437 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0438\u0434\u0443\u0442 \u0440\u0435\u0431\u0440\u0430 \u2013 \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u0441\u043e\u0441\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0448\u0438\u043d\u0443. <br \/>  \u0422\u0430\u043a\u0438\u0445 \u0440\u0435\u0431\u0435\u0440 \u043b\u0438\u0431\u043e \u043e\u0442 2 \u0434\u043e 4. \u0414\u043b\u044f \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043a\u043b\u0435\u0442\u043e\u0447\u043a\u0438 \u0438 \u0434\u043b\u044f \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u0413\u0434\u0435-\u0442\u043e 4 \u0430\u0432\u0433\u0443\u0441\u0442\u0430 1805 \u2014 2 \u0441\u0435\u043d\u0442\u044f\u0431\u0440\u044f 1865 \u0432 \u0418\u0440\u043b\u0430\u043d\u0434\u0438\u0438 \u0436\u0438\u043b \u043d\u0435\u043a\u0438\u0439 \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d \u0423\u0438\u043b\u044c\u044f\u043c \u0420\u043e\u0443\u044d\u043d, \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b \u0437\u0430\u0434\u0430\u0447\u0443 \u00ab\u043a\u0440\u0443\u0433\u043e\u0441\u0432\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0438\u044f\u00bb \u043f\u043e \u0434\u043e\u0434\u0435\u043a\u0430\u044d\u0434\u0440\u0443. \u0412 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0434\u043e\u0434\u0435\u043a\u0430\u044d\u0434\u0440\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0433\u043e\u0440\u043e\u0434\u0430, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0411\u0440\u044e\u0441\u0441\u0435\u043b\u044c, \u0410\u043c\u0441\u0442\u0435\u0440\u0434\u0430\u043c, \u042d\u0434\u0438\u043d\u0431\u0443\u0440\u0433, \u041f\u0435\u043a\u0438\u043d, \u041f\u0440\u0430\u0433\u0430, \u0414\u0435\u043b\u0438, \u0424\u0440\u0430\u043d\u043a\u0444\u0443\u0440\u0442 \u0438 \u0434\u0440., \u0430 \u0440\u0451\u0431\u0440\u0430 \u2014 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u044e\u0449\u0438\u0435 \u0438\u0445 \u0434\u043e\u0440\u043e\u0433\u0438. \u041f\u0443\u0442\u0435\u0448\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u043e\u0439\u0442\u0438 \u00ab\u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0432\u0435\u0442\u0430\u00bb, \u043d\u0430\u0439\u0434\u044f \u043f\u0443\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u0432\u0441\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0433\u043e\u0440\u043e\u0434\u043e\u0432 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u043b\u0441\u044f \u0437\u0430\u0440\u0430\u043d\u0435\u0435. \u0410 \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043b\u0435\u0433\u0447\u0435 \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0433\u043e\u0440\u043e\u0434\u0430 \u0443\u0436\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b, \u0432 \u043a\u0430\u0436\u0434\u0443\u044e \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0434\u043e\u0434\u0435\u043a\u0430\u044d\u0434\u0440\u0430 \u0431\u044b\u043b \u0432\u0431\u0438\u0442 \u0433\u0432\u043e\u0437\u0434\u044c, \u0438 \u043f\u0440\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043e\u0442\u043c\u0435\u0447\u0430\u043b\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u0435\u0440\u0451\u0432\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0433\u043b\u0430 \u043e\u0431\u043c\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043e\u043a\u0440\u0443\u0433 \u0433\u0432\u043e\u0437\u0434\u044f. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e\u0439, \u0438 \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u043d\u043e\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438\u0433\u0440\u044b, \u0437\u0430\u043c\u0435\u043d\u0438\u0432 \u0434\u043e\u0434\u0435\u043a\u0430\u044d\u0434\u0440 \u043f\u043b\u043e\u0441\u043a\u0438\u043c \u0433\u0440\u0430\u0444\u043e\u043c, \u0438\u0437\u043e\u043c\u043e\u0440\u0444\u043d\u044b\u043c \u0433\u0440\u0430\u0444\u0443, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c\u0443 \u043d\u0430 \u0440\u0451\u0431\u0440\u0430\u0445 \u0434\u043e\u0434\u0435\u043a\u0430\u044d\u0434\u0440\u0430.<\/p>\n<p>  \u0412 \u043e\u0431\u0449\u0435\u043c \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u0448\u0443\u0442\u043a\u0430 \u043a\u0430\u043a \u00ab\u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432\u044b\u0439 \u0446\u0438\u043a\u043b\u00bb. \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432\u044b\u0439 \u0446\u0438\u043a\u043b\u00bb \u2014 \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0446\u0438\u043a\u043b (\u0437\u0430\u043c\u043a\u043d\u0443\u0442\u044b\u0439 \u043f\u0443\u0442\u044c), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u0436\u0434\u0443\u044e \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0433\u0440\u0430\u0444\u0430 \u0440\u043e\u0432\u043d\u043e \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0440\u0430\u0437\u0443; \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0446\u0438\u043a\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432\u0441\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0433\u0440\u0430\u0444\u0430. \u0422\u0430\u043a\u0436\u0435 \u0441 \u0433\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432\u044b\u043c \u0433\u0440\u0430\u0444\u043e\u043c \u0442\u0435\u0441\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0433\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432\u0430 \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u043f\u0443\u0442\u0451\u043c (\u043f\u0443\u0442\u0451\u043c \u0431\u0435\u0437 \u043f\u0435\u0442\u0435\u043b\u044c), \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u0436\u0434\u0443\u044e \u0432\u0435\u0440\u0448\u0438\u043d\u0443 \u0433\u0440\u0430\u0444\u0430 \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432 \u043f\u0443\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0446\u0438\u043a\u043b\u0430 \u0442\u0435\u043c, \u0447\u0442\u043e \u0443 \u043f\u0443\u0442\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0446\u0438\u043a\u043b\u0430. \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432 \u0446\u0438\u043a\u043b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432\u044b\u043c \u043f\u0443\u0442\u0451\u043c. <\/p>\n<p>  \u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/cd\/vb\/lt\/cdvblt7iz91zy1l17vu0mwb6dte.jpeg\"><\/div>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0430\u043a.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/0u\/rp\/gi\/0urpgid2eitflowmgthbkqi97ty.jpeg\"><\/div>\n<p>  \u0422\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u0442 \u043d\u044e\u0430\u043d\u0441\u2026 \u0415\u0441\u043b\u0438 \u043c\u044b \u043e\u0442 \u0431\u0430\u043b\u0434\u044b \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0432\u043e\u0442 \u0446\u0438\u043a\u043b, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043f\u0435\u0440\u0435\u0431\u043e\u0440 \u0442\u0430\u043a\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u0447\u0442\u043e \u0436\u0434\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u0448\u0435\u0441\u0442\u0432\u0438\u044f. <\/p>\n<p>  \u0421\u0443\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u0431\u0449\u0438\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044e \u00ab\u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432 \u0446\u0438\u043a\u043b\u0430\u00bb \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0431\u043e\u0440 \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u043d\u0435\u0442. \u0410 \u0443 \u043d\u0430\u0441 \u043f\u0440\u0438 \u043c\u0430\u0442\u0440\u0438\u0446\u0435 12 \u043d\u0430 12 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u0448\u0438\u043d 144 \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043e\u0442 2 \u0434\u043e 4-\u0445 \u0440\u0435\u0431\u0435\u0440. \u0412 \u043e\u0431\u0449\u0435\u043c, \u0442\u0430\u043c \u0433\u0434\u0435-\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c n!..<\/p>\n<p>  \u041d\u043e \u0442.\u043a. \u043c\u044b \u0440\u0435\u0448\u0430\u0435\u043c \u0437\u0430\u0434\u0430\u0447\u043a\u0443 \u0434\u043b\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043a\u0430\u0436\u0434\u0430\u044f \u0432\u0435\u0440\u0448\u0438\u043d\u0430 \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0441\u043e\u0441\u0435\u0434\u044f\u043c\u0438, \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0445\u043e\u0434 \u043f\u043e \u0447\u0430\u0441\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0435.<\/p>\n<p>  \u0422\u043e\u0433\u0434\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u00ab\u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u043e\u0432 \u0446\u0438\u043a\u043b\u00bb \u043d\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0440\u0443\u0434\u0430.<\/p>\n<pre><code class=\"cs\">private void CreateHamiltonPath()         {             this.HamiltonPath.Clear();             this.HamiltonPath.Add(new Vector2(0, 0));             HamiltonStep(this.HamiltonPath.Last());         }          private bool HamiltonStep(Vector2 current)         {             if (HamiltonPath.Count == HamiltonPath.Capacity)             {                 var first = HamiltonPath.First();                 return (first.X == current.X &amp;&amp; first.Y == current.Y - 1)                     || (first.X == current.X &amp;&amp; first.Y == current.Y + 1)                     || (first.X - 1 == current.X &amp;&amp; first.Y == current.Y)                     || (first.X + 1 == current.X &amp;&amp; first.Y == current.Y);             }             foreach (var direction in new[] { Directions.Down, Directions.Rigth, Directions.Up, Directions.Left })             {                 Vector2 newElement = null;                 switch (direction)                 {                     case Directions.Up:                         newElement = new Vector2(current.X, current.Y - 1);                         break;                     case Directions.Left:                         newElement = new Vector2(current.X - 1, current.Y);                         break;                     case Directions.Down:                         newElement = new Vector2(current.X, current.Y + 1);                         break;                     case Directions.Rigth:                         newElement = new Vector2(current.X + 1, current.Y);                         break;                 }                 if (0 &lt;= newElement.X &amp;&amp; newElement.X &lt; xSize                     &amp;&amp; 0 &lt;= newElement.Y &amp;&amp; newElement.Y &lt; ySize                     &amp;&amp; !HamiltonPath.Contains(newElement, vector2Comparer))                 {                     HamiltonPath.Add(newElement);                     if (HamiltonStep(newElement))                     {                         return true;                     }                     HamiltonPath.Remove(newElement);                 }             }             return false;         }<\/code><\/pre>\n<p>  \u0418 \u0434\u0430 \u044d\u0442\u043e \u0438\u0434\u0435\u044e \u044f \u201e\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u201c \u044d\u0442\u0443 \u0438\u0434\u0435\u044e \u0443 \u201e<a href=\"https:\/\/www.youtube.com\/channel\/UC0e3QhIYukixgh5VVpKHH9Q\" rel=\"nofollow noopener noreferrer\">Code Bullet<\/a>\u201c, \u0430 \u043e\u043d \u0435\u0451 \u0435\u0449\u0435 \u0443 \u043e\u0434\u043d\u043e\u0433\u043e \u0447\u0443\u0432\u0430\u043a\u0430 \u0432 \u0438\u043d\u0442\u0435\u0440\u0435\u043d\u0442\u0435.<\/p>\n<p>  \u041a\u043e\u0440\u043e\u0447\u0435, \u043a\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u043b \u041f\u0430\u0431\u043b\u043e \u041f\u0438\u043a\u0430\u0441\u0441\u043e:   <\/p>\n<blockquote><p>\u0425\u043e\u0440\u043e\u0448\u0438\u0435 \u0445\u0443\u0434\u043e\u0436\u043d\u0438\u043a\u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442, \u0432\u0435\u043b\u0438\u043a\u0438\u0435 \u0445\u0443\u0434\u043e\u0436\u043d\u0438\u043a\u0438 \u0432\u043e\u0440\u0443\u044e\u0442<\/p><\/blockquote>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ns\/fa\/eb\/nsfaebncwspo4bsctknaj1p1q-g.jpeg\"><\/div>\n<p>  \u0418 \u0442\u0430\u043a, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u043c\u0435\u0439\u043a\u0443 \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0446\u0438\u043a\u043b\u0443 \u0434\u043e \u043f\u043e\u0431\u0435\u0434\u044b:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xp\/dj\/wi\/xpdjwibjutsdvfgktx2ebnnbapu.jpeg\"><\/div>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0448\u0435\u043d\u0430! \u041d\u043e \u043a\u0430\u043a \u0436\u0435 \u0443\u0431\u043e\u0433\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u043a\u043e\u0433\u0434\u0430 \u043e\u0434\u043d\u043e\u043a\u043b\u0435\u0442\u043e\u0447\u043d\u0430\u044f \u0437\u043c\u0435\u044f \u043f\u043e\u043b\u0437\u0435\u0442 \u043e\u0442 \u0442\u043e\u0447\u043a\u0438 \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443. \u0425\u043e\u0442\u044f \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439 \u0432\u0437\u044f\u0442\u044c \u0435\u0451 \u043d\u0435\u0442\u2026<\/p>\n<p>  \u0410 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 (O)n^n-1<\/p>\n<p>  \u0422.\u043a. \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437\u2026 \u041a\u0430\u0436\u0434\u044b\u0439\u2026. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0445\u043e\u0434\u0438\u0442\u044c \u0432\u0441\u0451 \u043f\u043e \u0446\u0438\u043a\u043b\u0443\u2026<\/p>\n<p>  \u041f\u0440\u043e\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f \u2014 \u0443\u0441\u0442\u0430\u043d\u0435\u043c \u0436\u0434\u0430\u0442\u044c\u2026 \u0422\u0430\u043a, \u0447\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0445\u043e\u0442\u044c \u0438 \u0445\u043e\u0440\u043e\u0448\u0435\u0435, \u043d\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u2014 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e\u2026<\/p>\n<h2>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  \u0427\u0442\u043e \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u043e \u0437\u043c\u0435\u0435. \u0415\u0451 \u0434\u043b\u0438\u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u0435\u0434\u0430\u043d\u0438\u0438 \u043c\u044b\u0448\u0438. \u0418 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0440\u0430\u0435\u043a\u0442\u043e\u0440\u0438\u0435\u0439 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043d\u0435\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0413\u0430\u043c\u0435\u043b\u044c\u0442\u043e\u043d\u043e\u0432 \u043f\u0443\u0442\u044c. \u0410 \u0441\u0430\u043c\u043e\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u2013 \u044d\u0442\u043e \u043f\u0440\u044f\u043c\u0430\u044f.<\/p>\n<p>  \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0432\u044b\u0437\u043e\u0432\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438:<\/p>\n<pre><code class=\"cs\">private void CalculatePath()         {             this.StepsCountAfterCalculatePath = 0;             int finalIndexPoint = this.HamiltonPath.FindIndex(p =&gt; p.X == this.Mouse.X &amp;&amp; p.Y == this.Mouse.Y);             List&lt;Vector2&gt; tempPath = new List&lt;Vector2&gt;();             List&lt;Vector2&gt; stepPiton = new List&lt;Vector2&gt;(this.Piton);             Debug.WriteLine($&quot;Piton length: {this.Piton.Count}&quot;);             int index = 0;             var result = StepTempPath(ref index, GetInvert(stepPiton, this.Mouse), this.Piton.Last(), finalIndexPoint, stepPiton, tempPath);             if (result.PathIsFound)             {                 this.TempPath = new Queue&lt;Vector2&gt;(tempPath);                 this.InvertHamiltonPath = result.InvertHamiltonPath;             }         }<\/code><\/pre>\n<p>  \u0410 \u0432\u043e\u0442 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f.<\/p>\n<p>  \u041c\u044b \u0443\u043f\u043e\u0440\u043d\u043e \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0430\u0435\u043c\u0441\u044f \u043a \u0446\u0435\u043b\u0438:<\/p>\n<pre><code class=\"cs\">if (current.X &lt; finalPoint.X)                 {                     newElement = new Vector2(current.X + 1, current.Y);                 }                 else if (finalPoint.X &lt; current.X)                 {                     newElement = new Vector2(current.X - 1, current.Y);                 }                 else if (current.Y &lt; finalPoint.Y)                 {                     newElement = new Vector2(current.X, current.Y + 1);                 }                 else if (finalPoint.Y &lt; current.Y)                 {                     newElement = new Vector2(current.X, current.Y - 1);                 }<\/code><\/pre>\n<p>  \u0417\u043c\u0435\u044f \u043d\u0435 \u0443\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u0437\u0430\u0442\u044c \u043f\u043e \u0434\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u0438, \u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u0443\u0436\u0435 \u0438\u0434\u0435\u043c \u043a \u0446\u0435\u043b\u0438 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438. \u0418 \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430.<\/p>\n<pre><code class=\"cs\">if (current.X == finalPoint.X &amp;&amp; current.Y == finalPoint.Y)             {                 var tempPiton = stepPiton.TakeLast(this.Piton.Count).ToList();                 for (int i = 1; i &lt; this.Piton.Count; i++)                 {                     var hamiltonPoint = (finalIndexPoint + i &lt; this.HamiltonPath.Count) ? this.HamiltonPath[finalIndexPoint + i] : this.HamiltonPath[finalIndexPoint + i - this.HamiltonPath.Count];                     if (tempPiton.TakeLast(this.Piton.Count).Contains(hamiltonPoint, vector2Comparer))                     {                         return false;                     }                     tempPiton.Add(hamiltonPoint);                 }                 return true;             }<\/code><\/pre>\n<p>  \u0427\u0442\u043e \u043c\u044b \u0442\u0443\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0434\u0435\u043b\u0430\u0435\u043c. <\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 \u043d\u0430\u0448\u0443 \u043c\u044b\u0448\u044c. \u041c\u044b \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0443\u0442\u044c, \u043d\u043e \u0443\u0436\u0435 \u043f\u043e \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u0430 \u0438 \u0435\u0441\u043b\u0438 \u043e\u043d \u043d\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u0442\u0435\u043b\u043e\u043c \u043d\u0430\u0448\u0435\u0439 \u0437\u043c\u0435\u0438, \u0442\u043e \u043c\u044b \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 \u0434\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043c\u044b\u0448\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0437\u043c\u0435\u044e \u0442.\u043a. \u043f\u043e\u0441\u043b\u0435 \u00ab\u0441\u044a\u0435\u0434\u0435\u043d\u0438\u044f \u043c\u044b\u0448\u0438\u00bb, \u0433\u0434\u0435 \u0431\u044b \u043d\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u043f\u0443\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0438 \u0441\u044a\u0435\u0441\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e.<\/p>\n<p>  \u041f\u043e\u043a\u0430 \u043c\u044b \u043e\u0434\u043d\u043e\u043a\u043b\u0435\u0442\u043e\u0447\u043d\u044b\u0435 \u2014 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u044b\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u0434\u043e\u043b\u0433\u043e\u2026 \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0448\u0430 \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0439 \u043f\u0443\u0442\u044c \u043a \u0446\u0435\u043b\u0438 \u2013 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443. \u0426\u0438\u043a\u043b \u0438\u043c\u0435\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0442.\u0435. \u0437\u043c\u0435\u044f \u0434\u0432\u0438\u0436\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e \u0447\u0430\u0441\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0435, \u043a\u0430\u043a \u043c\u044b \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0442\u043e\u0438\u043b\u0438 \u0441\u0430\u043c \u043f\u0443\u0442\u044c.<\/p>\n<p>  \u0418 \u0442\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043c\u044b \u043f\u043e\u0434\u043e\u0448\u043b\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043c\u044b\u0448\u0438 \u0441\u0432\u0435\u0440\u0445\u0443, \u0430 \u043f\u0443\u0441\u0442\u044c \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u0430 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043f\u0443\u0442\u0438 \u0438\u0434\u0435\u0442 \u0432\u0432\u0435\u0440\u0445. \u041f\u043e \u0437\u043c\u0435\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0442\u0438\u0432 \u0441\u0430\u043c\u043e\u0439 \u0441\u0435\u0431\u044f, \u0447\u0442\u043e \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u2026 \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043c\u044b \u0432\u0432\u0435\u0434\u0435\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u0413\u0430\u043c\u0438\u043b\u044c\u0442\u043e\u043d\u0430. <\/p>\n<p>  \u0422.\u0435. \u0437\u043c\u0435\u044f \u043c\u043e\u0436\u0435\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u0447\u0430\u0441\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0435\u043b\u043a\u0435 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u0440\u043e\u0438\u043b\u0441\u044f \u043f\u0443\u0442\u044c, \u043d\u043e \u0438 \u0432 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0443\u0442\u0438. \u041f\u0443\u0442\u044c \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f, \u0430 \u0432\u043e\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u2013 \u0434\u0430.<\/p>\n<p>  \u0418\u0437\u043c\u0435\u043d\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443.<\/p>\n<pre><code class=\"cs\">if (current.X == finalPoint.X &amp;&amp; current.Y == finalPoint.Y)             {                 if (this.Piton.Count == 1)                 {                     return new ResultAnlaizePath(true);                 }                 foreach (var d in new[] { false, true })                 {                     var tempPiton = stepPiton.TakeLast(this.Piton.Count).ToList();                     bool isFound = true;                     bool invertHamiltonPath = d;                     for (int j = 1; j &lt; this.Piton.Count; j++)                     {                         Vector2 hamiltonPoint;                         if (invertHamiltonPath)                         {                             hamiltonPoint = (finalIndexPoint - j &gt;= 0) ? this.HamiltonPath[finalIndexPoint - j] : this.HamiltonPath[this.HamiltonPath.Count - j];                         }                         else                         {                             hamiltonPoint = (finalIndexPoint + j &lt; this.HamiltonPath.Count) ? this.HamiltonPath[finalIndexPoint + j] : this.HamiltonPath[finalIndexPoint + j - this.HamiltonPath.Count];                         }                         if (tempPiton.TakeLast(this.Piton.Count).Contains(hamiltonPoint, vector2Comparer))                         {                             isFound = false;                             break;                         }                         tempPiton.Add(hamiltonPoint);                     }                     if (isFound)                     {                         return new ResultAnlaizePath(true, invertHamiltonPath);                     }                 }                 return new ResultAnlaizePath(false);             }<\/code><\/pre>\n<p>  \u0418 \u043a\u0441\u0442\u0430\u0442\u0438, \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0439 \u00abCode Bullet\u00bb \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0444\u0438\u043d\u0442\u0430 \u0443\u0448\u0430\u043c\u0438 \u043d\u0435 \u0434\u043e\u0434\u0443\u043c\u0430\u043b\u0441\u044f. \u042f \u043f\u0440\u043e \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0434\u0430 \u043e\u043d \u00ab\u0441\u0440\u0435\u0437\u0430\u043b \u0443\u0433\u043b\u044b\u00bb, \u043f\u043e \u043d\u0435\u043a\u043e\u043c\u0443 \u0441\u0432\u043e\u0435\u043c\u0443 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0432 \u0442\u0430\u0439\u043d\u0435 \u043f\u043e\u043a\u0440\u044b\u0442\u044b\u043c \u043c\u0440\u0430\u043a\u043e\u043c. \u041d\u043e \u0442\u043e\u0447\u043d\u043e \u043c\u043e\u0433\u0443 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0432 \u0435\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0431\u044b\u043b \u043a\u043e\u0441\u044f\u0447\u043e\u043a, \u0438\u0437-\u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u043b\u0441\u044f \u0435\u0433\u043e \u043f\u0440\u043e\u0445\u043e\u0434.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/t8\/px\/zl\/t8pxzlyeies5fmnnkps23m8qy7i.jpeg\"><\/p>\n<p>  \u041d\u0443 \u0432 \u0446\u0435\u043b\u043e\u043c, \u0447\u0442\u043e \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c. \u041f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0434\u0435\u043b\u043e, \u0447\u0442\u043e \u043a\u0440\u043e\u043c\u0435 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0445\u043e\u0434\u0430 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044e \u0437\u043c\u0435\u0438, \u043c\u043e\u0436\u043d\u043e \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 \u0435\u0451 \u0445\u0432\u043e\u0441\u0442. \u0414\u043b\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u043e\u0438\u0441\u043a \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043f\u0443\u0442\u0438. <\/p>\n<pre><code class=\"cs\">if (!stepPiton.TakeLast(this.Piton.Count).Contains(newElement, vector2Comparer))             {                 tempPath.Add(newElement);                 stepPiton.Add(newElement);                 var retult = StepTempPath(ref index, !invert, newElement, finalIndexPoint, stepPiton, tempPath);                 if (retult.PathIsFound)                 {                     return retult;                 }                 if (this.HamiltonPath.Count &lt; index)                 {                     return new ResultAnlaizePath(false);                 }                 tempPath.Remove(newElement);                 stepPiton.Remove(newElement);             }              Vector2 nextFinalPoint;             if (this.InvertHamiltonPath)             {                 nextFinalPoint = (finalIndexPoint - 1 &lt; 0) ? this.HamiltonPath[this.HamiltonPath.Count - 1] : this.HamiltonPath[finalIndexPoint - 1];             }             else             {                 nextFinalPoint = (finalIndexPoint + 1 == this.HamiltonPath.Count) ? this.HamiltonPath[0] : this.HamiltonPath[finalIndexPoint + 1];             }             List&lt;Directions&gt; directions = new List&lt;Directions&gt;(4);             directions.Add(finalPoint.Y &lt; nextFinalPoint.Y ? Directions.Up : Directions.Down);             directions.Add(finalPoint.X &lt; nextFinalPoint.X ? Directions.Left : Directions.Rigth);             directions.Add(finalPoint.Y &lt; nextFinalPoint.Y ? Directions.Down : Directions.Up);             directions.Add(finalPoint.X &lt; nextFinalPoint.X ? Directions.Rigth : Directions.Left);              foreach (var direction in directions)             {                 switch (direction)                 {                     case Directions.Up:                         newElement = new Vector2(current.X, current.Y - 1);                         break;                     case Directions.Left:                         newElement = new Vector2(current.X - 1, current.Y);                         break;                     case Directions.Down:                         newElement = new Vector2(current.X, current.Y + 1);                         break;                     case Directions.Rigth:                         newElement = new Vector2(current.X + 1, current.Y);                         break;                 }                 if (0 &lt;= newElement.X &amp;&amp; newElement.X &lt; xSize                  &amp;&amp; 0 &lt;= newElement.Y &amp;&amp; newElement.Y &lt; ySize                  &amp;&amp; !stepPiton.TakeLast(this.Piton.Count).Contains(newElement, vector2Comparer))                 {                     tempPath.Add(newElement);                     stepPiton.Add(newElement);                     var retult = StepTempPath(ref index, GetInvert(stepPiton, finalPoint), newElement, finalIndexPoint, stepPiton, tempPath);                     if (retult.PathIsFound)                     {                         return retult;                     }                     if (this.HamiltonPath.Count &lt; index)                     {                         return new ResultAnlaizePath(false);                     }                     tempPath.Remove(newElement);                     stepPiton.Remove(newElement);                 }             }             return new ResultAnlaizePath(false);<\/code><\/pre>\n<p>  \u0412 \u0446\u0435\u043b\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e. <\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u043e\u043c. <\/p>\n<p>  \u0417\u0434\u0435\u0441\u044c \u044f \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u043f\u0443\u0441\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0445\u043e\u0434 \u00ab\u043f\u0440\u044f\u043c\u043e\u043c\u0443 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044e\u00bb \u043a \u043c\u044b\u0448\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u043c\u0443 \u0432\u044b\u0448\u0435.<\/p>\n<pre><code class=\"css\">            List&lt;Directions&gt; directions = new List&lt;Directions&gt;(4);             directions.Add(finalPoint.Y &lt; nextFinalPoint.Y ? Directions.Up : Directions.Down);             directions.Add(finalPoint.X &lt; nextFinalPoint.X ? Directions.Left : Directions.Rigth);             directions.Add(finalPoint.Y &lt; nextFinalPoint.Y ? Directions.Down : Directions.Up);             directions.Add(finalPoint.X &lt; nextFinalPoint.X ? Directions.Rigth : Directions.Left); <\/code><\/pre>\n<p>  \u0422.\u0435. \u00ab\u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0448\u0430\u0433 \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u0440\u043e\u043d\u0443\u00bb \u0434\u0430\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u044b\u043b\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u043d\u0430 \u043f\u0440\u044f\u043c\u043e\u043c \u043f\u0443\u0442\u0438.<\/p>\n<p>  \u041d\u0438\u0436\u0435 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434, \u0434\u0430 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u043f\u043e\u0434 \u0444\u0430\u0439\u043b\u0438\u043a\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u043e, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u0442\u0430\u043a \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u0435\u0439 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0444\u0430\u0439\u043b\u0430 \u043b\u043e\u0433\u0438\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"css\"> using Microsoft.AspNetCore.SignalR; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.ExceptionServices; using System.Threading.Tasks; using System.Timers;  namespace SnakeApplication.WebApp.Hubs {     public class SnakeHub : Hub     {     }      public class SnakeSender     {         class Vector2         {             public int X { get; set; }             public int Y { get; set; }             public Vector2(int x, int y)             {                 this.X = x;                 this.Y = y;             }         }          class Vector2Comparer : IEqualityComparer&lt;Vector2&gt;         {             public bool Equals([AllowNull] Vector2 value1, [AllowNull] Vector2 value2)             {                 return value1.X == value2.X &amp;&amp; value1.Y == value2.Y;             }              public int GetHashCode([DisallowNull] Vector2 obj)             {                 return 0;             }         }          private readonly static Vector2Comparer vector2Comparer = new Vector2Comparer();           [JsonConverter(typeof(StringEnumConverter))]         enum Cell         {             None,             Mouse,             Snake         }          enum Directions         {             Up,             Left,             Down,             Rigth         }          class StateBoard         {             public bool IsLife { get; set; }             public bool IsWin { get; set; }             public int XSize { get; set; }             public int YSize { get; set; }             public Vector2 Mouse { get; set; }             public List&lt;Vector2&gt; Piton { get; set; }             public List&lt;Vector2&gt; HamiltonPath { get; set; }         }          const int xSize = 12, ySize = 12;         private Random Rand { get; }         private IServiceProvider ServiceProvider { get; }         private bool IsLife { get; set; }         private bool IsWin { get; set; }         Directions Direction { get; set; }         private Vector2 Mouse { get; set; }         private Queue&lt;Vector2&gt; Piton { get; set; }         private bool InvertHamiltonPath { get; set; }         private List&lt;Vector2&gt; HamiltonPath { get; }         private Queue&lt;Vector2&gt; TempPath { get; set; }         private int StepsCountAfterCalculatePath { get; set; }      public SnakeSender(IServiceProvider serviceProvider)         {             this.Rand = new Random();             this.ServiceProvider = serviceProvider;             this.TempPath = new Queue&lt;Vector2&gt;();             this.HamiltonPath = new List&lt;Vector2&gt;(xSize * ySize);             this.CreateHamiltonPath();             this.CreateBoard();         }          private void CreateHamiltonPath()         {             this.HamiltonPath.Clear();             this.HamiltonPath.Add(new Vector2(0, 0));             HamiltonStep(this.HamiltonPath.Last());         }          private bool HamiltonStep(Vector2 current)         {             if (HamiltonPath.Count == HamiltonPath.Capacity)             {                 var first = HamiltonPath.First();                 return (first.X == current.X &amp;&amp; first.Y == current.Y - 1)                     || (first.X == current.X &amp;&amp; first.Y == current.Y + 1)                     || (first.X - 1 == current.X &amp;&amp; first.Y == current.Y)                     || (first.X + 1 == current.X &amp;&amp; first.Y == current.Y);             }             foreach (var direction in new[] { Directions.Down, Directions.Rigth, Directions.Up, Directions.Left })             {                 Vector2 newElement = null;                 switch (direction)                 {                     case Directions.Up:                         newElement = new Vector2(current.X, current.Y - 1);                         break;                     case Directions.Left:                         newElement = new Vector2(current.X - 1, current.Y);                         break;                     case Directions.Down:                         newElement = new Vector2(current.X, current.Y + 1);                         break;                     case Directions.Rigth:                         newElement = new Vector2(current.X + 1, current.Y);                         break;                 }                 if (0 &lt;= newElement.X &amp;&amp; newElement.X &lt; xSize                     &amp;&amp; 0 &lt;= newElement.Y &amp;&amp; newElement.Y &lt; ySize                     &amp;&amp; !HamiltonPath.Contains(newElement, vector2Comparer))                 {                     HamiltonPath.Add(newElement);                     if (HamiltonStep(newElement))                     {                         return true;                     }                     HamiltonPath.Remove(newElement);                 }             }             return false;         }          private void CreateBoard()         {             Task.Run(async () =&gt;             {                 this.Piton = new Queue&lt;Vector2&gt;();                 \/\/for (int i = 0; i &lt; 1; i++)                 \/\/{                 \/\/    this.Piton.Enqueue(new Vector2(ySize \/ 2, xSize \/ 2 - i));                 \/\/}                 this.Piton.Enqueue(new Vector2(0, 0));                 this.IsLife = true;                 this.Direction = Directions.Up;                 this.CreateMouse();                 while (this.IsLife)                 {                     this.LifeCycle();                     await Task.Delay(100);                 }             });         }          private void LifeCycle()         {             this.SetDirection();             this.Step();             this.CheckDead();             this.Render();         }          private void SetDirection()         {             Vector2 head = this.Piton.Last();             int currentIndnex = this.HamiltonPath.FindIndex(p =&gt; p.X == head.X &amp;&amp; p.Y == head.Y);             Vector2 currentElement = this.HamiltonPath[currentIndnex];             Vector2 nextElement = null;             if (this.TempPath.Count &gt; 0)             {                 nextElement = this.TempPath.Dequeue();             }             else             {                 this.StepsCountAfterCalculatePath++;                 if (this.InvertHamiltonPath)                 {                     nextElement = (currentIndnex - 1 &lt; 0) ? this.HamiltonPath[this.HamiltonPath.Count - 1] : this.HamiltonPath[currentIndnex - 1];                 }                 else                 {                     nextElement = (currentIndnex + 1 == this.HamiltonPath.Count) ? this.HamiltonPath[0] : this.HamiltonPath[currentIndnex + 1];                 }             }              if (currentElement.X == nextElement.X &amp;&amp; currentElement.Y &lt; nextElement.Y)             {                 this.Direction = Directions.Down;                 return;             }              if (currentElement.X == nextElement.X &amp;&amp; nextElement.Y &lt; currentElement.Y)             {                 this.Direction = Directions.Up;                 return;             }              if (currentElement.X &lt; nextElement.X &amp;&amp; currentElement.Y == nextElement.Y)             {                 this.Direction = Directions.Rigth;                 return;             }              if (nextElement.X &lt; currentElement.X &amp;&amp; currentElement.Y == nextElement.Y)             {                 this.Direction = Directions.Left;                 return;             }              throw new NotImplementedException();         }          private void Step()         {             Vector2 head = this.Piton.Last();             switch (this.Direction)             {                 case Directions.Up:                     this.Piton.Enqueue(new Vector2(head.X, head.Y - 1));                     break;                 case Directions.Left:                     this.Piton.Enqueue(new Vector2(head.X - 1, head.Y));                     break;                 case Directions.Down:                     this.Piton.Enqueue(new Vector2(head.X, head.Y + 1));                     break;                 case Directions.Rigth:                     this.Piton.Enqueue(new Vector2(head.X + 1, head.Y));                     break;             }             if (this.Piton.Contains(this.Mouse, vector2Comparer))             {                 CreateMouse();              }             else             {                 this.Piton.Dequeue();             }             if (this.Piton.Count &lt; this.StepsCountAfterCalculatePath) {                 this.CalculatePath();             }         }          private void CheckDead()         {             Vector2 head = this.Piton.Last();             if (head.X &lt; 0              || head.Y &lt; 0              || xSize &lt;= head.X              || ySize &lt;= head.Y              || this.Piton.SkipLast(1).Contains(head, vector2Comparer))             {                 this.IsLife = false;                 this.IsWin = false;                 return;             }         }          private void Render()         {             var hubContext = (IHubContext&lt;SnakeHub&gt;)this.ServiceProvider.GetService(typeof(IHubContext&lt;SnakeHub&gt;));             var piton = this.Piton.ToList();             piton.Reverse();             hubContext.Clients?.All.SendAsync(&quot;newState&quot;, JsonConvert.SerializeObject(new StateBoard()             {                 IsLife = this.IsLife,                 IsWin = this.IsWin,                 XSize = xSize,                 YSize = ySize,                 Mouse = this.Mouse,                 Piton = piton,                 HamiltonPath = HamiltonPath             }));         }          private void CreateMouse()         {             List&lt;Vector2&gt; emptyCells = GetEmptyCells();             if (emptyCells.Count &gt; 0)             {                 this.Mouse = emptyCells[this.Rand.Next(emptyCells.Count)];                 this.CalculatePath();             }             else             {                 this.IsLife = false;                 this.IsWin = true;             }         }          private void CalculatePath()         {             this.StepsCountAfterCalculatePath = 0;             int finalIndexPoint = this.HamiltonPath.FindIndex(p =&gt; p.X == this.Mouse.X &amp;&amp; p.Y == this.Mouse.Y);             List&lt;Vector2&gt; tempPath = new List&lt;Vector2&gt;();             List&lt;Vector2&gt; stepPiton = new List&lt;Vector2&gt;(this.Piton);             Debug.WriteLine($&quot;Piton length: {this.Piton.Count}&quot;);             int index = 0;             var result = StepTempPath(ref index, GetInvert(stepPiton, this.Mouse), this.Piton.Last(), finalIndexPoint, stepPiton, tempPath);             if (result.PathIsFound)             {                 this.TempPath = new Queue&lt;Vector2&gt;(tempPath);                 this.InvertHamiltonPath = result.InvertHamiltonPath;             }         }          private bool GetInvert(List&lt;Vector2&gt; stepPiton, Vector2 finalPoint)         {             if (this.Piton.Count &gt; 1)             {                 int pitonDirection = stepPiton.Last().Y - stepPiton[stepPiton.Count - 2].Y;                 int mouseDirection = stepPiton.Last().Y - finalPoint.Y;                 return (pitonDirection &lt; 0 &amp;&amp; mouseDirection &lt; 0) || (pitonDirection &gt; 0 &amp;&amp; mouseDirection &gt; 0);             }             return false;         }          class ResultAnlaizePath         {             public bool PathIsFound { get; set; }             public bool InvertHamiltonPath { get; set; }             public ResultAnlaizePath(bool pathIsFound, bool invertHamiltonPath = false)             {                 PathIsFound = pathIsFound;                 InvertHamiltonPath = invertHamiltonPath;             }         }          private ResultAnlaizePath StepTempPath(ref int index, bool invert, Vector2 current, int finalIndexPoint, List&lt;Vector2&gt; stepPiton, List&lt;Vector2&gt; tempPath)         {             index++;             if (this.HamiltonPath.Count &lt; index)             {                 return new ResultAnlaizePath(false);             }             Debug.WriteLine($&quot;index {index} {tempPath.Count}&quot;);             var finalPoint = this.HamiltonPath[finalIndexPoint];             if (current.X == finalPoint.X &amp;&amp; current.Y == finalPoint.Y)             {                 if (this.Piton.Count == 1)                 {                     return new ResultAnlaizePath(true);                 }                 foreach (var d in new[] { false, true })                 {                     var tempPiton = stepPiton.TakeLast(this.Piton.Count).ToList();                     bool isFound = true;                     bool invertHamiltonPath = d;                     for (int j = 1; j &lt; this.Piton.Count; j++)                     {                         Vector2 hamiltonPoint;                         if (invertHamiltonPath)                         {                             hamiltonPoint = (finalIndexPoint - j &gt;= 0) ? this.HamiltonPath[finalIndexPoint - j] : this.HamiltonPath[this.HamiltonPath.Count - j];                         }                         else                         {                             hamiltonPoint = (finalIndexPoint + j &lt; this.HamiltonPath.Count) ? this.HamiltonPath[finalIndexPoint + j] : this.HamiltonPath[finalIndexPoint + j - this.HamiltonPath.Count];                         }                         if (tempPiton.TakeLast(this.Piton.Count).Contains(hamiltonPoint, vector2Comparer))                         {                             isFound = false;                             break;                         }                         tempPiton.Add(hamiltonPoint);                     }                     if (isFound)                     {                         return new ResultAnlaizePath(true, invertHamiltonPath);                     }                 }                 return new ResultAnlaizePath(false);             }             if ((xSize + ySize * 2) &lt;= tempPath.Count)             {                 return new ResultAnlaizePath(false);             }             Vector2 newElement = null;              if (invert)             {                 if (current.X &lt; finalPoint.X)                 {                     newElement = new Vector2(current.X + 1, current.Y);                 }                 else if (finalPoint.X &lt; current.X)                 {                     newElement = new Vector2(current.X - 1, current.Y);                 }                 else if (current.Y &lt; finalPoint.Y)                 {                     newElement = new Vector2(current.X, current.Y + 1);                 }                 else if (finalPoint.Y &lt; current.Y)                 {                     newElement = new Vector2(current.X, current.Y - 1);                 }             }             else             {                 if (current.Y &lt; finalPoint.Y)                 {                     newElement = new Vector2(current.X, current.Y + 1);                 }                 else if (finalPoint.Y &lt; current.Y)                 {                     newElement = new Vector2(current.X, current.Y - 1);                 }                 else if (current.X &lt; finalPoint.X)                 {                     newElement = new Vector2(current.X + 1, current.Y);                 }                 else if (finalPoint.X &lt; current.X)                 {                     newElement = new Vector2(current.X - 1, current.Y);                 }             }              if (!stepPiton.TakeLast(this.Piton.Count).Contains(newElement, vector2Comparer))             {                 tempPath.Add(newElement);                 stepPiton.Add(newElement);                 var retult = StepTempPath(ref index, !invert, newElement, finalIndexPoint, stepPiton, tempPath);                 if (retult.PathIsFound)                 {                     return retult;                 }                 if (this.HamiltonPath.Count &lt; index)                 {                     return new ResultAnlaizePath(false);                 }                 tempPath.Remove(newElement);                 stepPiton.Remove(newElement);             }              Vector2 nextFinalPoint;             if (this.InvertHamiltonPath)             {                 nextFinalPoint = (finalIndexPoint - 1 &lt; 0) ? this.HamiltonPath[this.HamiltonPath.Count - 1] : this.HamiltonPath[finalIndexPoint - 1];             }             else             {                 nextFinalPoint = (finalIndexPoint + 1 == this.HamiltonPath.Count) ? this.HamiltonPath[0] : this.HamiltonPath[finalIndexPoint + 1];             }             List&lt;Directions&gt; directions = new List&lt;Directions&gt;(4);             directions.Add(finalPoint.Y &lt; nextFinalPoint.Y ? Directions.Up : Directions.Down);             directions.Add(finalPoint.X &lt; nextFinalPoint.X ? Directions.Left : Directions.Rigth);             directions.Add(finalPoint.Y &lt; nextFinalPoint.Y ? Directions.Down : Directions.Up);             directions.Add(finalPoint.X &lt; nextFinalPoint.X ? Directions.Rigth : Directions.Left);              foreach (var direction in directions)             {                 switch (direction)                 {                     case Directions.Up:                         newElement = new Vector2(current.X, current.Y - 1);                         break;                     case Directions.Left:                         newElement = new Vector2(current.X - 1, current.Y);                         break;                     case Directions.Down:                         newElement = new Vector2(current.X, current.Y + 1);                         break;                     case Directions.Rigth:                         newElement = new Vector2(current.X + 1, current.Y);                         break;                 }                 if (0 &lt;= newElement.X &amp;&amp; newElement.X &lt; xSize                  &amp;&amp; 0 &lt;= newElement.Y &amp;&amp; newElement.Y &lt; ySize                  &amp;&amp; !stepPiton.TakeLast(this.Piton.Count).Contains(newElement, vector2Comparer))                 {                     tempPath.Add(newElement);                     stepPiton.Add(newElement);                     var retult = StepTempPath(ref index, GetInvert(stepPiton, finalPoint), newElement, finalIndexPoint, stepPiton, tempPath);                     if (retult.PathIsFound)                     {                         return retult;                     }                     if (this.HamiltonPath.Count &lt; index)                     {                         return new ResultAnlaizePath(false);                     }                     tempPath.Remove(newElement);                     stepPiton.Remove(newElement);                 }             }             return new ResultAnlaizePath(false);         }          private List&lt;Vector2&gt; GetEmptyCells()         {             List&lt;Vector2&gt; emptyCells = new List&lt;Vector2&gt;(xSize * ySize);             for (int i = 0; i &lt; ySize; i++)             {                 for (int j = 0; j &lt; xSize; j++)                 {                     if (!this.Piton.Contains(new Vector2(j, i), vector2Comparer))                     {                         emptyCells.Add(new Vector2(j, i));                     }                 }             }              return emptyCells;         }     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a\u0430\u043a \u0432\u0441\u0451 \u044d\u0442\u043e \u043f\u043e\u043b\u0437\u0430\u0435\u0442.<\/p>\n<div class=\"oembed\"><iframe allowfullscreen id=\"603c10077c24d22e1e99f9d5\" src=\"https:\/\/embedd.srv.habr.com\/iframe\/603c10077c24d22e1e99f9d5\"><\/iframe><\/div>\n<p>  \u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0443\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439 AI.<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/544696\/\"> https:\/\/habr.com\/ru\/post\/544696\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\u0414\u043e\u0431\u0440\u044b\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0443\u0447\u0438\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0438\u0433\u0440\u0430\u0442\u044c \u0432 \u0437\u043c\u0435\u0439\u043a\u0443.<\/p>\n<p>  \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u044d\u0442\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u043a\u0443. \u0421\u043a\u0430\u0436\u0435\u043c \u0442\u0430\u043a \u0440\u0430\u0437\u043c\u0438\u043d\u043e\u0447\u043d\u0430\u044f, \u043f\u0435\u0440\u0435\u0434 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0431\u043e\u0435\u043c.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/xo\/ex\/ma\/xoexmae9mrj2ec2zqoi2ttc0i3w.jpeg\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-318786","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318786","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=318786"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318786\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=318786"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=318786"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=318786"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}