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 static QMazeOutput getShuffleOutput()
 {
     QMazeOutput mazeOutput = new QMazeOutput();
     mazeOutput.outputDirList = new List<QMazeOutputDirection>();
     mazeOutput.outputDirList.Add(QMazeOutputDirection.N);
     mazeOutput.outputDirList.Add(QMazeOutputDirection.E);
     mazeOutput.outputDirList.Add(QMazeOutputDirection.S);
     mazeOutput.outputDirList.Add(QMazeOutputDirection.W);
     QListUtil.Shuffle(mazeOutput.outputDirList);
     return mazeOutput;
 }
예제 #3
0
        public static QMazeOutput getShuffleOutput()
        {
            QMazeOutput mazeOutput = new QMazeOutput();

            mazeOutput.outputDirList = new List <QMazeOutputDirection>();
            mazeOutput.outputDirList.Add(QMazeOutputDirection.N);
            mazeOutput.outputDirList.Add(QMazeOutputDirection.E);
            mazeOutput.outputDirList.Add(QMazeOutputDirection.S);
            mazeOutput.outputDirList.Add(QMazeOutputDirection.W);
            QListUtil.Shuffle(mazeOutput.outputDirList);
            return(mazeOutput);
        }
        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);
        }
예제 #5
0
        // PRIVATE
        private void rotate(List <QMazeOutput> sourceOutputs)
        {
            int sourceOutputsCount = sourceOutputs.Count;

            for (int i = 0; i < sourceOutputsCount; i++)
            {
                QMazeOutput sourceOutput = sourceOutputs[i];
                List <QMazeOutputDirection> directions = sourceOutput.outputDirList;
                int directionCount = directions.Count;
                for (int j = 0; j < directionCount; j++)
                {
                    directions[j] = QMazeOutput.rotateCW[directions[j]];
                }
            }
        }
        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 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 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 checkTripleDeadlock(QVector2Int currentPosition, QVector2Int newPosition, List<QMazeOutput> newPositionOutputs, QMazeOutputDirection dir)
        {
            if (QMath.getRandom() < piecePack.getPiece(QMazePieceType.TripleDeadlock).frequency &&
                newPositionOutputs != null &&
                newPositionOutputs.Count == 1 &&
                newPositionOutputs[0].outputDirList.Count == 3 &&
                !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);

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

                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;
        }
        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 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())
                    {
                        ;
                    }
                }
            }
        }