private int checkCrossing(QVector2Int currentPosition, QVector2Int newPosition, List <QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.Crossing).frequency&&
                newPositionOutputs != null &&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 2 &&
                !newPositionOutputs[0].outputDirList.Contains(dir) &&
                !newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                QVector2Int newPosition2 = newPosition.clone();
                newPosition2.x += QMazeOutput.dx[dir];
                newPosition2.y += QMazeOutput.dy[dir];

                if (pointInMaze(newPosition2) &&
                    mazeArray[newPosition2.x][newPosition2.y] == null)
                {
                    QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                    output.outputDirList.Add(dir);

                    mazeArray[newPosition.x][newPosition.y][0].outputDirList.Add(dir);
                    mazeArray[newPosition.x][newPosition.y][0].outputDirList.Add(QMazeOutput.opposite[dir]);

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir]);
                    mazeArray[newPosition2.x][newPosition2.y] = new List <QMazeOutput>();
                    mazeArray[newPosition2.x][newPosition2.y].Add(output);

                    path.Add(new QVector2Int(newPosition2.x, newPosition2.y));
                    lastDirection = dir;

                    return(CHECK_BREAK);
                }
            }
            return(CHECK_FAILED);
        }
        public bool pointInMaze(QVector2Int point)
        {
            bool inMaze        = point.x >= 0 && point.x < mazeWidth && point.y >= 0 && point.y < mazeHeight;
            bool notInObstacle = !QListUtil.has(obstaclePointList, point);

            return(inMaze && notInObstacle);
        }
Пример #3
0
        public float sqrMagnitude(QVector2Int otherPoint)
        {
            float tx = x - otherPoint.x;
            float ty = y - otherPoint.y;

            return(tx * tx + ty * ty);
        }
 public void setPositionOnPiece(QVector2Int piecePosition)
 {
     Vector3 pos = currentPosition;
     pos.x = piecePosition.x;
     pos.z = - piecePosition.y;
     currentPosition = checkPosition(pos);
     targetPosition = currentPosition;
 }
Пример #5
0
 public static bool has(List <QVector2Int> list, QVector2Int element)
 {
     List <QVector2Int> .Enumerator listEnumerator = list.GetEnumerator();
     while (listEnumerator.MoveNext())
     {
         if (listEnumerator.Current.equal(element))
         {
             return(true);
         }
     }
     return(false);
 }
