/// <summary>
    /// Вращение всех shape так, чтобы не пропали соединения с коннекторами. Также генерирует shape-ы, если у повернутого shape есть свободные выходы в соседние пустые ноды.
    /// </summary>
    private static void RandomSafeRotateWithGenerationAllShapes()
    {
        //количество подключенных коннекторов в начале этой функции
        int connectedConnectorsMaxCount = ConnectorsManager.GetConnectedCount();

        foreach (var node in NodesGrid.Grid)
        {
            if (node.Shape != null)
            {
                Direction currentDir = node.Shape.CurrentDirection;
                RandomRotateShape(node.Shape);

                int connectedCount = ConnectorsManager.GetConnectedCount();

                //возврат к состоянию до рэндомного вращения
                if (connectedCount < connectedConnectorsMaxCount)
                {
                    node.Shape.FastRotateToDirection(currentDir);
                }

                connectedConnectorsMaxCount = Mathf.Max(connectedConnectorsMaxCount, connectedCount);
            }

            //генерация ноды, если свободная клетка
            List <KeyValuePair <Node, Direction> > nodes = NodesGrid.FindAvailableNeighborNodesForShapeSides(node);
            foreach (var nodeDirPair in nodes)
            {
                GenerateRecursively(nodeDirPair.Key, nodeDirPair.Value.GetOpposite());
            }
        }
    }
    public static void Generate()
    {
        _shapesCount = 0;

        var        astarNode = AstarPath.active.astarData.gridGraph.GetNearest(ConnectorsManager.StartConnector.transform.position).node;
        VectorInt2 nodeIndex = astarNode.position.ToVector3();
        var        node      = NodesGrid.Grid[nodeIndex.x, nodeIndex.y];

        GenerateRecursively(node, ConnectorsManager.StartConnector.CurrentDirection);

        int  i = 0;
        bool isAllConnected = false;

        while (i < 100 && isAllConnected == false)
        {
            RandomSafeRotateWithGenerationAllShapes();
            isAllConnected = ConnectorsManager.GetConnectedCount() == ConnectorsManager.TargetConnectors.Count();
            i++;
        }
        //if (isAllConnected)
        //    Debug.LogWarning("<color=green>AllConnected=true</color> iterations_count=" + i);


        RandomReplacementAllShapes();
        ShapesPathBaker.FindAndSavePath();

        FillEmptyNodes();

        RandomRotateAllShapes();
        //проверка, чтобы не был соединен ни один коннектор.
        while (ConnectorsManager.GetConnectedCount() > 0)
        {
            //Debug.LogWarning("<color=cyan>ConnectedCount>0</color>");
            RandomRotateAllShapes();
        }

        //EventMessenger.SendMessage(GameEvent.CompleteGeneration, null); //typeof(ShapesGenerator));
    }
    /// <summary>
    /// Рэндомная замена с проверкой существования пути
    /// </summary>
    private static void RandomReplacementAllShapes()
    {
        //количество подключенных коннекторов в начале этой функции
        int connectedConnectorsMaxCount = ConnectorsManager.GetConnectedCount();

        foreach (var node in NodesGrid.Grid)
        {
            if (node.Shape != null)
            {
                Direction currentDir       = node.Shape.CurrentDirection;
                Type      currentShapeType = node.Shape.GetType();

                RemoveShape(node);
                CreateRandomShape(node);

                //вращение с целью попытаться соединить ноду с другими
                int connectedCount = ConnectorsManager.GetConnectedCount();
                int i = 0;
                while (i < 3 && connectedCount < connectedConnectorsMaxCount)
                {
                    node.Shape.FastRotate();
                    connectedCount = ConnectorsManager.GetConnectedCount();
                    i++;
                }

                //возврат к состоянию до рендома
                if (connectedCount < connectedConnectorsMaxCount)
                {
                    RemoveShape(node);
                    CreateShape(node, currentShapeType);
                    node.Shape.FastRotateToDirection(currentDir);
                }

                connectedConnectorsMaxCount = Mathf.Max(connectedConnectorsMaxCount, connectedCount);
            }
        }
    }