Пример #6
0
 public static QVector2IntDir get(List <QVector2IntDir> list, QVector2Int element)
 {
     List <QVector2IntDir> .Enumerator listEnumerator = list.GetEnumerator();
     while (listEnumerator.MoveNext())
     {
         if (listEnumerator.Current.equal(element))
         {
             return(listEnumerator.Current);
         }
     }
     return(null);
 }
        private int checkDoubleCorner(QVector2Int currentPosition, QVector2Int newPosition, List <QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.DoubleCorner).frequency&&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 2 &&
                newPositionOutputs[0].outputDirList.Contains(dir) &&
                !newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                QVector2Int newPos1 = new QVector2Int(newPosition.x + QMazeOutput.dx[QMazeOutput.rotateCW[dir]],
                                                      newPosition.y + QMazeOutput.dy[QMazeOutput.rotateCW[dir]]);
                QVector2Int newPos2 = new QVector2Int(newPosition.x + QMazeOutput.dx[QMazeOutput.rotateCCW[dir]],
                                                      newPosition.y + QMazeOutput.dy[QMazeOutput.rotateCCW[dir]]);

                if ((pointInMaze(newPos1) && mazeArray[newPos1.x][newPos1.y] == null && newPositionOutputs[0].outputDirList.Contains(QMazeOutput.rotateCCW[dir])) ||
                    (pointInMaze(newPos2) && mazeArray[newPos2.x][newPos2.y] == null && newPositionOutputs[0].outputDirList.Contains(QMazeOutput.rotateCW [dir])))
                {
                    QMazeOutputDirection dir2 = dir;

                    QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                    output.outputDirList.Add(dir);

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir]);
                    if (!mazeArray[newPosition.x][newPosition.y][0].outputDirList.Contains(QMazeOutput.rotateCW[dir]))
                    {
                        output.outputDirList.Add(QMazeOutput.rotateCW[dir]);
                        dir2 = QMazeOutput.rotateCW[dir];
                    }
                    else
                    {
                        output.outputDirList.Add(QMazeOutput.rotateCCW[dir]);
                        dir2 = QMazeOutput.rotateCCW[dir];
                    }
                    mazeArray[newPosition.x][newPosition.y].Add(output);

                    newPosition.x += QMazeOutput.dx[dir2];
                    newPosition.y += QMazeOutput.dy[dir2];

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir2]);
                    mazeArray[newPosition.x][newPosition.y] = new List <QMazeOutput>();
                    mazeArray[newPosition.x][newPosition.y].Add(output);

                    path.Add(new QVector2Int(newPosition.x, newPosition.y));
                    lastDirection = dir2;

                    return(CHECK_BREAK);
                }
            }
            return(CHECK_FAILED);
        }
        private int checkTripple(QVector2Int currentPosition, QVector2Int newPosition, List <QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.Triple).frequency&&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 2 &&
                newPositionOutputs[0].outputDirList.Contains(dir) &&
                !newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                output.outputDirList.Add(dir);

                newPositionOutputs[newPositionOutputs.Count - 1].outputDirList.Add(QMazeOutput.opposite[dir]);

                return(CHECK_CONTINUE);
            }
            return(CHECK_FAILED);
        }
 private void generateFinishPoint()
 {
     if (generateFinishCount > 0)
     {
         finishPointList.Clear();
     }
     for (int i = 0; i < generateFinishCount; i++)
     {
         QVector2Int newFinishPoint = new QVector2Int(QMath.getRandom(0, mazeWidth), QMath.getRandom(0, mazeHeight));
         while (QListUtil.has(startPointList, newFinishPoint) || QListUtil.has(finishPointList, newFinishPoint))
         {
             newFinishPoint.x = QMath.getRandom(0, mazeWidth);
             newFinishPoint.y = QMath.getRandom(0, mazeHeight);
         }
         finishPointList.Add(newFinishPoint);
     }
 }
        private bool showVector2IntList(List <QVector2Int> list, bool foldout)
        {
            int count = EditorGUILayout.IntField("Count", list.Count);

            if (count < 0)
            {
                count = 0;
            }
            if (count != list.Count)
            {
                while (count > list.Count)
                {
                    list.Add(new QVector2IntDir(0, 0, QMazeOutputDirection.NotSpecified));
                }
                if (count < list.Count)
                {
                    list.RemoveRange(count, list.Count - count);
                }
            }

            if (count > 0)
            {
                EditorGUI.indentLevel++;
                foldout = EditorGUILayout.Foldout(foldout, "Position List");
                if (foldout)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        QVector2Int element = list[i];

                        EditorGUILayout.LabelField("Position " + (i + 1));
                        EditorGUI.indentLevel++;

                        element.x = EditorGUILayout.IntField("X", element.x);
                        element.y = EditorGUILayout.IntField("Y", element.y);

                        EditorGUI.indentLevel--;
                    }
                }
                EditorGUI.indentLevel--;
            }

            return(foldout);
        }
        private int checkCornerDeadlock2(QVector2Int currentPosition, QVector2Int newPosition, List <QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.CornerDeadlock2).frequency&&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 2 &&
                newPositionOutputs[0].outputDirList.Contains(dir) &&
                newPositionOutputs[0].outputDirList.Contains(QMazeOutput.rotateCCW[dir]))
            {
                QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                output.outputDirList.Add(dir);

                output = new QMazeOutput();
                output.outputDirList.Add(QMazeOutput.opposite[dir]);
                mazeArray[newPosition.x][newPosition.y].Add(output);

                return(CHECK_CONTINUE);
            }
            return(CHECK_FAILED);
        }
        private int checkStandard(QVector2Int currentPosition, QVector2Int newPosition, List <QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (mazeArray[newPosition.x][newPosition.y] == null)
            {
                QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                output.outputDirList.Add(dir);

                output = new QMazeOutput();
                output.outputDirList.Add(QMazeOutput.opposite[dir]);
                mazeArray[newPosition.x][newPosition.y] = new List <QMazeOutput>();
                mazeArray[newPosition.x][newPosition.y].Add(output);

                path.Add(new QVector2Int(newPosition.x, newPosition.y));
                lastDirection = dir;

                return(CHECK_BREAK);
            }
            return(CHECK_FAILED);
        }
        private int checkEmpty(QVector2Int currentPosition, QVector2Int newPosition, List <QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.Empty).frequency&&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 1 &&
                newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                newPositionOutputs.Clear();
                newPositionOutputs.Add(new QMazeOutput());

                List <QMazeOutput> currentOutputs = mazeArray[currentPosition.x][currentPosition.y];
                for (int i = 0; i < currentOutputs.Count; i++)
                {
                    currentOutputs[i].outputDirList.Remove(dir);
                }

                return(CHECK_BREAK);
            }
            return(CHECK_FAILED);
        }
        private int checkStartFinishPoint(QVector2Int currentPosition, QVector2Int newPosition, List <QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QListUtil.has(startPointList, newPosition) || QListUtil.has(finishPointList, newPosition))
            {
                if (mazeArray[newPosition.x][newPosition.y] == null)
                {
                    QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                    output.outputDirList.Add(dir);

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir]);
                    mazeArray[newPosition.x][newPosition.y] = new List <QMazeOutput>();
                    mazeArray[newPosition.x][newPosition.y].Add(output);
                }
                return(CHECK_CONTINUE);
            }
            else if (QListUtil.has(startPointList, currentPosition) || QListUtil.has(finishPointList, currentPosition))
            {
                return(CHECK_BREAK);
            }
            return(CHECK_FAILED);
        }
        private IEnumerator generate(bool generateWithGeometry = true, bool asynchronous = true, float maxTime = 0.1f)
        {
            generationProgress = 0;

            generateStartPoint();
            generateFinishPoint();

            QVector2Int startGenerationPoint = new QVector2Int(QMath.getRandom(0, mazeWidth), QMath.getRandom(0, mazeHeight));
            while (QListUtil.has(startPointList, startGenerationPoint) ||
                   QListUtil.has(finishPointList, startGenerationPoint) ||
                   QListUtil.has(obstaclePointList, startGenerationPoint))
            {
                startGenerationPoint.x = QMath.getRandom(0, mazeWidth);
                startGenerationPoint.y = QMath.getRandom(0, mazeHeight);
            }

            path = new List<QVector2Int>();
            mazeArray = new List<QMazeOutput>[mazeWidth][];
            for (int px = 0; px < mazeWidth; px++) mazeArray[px] = new List<QMazeOutput>[mazeHeight];

            lastDirection = QMazeOutputDirection.None;
            QVector2Int currentPosition = new QVector2Int(startGenerationPoint.x, startGenerationPoint.y);

            QMazeOutput output = new QMazeOutput();
            mazeArray[currentPosition.x][currentPosition.y] = new List<QMazeOutput>();
            mazeArray[currentPosition.x][currentPosition.y].Add(output);

            path.Add(new QVector2Int(currentPosition.x, currentPosition.y));

            checkTaskList.Clear();
            if (startPointList.Count > 0 || finishPointList.Count > 0) checkTaskList.Add(checkStartFinishPoint);
            checkTaskList.Add(checkStandard);
            if (piecePack.getPiece(QMazePieceType.Intersection		  ).use) checkTaskList.Add(checkUnder);
            if (piecePack.getPiece(QMazePieceType.Crossing			  ).use && !onlyWay) checkTaskList.Add(checkCrossing);
            if (piecePack.getPiece(QMazePieceType.Triple			  ).use && !onlyWay) checkTaskList.Add(checkTripple);
            if (piecePack.getPiece(QMazePieceType.DoubleCorner		  ).use) checkTaskList.Add(checkDoubleCorner);
            if (piecePack.getPiece(QMazePieceType.DeadlockCorner	  ).use) checkTaskList.Add(checkDeadlockCorner);
            if (piecePack.getPiece(QMazePieceType.DeadlockLine	      ).use) checkTaskList.Add(checkDeadlockLine);
            if (piecePack.getPiece(QMazePieceType.DeadlockTriple	  ).use) checkTaskList.Add(checkDeadlockTriple);
            if (piecePack.getPiece(QMazePieceType.DeadlockCrossing	  ).use) checkTaskList.Add(checkDeadlockCrossing);
            if (piecePack.getPiece(QMazePieceType.TripleDeadlock	  ).use) checkTaskList.Add(checkTripleDeadlock);
            if (piecePack.getPiece(QMazePieceType.LineDeadlock		  ).use) checkTaskList.Add(checkLineDeadlock);
            if (piecePack.getPiece(QMazePieceType.LineDeadlockLine	  ).use) checkTaskList.Add(checkLineDeadlockLine);
            if (piecePack.getPiece(QMazePieceType.CornerDeadlock1	  ).use) checkTaskList.Add(checkCornerDeadlock1);
            if (piecePack.getPiece(QMazePieceType.CornerDeadlock2	  ).use) checkTaskList.Add(checkCornerDeadlock2);
            if (piecePack.getPiece(QMazePieceType.CornerDeadlockCorner).use) checkTaskList.Add(checkCornerDeadlockCorner);
            if (piecePack.getPiece(QMazePieceType.Empty				  ).use) checkTaskList.Add(checkEmpty);

            float time = Time.realtimeSinceStartup;

            do
            {
                int lastPathIndex = path.Count - 1;
                currentPosition.set(path[lastPathIndex].x, path[lastPathIndex].y);

                lastDirection = QMazeOutputDirection.None;
                QMazeOutput outputArray = QMazeOutput.getShuffleOutput();

                foreach (QMazeOutputDirection dir in outputArray.outputDirList)
                {
                    QVector2Int newPosition = new QVector2Int(currentPosition.x + QMazeOutput.dx[dir], currentPosition.y + QMazeOutput.dy[dir]);
                    if (pointInMaze(newPosition))
                    {
                        if (mazeArray[currentPosition.x][currentPosition.y].Count == 1)
                        {
                            List<QMazeOutput> newPositionOutputs = mazeArray[newPosition.x][newPosition.y];

                            int checkResult = 0;
                            for (int i = 0; i < checkTaskList.Count; i++)
                            {
                                CheckTask checkTask = checkTaskList[i];
                                checkResult = checkTask(currentPosition, newPosition, newPositionOutputs, dir);
                                if (checkResult != CHECK_FAILED) break;
                            }

                            if (checkResult == CHECK_CONTINUE) continue;
                            if (checkResult == CHECK_BREAK)
                            {
                                generationProgress++;
                                break;
                            }
                        }
                    }
                    else if (QListUtil.has(exitPointList, newPosition))
                    {
                        if (!mazeArray[currentPosition.x][currentPosition.y][0].outputDirList.Contains(dir))
                            mazeArray[currentPosition.x][currentPosition.y][0].outputDirList.Add(dir);
                    }
                }

                if (lastDirection == QMazeOutputDirection.None)
                    path.RemoveAt(path.Count - 1);

                if (asynchronous && Time.realtimeSinceStartup - time > maxTime)
                {
                    time = Time.realtimeSinceStartup;
                    yield return null;
                }
            }
            while (path.Count > 0);

            if (generateWithGeometry && mazeGeometryGenerator != null)
            {
                if (asynchronous)
                {
                    yield return StartCoroutine(mazeGeometryGenerator.generateGeometry(this, mazeArray, maxTime));
                }
                else
                {
                    IEnumerator geometryCreatorEnumerator = mazeGeometryGenerator.generateGeometry(this, mazeArray, maxTime);
                    while (geometryCreatorEnumerator.MoveNext());
                }
            }
        }
        private int checkUnder(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.Intersection).frequency &&
                newPositionOutputs != null &&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 2 &&
                !newPositionOutputs[0].outputDirList.Contains(dir) &&
                !newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                QVector2Int newPosition2 = newPosition.clone();
                newPosition2.x += QMazeOutput.dx[dir];
                newPosition2.y += QMazeOutput.dy[dir];

                if (pointInMaze(newPosition2) &&
                    mazeArray[newPosition2.x][newPosition2.y] == null)
                {
                    QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                    output.outputDirList.Add(dir);

                    output = new QMazeOutput();
                    output.outputDirList.Add(dir);
                    output.outputDirList.Add(QMazeOutput.opposite[dir]);
                    mazeArray[newPosition.x][newPosition.y].Add(output);

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir]);
                    mazeArray[newPosition2.x][newPosition2.y] = new List<QMazeOutput>();
                    mazeArray[newPosition2.x][newPosition2.y].Add(output);

                    path.Add(new QVector2Int(newPosition2.x, newPosition2.y));
                    lastDirection = dir;

                    return CHECK_BREAK;
                }
            }
            return CHECK_FAILED;
        }
        private int checkTripple(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.Triple).frequency &&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 2 &&
                newPositionOutputs[0].outputDirList.Contains(dir) &&
                !newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                output.outputDirList.Add(dir);

                newPositionOutputs[newPositionOutputs.Count - 1].outputDirList.Add(QMazeOutput.opposite[dir]);

                return CHECK_CONTINUE;
            }
            return CHECK_FAILED;
        }
        private int checkStartFinishPoint(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QListUtil.has(startPointList, newPosition) || QListUtil.has(finishPointList, newPosition))
            {
                if (mazeArray[newPosition.x][newPosition.y] == null)
                {
                    QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                    output.outputDirList.Add(dir);

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir]);
                    mazeArray[newPosition.x][newPosition.y] = new List<QMazeOutput>();
                    mazeArray[newPosition.x][newPosition.y].Add(output);
                }
                return CHECK_CONTINUE;
            }
            else if (QListUtil.has(startPointList, currentPosition) || QListUtil.has(finishPointList, currentPosition))
            {
                return CHECK_BREAK;
            }
            return CHECK_FAILED;
        }
        private int checkStandard(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (mazeArray[newPosition.x][newPosition.y] == null)
            {
                QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                output.outputDirList.Add(dir);

                output = new QMazeOutput();
                output.outputDirList.Add(QMazeOutput.opposite[dir]);
                mazeArray[newPosition.x][newPosition.y] = new List<QMazeOutput>();
                mazeArray[newPosition.x][newPosition.y].Add(output);

                path.Add(new QVector2Int(newPosition.x, newPosition.y));
                lastDirection = dir;

                return CHECK_BREAK;
            }
            return CHECK_FAILED;
        }
Пример #20
0
 public override bool equal(QVector2Int otherPoint)
 {
     return(x == otherPoint.x && y == otherPoint.y);
 }
 public bool equal(QVector2Int otherPoint)
 {
     return x == otherPoint.x && y == otherPoint.y;
 }
 private void generateStartPoint()
 {
     if (generateStartCount > 0) startPointList.Clear();
     for (int i = 0; i < generateStartCount; i++)
     {
         QVector2Int newStartPoint = new QVector2Int(QMath.getRandom(0, mazeWidth), QMath.getRandom(0, mazeHeight));
         while (QListUtil.has(startPointList, newStartPoint) || QListUtil.has(finishPointList, newStartPoint))
         {
             newStartPoint.x = QMath.getRandom(0, mazeWidth);
             newStartPoint.y = QMath.getRandom(0, mazeHeight);
         }
         startPointList.Add(newStartPoint);
     }
 }
 public float sqrMagnitude(QVector2Int otherPoint)
 {
     float tx = x - otherPoint.x;
     float ty = y - otherPoint.y;
     return tx * tx + ty * ty;
 }
 public bool pointInMaze(QVector2Int point)
 {
     bool inMaze = point.x >= 0 && point.x < mazeWidth && point.y >= 0 && point.y < mazeHeight;
     bool notInObstacle = !QListUtil.has(obstaclePointList, point);
     return inMaze && notInObstacle;
 }
        private int checkDoubleCorner(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.DoubleCorner).frequency &&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 2 &&
                newPositionOutputs[0].outputDirList.Contains(dir) &&
                !newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                QVector2Int newPos1 = new QVector2Int(newPosition.x + QMazeOutput.dx[QMazeOutput.rotateCW[dir]],
                                                      newPosition.y + QMazeOutput.dy[QMazeOutput.rotateCW[dir]]);
                QVector2Int newPos2 = new QVector2Int(newPosition.x + QMazeOutput.dx[QMazeOutput.rotateCCW[dir]],
                                                      newPosition.y + QMazeOutput.dy[QMazeOutput.rotateCCW[dir]]);

                if ((pointInMaze(newPos1) && mazeArray[newPos1.x][newPos1.y] == null && newPositionOutputs[0].outputDirList.Contains(QMazeOutput.rotateCCW[dir])) ||
                    (pointInMaze(newPos2) && mazeArray[newPos2.x][newPos2.y] == null && newPositionOutputs[0].outputDirList.Contains(QMazeOutput.rotateCW [dir])))
                {
                    QMazeOutputDirection dir2 = dir;

                    QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                    output.outputDirList.Add(dir);

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir]);
                    if (!mazeArray[newPosition.x][newPosition.y][0].outputDirList.Contains(QMazeOutput.rotateCW[dir]))
                    {
                        output.outputDirList.Add(QMazeOutput.rotateCW[dir]);
                        dir2 = QMazeOutput.rotateCW[dir];
                    }
                    else
                    {
                        output.outputDirList.Add(QMazeOutput.rotateCCW[dir]);
                        dir2 = QMazeOutput.rotateCCW[dir];
                    }
                    mazeArray[newPosition.x][newPosition.y].Add(output);

                    newPosition.x += QMazeOutput.dx[dir2];
                    newPosition.y += QMazeOutput.dy[dir2];

                    output = new QMazeOutput();
                    output.outputDirList.Add(QMazeOutput.opposite[dir2]);
                    mazeArray[newPosition.x][newPosition.y] = new List<QMazeOutput>();
                    mazeArray[newPosition.x][newPosition.y].Add(output);

                    path.Add(new QVector2Int(newPosition.x, newPosition.y));
                    lastDirection = dir2;

                    return CHECK_BREAK;
                }
            }
            return CHECK_FAILED;
        }
Пример #26
0
 public virtual bool equal(QVector2Int otherPoint)
 {
     return(x == otherPoint.x && y == otherPoint.y);
 }
        private int checkEmpty(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.Empty).frequency &&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 1 &&
                newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]))
            {
                newPositionOutputs.Clear();
                newPositionOutputs.Add(new QMazeOutput());

                List<QMazeOutput> currentOutputs = mazeArray[currentPosition.x][currentPosition.y];
                for (int i = 0; i < currentOutputs.Count; i++)
                {
                    currentOutputs[i].outputDirList.Remove(dir);
                }

                return CHECK_BREAK;
            }
            return CHECK_FAILED;
        }
        private int checkLineDeadlockLine(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.LineDeadlockLine).frequency &&
                newPositionOutputs != null &&
                newPositionOutputs.Count == 2 &&
                !newPositionOutputs[0].outputDirList.Contains(QMazeOutput.opposite[dir]) &&
                !newPositionOutputs[1].outputDirList.Contains(QMazeOutput.opposite[dir]) &&
                ((newPositionOutputs[0].outputDirList.Count == 2 && newPositionOutputs[1].outputDirList.Count == 1 && newPositionOutputs[0].outputDirList[0] == QMazeOutput.opposite[newPositionOutputs[0].outputDirList[1]]) ||
                 (newPositionOutputs[0].outputDirList.Count == 1 && newPositionOutputs[1].outputDirList.Count == 2 && newPositionOutputs[1].outputDirList[0] == QMazeOutput.opposite[newPositionOutputs[1].outputDirList[1]])))
            {
                QMazeOutput output = mazeArray[currentPosition.x][currentPosition.y][mazeArray[currentPosition.x][currentPosition.y].Count - 1];
                output.outputDirList.Add(dir);

                output = new QMazeOutput();
                output.outputDirList.Add(QMazeOutput.opposite[dir]);
                mazeArray[newPosition.x][newPosition.y].Add(output);

                return CHECK_CONTINUE;
            }
            return CHECK_FAILED;
        }
        private IEnumerator generate(bool generateWithGeometry = true, bool asynchronous = true, float maxTime = 0.1f)
        {
            generationProgress = 0;

            generateStartPoint();
            generateFinishPoint();

            QVector2Int startGenerationPoint = new QVector2Int(QMath.getRandom(0, mazeWidth), QMath.getRandom(0, mazeHeight));

            while (QListUtil.has(startPointList, startGenerationPoint) ||
                   QListUtil.has(finishPointList, startGenerationPoint) ||
                   QListUtil.has(obstaclePointList, startGenerationPoint))
            {
                startGenerationPoint.x = QMath.getRandom(0, mazeWidth);
                startGenerationPoint.y = QMath.getRandom(0, mazeHeight);
            }

            path      = new List <QVector2Int>();
            mazeArray = new List <QMazeOutput> [mazeWidth][];
            for (int px = 0; px < mazeWidth; px++)
            {
                mazeArray[px] = new List <QMazeOutput> [mazeHeight];
            }

            lastDirection = QMazeOutputDirection.None;
            QVector2Int currentPosition = new QVector2Int(startGenerationPoint.x, startGenerationPoint.y);

            QMazeOutput output = new QMazeOutput();

            mazeArray[currentPosition.x][currentPosition.y] = new List <QMazeOutput>();
            mazeArray[currentPosition.x][currentPosition.y].Add(output);

            path.Add(new QVector2Int(currentPosition.x, currentPosition.y));

            checkTaskList.Clear();
            if (startPointList.Count > 0 || finishPointList.Count > 0)
            {
                checkTaskList.Add(checkStartFinishPoint);
            }
            checkTaskList.Add(checkStandard);
            if (piecePack.getPiece(QMazePieceType.Intersection).use)
            {
                checkTaskList.Add(checkUnder);
            }
            if (piecePack.getPiece(QMazePieceType.Crossing).use&& !onlyWay)
            {
                checkTaskList.Add(checkCrossing);
            }
            if (piecePack.getPiece(QMazePieceType.Triple).use&& !onlyWay)
            {
                checkTaskList.Add(checkTripple);
            }
            if (piecePack.getPiece(QMazePieceType.DoubleCorner).use)
            {
                checkTaskList.Add(checkDoubleCorner);
            }
            if (piecePack.getPiece(QMazePieceType.DeadlockCorner).use)
            {
                checkTaskList.Add(checkDeadlockCorner);
            }
            if (piecePack.getPiece(QMazePieceType.DeadlockLine).use)
            {
                checkTaskList.Add(checkDeadlockLine);
            }
            if (piecePack.getPiece(QMazePieceType.DeadlockTriple).use)
            {
                checkTaskList.Add(checkDeadlockTriple);
            }
            if (piecePack.getPiece(QMazePieceType.DeadlockCrossing).use)
            {
                checkTaskList.Add(checkDeadlockCrossing);
            }
            if (piecePack.getPiece(QMazePieceType.TripleDeadlock).use)
            {
                checkTaskList.Add(checkTripleDeadlock);
            }
            if (piecePack.getPiece(QMazePieceType.LineDeadlock).use)
            {
                checkTaskList.Add(checkLineDeadlock);
            }
            if (piecePack.getPiece(QMazePieceType.LineDeadlockLine).use)
            {
                checkTaskList.Add(checkLineDeadlockLine);
            }
            if (piecePack.getPiece(QMazePieceType.CornerDeadlock1).use)
            {
                checkTaskList.Add(checkCornerDeadlock1);
            }
            if (piecePack.getPiece(QMazePieceType.CornerDeadlock2).use)
            {
                checkTaskList.Add(checkCornerDeadlock2);
            }
            if (piecePack.getPiece(QMazePieceType.CornerDeadlockCorner).use)
            {
                checkTaskList.Add(checkCornerDeadlockCorner);
            }
            if (piecePack.getPiece(QMazePieceType.Empty).use)
            {
                checkTaskList.Add(checkEmpty);
            }

            float time = Time.realtimeSinceStartup;

            do
            {
                int lastPathIndex = path.Count - 1;
                currentPosition.set(path[lastPathIndex].x, path[lastPathIndex].y);

                lastDirection = QMazeOutputDirection.None;
                QMazeOutput outputArray = QMazeOutput.getShuffleOutput();

                foreach (QMazeOutputDirection dir in outputArray.outputDirList)
                {
                    QVector2Int newPosition = new QVector2Int(currentPosition.x + QMazeOutput.dx[dir], currentPosition.y + QMazeOutput.dy[dir]);
                    if (pointInMaze(newPosition))
                    {
                        if (mazeArray[currentPosition.x][currentPosition.y].Count == 1)
                        {
                            List <QMazeOutput> newPositionOutputs = mazeArray[newPosition.x][newPosition.y];

                            int checkResult = 0;
                            for (int i = 0; i < checkTaskList.Count; i++)
                            {
                                CheckTask checkTask = checkTaskList[i];
                                checkResult = checkTask(currentPosition, newPosition, newPositionOutputs, dir);
                                if (checkResult != CHECK_FAILED)
                                {
                                    break;
                                }
                            }

                            if (checkResult == CHECK_CONTINUE)
                            {
                                continue;
                            }
                            if (checkResult == CHECK_BREAK)
                            {
                                generationProgress++;
                                break;
                            }
                        }
                    }
                    else if (QListUtil.has(exitPointList, newPosition))
                    {
                        if (!mazeArray[currentPosition.x][currentPosition.y][0].outputDirList.Contains(dir))
                        {
                            mazeArray[currentPosition.x][currentPosition.y][0].outputDirList.Add(dir);
                        }
                    }
                }

                if (lastDirection == QMazeOutputDirection.None)
                {
                    path.RemoveAt(path.Count - 1);
                }

                if (asynchronous && Time.realtimeSinceStartup - time > maxTime)
                {
                    time = Time.realtimeSinceStartup;
                    yield return(null);
                }
            }while (path.Count > 0);

            if (generateWithGeometry && mazeGeometryGenerator != null)
            {
                if (asynchronous)
                {
                    yield return(StartCoroutine(mazeGeometryGenerator.generateGeometry(this, mazeArray, maxTime)));
                }
                else
                {
                    IEnumerator geometryCreatorEnumerator = mazeGeometryGenerator.generateGeometry(this, mazeArray, maxTime);
                    while (geometryCreatorEnumerator.MoveNext())
                    {
                        ;
                    }
                }
            }
        }