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 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 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()) { ; } } } }
public IEnumerator generateGeometry(QMazeEngine mazeEngine, List <QMazeOutput>[][] mazeArray, float maxTime = 0.1f) { Vector3 transformPosition = transform.position; Quaternion transformRotation = transform.rotation; transform.rotation = Quaternion.identity; float time = Time.realtimeSinceStartup; int mazeWidth = mazeEngine.mazeWidth; int mazeHeight = mazeEngine.mazeHeight; float mazeSize = mazeWidth * mazeHeight; float count = 0; instantiatingProgress = 0; bool wasError = false; QMazePiecePack piecePack = mazeEngine.piecePack; List <QMazePiece> pieces = piecePack.toMazePieceList(); for (int i = 0; i < pieces.Count; i++) { if ((!pieces[i].use && !pieces[i].require) || pieces[i].type == QMazePieceType.Start || pieces[i].type == QMazePieceType.Finish) { pieces.RemoveAt(i); i--; } } for (int ix = 0; ix < mazeWidth; ix++) { for (int iy = 0; iy < mazeHeight; iy++) { List <QMazeOutput> mazeOutputData = mazeArray[ix][iy]; QMazePiece targetPiece = null; if (QListUtil.has(mazeEngine.startPointList, ix, iy) && mazeOutputData != null && piecePack.getPiece(QMazePieceType.Start).checkFit(mazeOutputData)) { targetPiece = piecePack.getPiece(QMazePieceType.Start); } else if (QListUtil.has(mazeEngine.finishPointList, ix, iy) && mazeOutputData != null && piecePack.getPiece(QMazePieceType.Finish).checkFit(mazeOutputData)) { targetPiece = piecePack.getPiece(QMazePieceType.Finish); } else { QListUtil.Shuffle <QMazePiece>(pieces); for (int i = 0; i < pieces.Count; i++) { if (pieces[i].checkFit(mazeOutputData)) { targetPiece = pieces[i]; break; } } } if (targetPiece == null) { if (mazeEngine.pointInMaze(new QVector2Int(ix, iy)) || mazeEngine.obstacleIsEmpty) { targetPiece = piecePack.getPiece(QMazePieceType.Empty); } else { continue; } } else if (targetPiece.geometryList.Count == 0) { if (mazeEngine.pointInMaze(new QVector2Int(ix, iy))) { if (!wasError) { wasError = true; Debug.LogWarning("QMaze: Geometry for " + targetPiece.type + " piece is not found. Please check that geometry is specified for it in the piece pack."); } } continue; } GameObject prefab = targetPiece.geometryList[QMath.getRandom(0, targetPiece.geometryList.Count)]; GameObject go; #if UNITY_EDITOR if (Application.isPlaying) { go = (GameObject)GameObject.Instantiate(prefab, new Vector3(), Quaternion.AngleAxis(randomPiecesRotation ? ((int)(UnityEngine.Random.value * 360 / 90)) * 90 : -targetPiece.getRotation(), Vector3.up)); } else { go = (GameObject)PrefabUtility.InstantiatePrefab(prefab); go.transform.rotation = Quaternion.AngleAxis(randomPiecesRotation ? ((int)(UnityEngine.Random.value * 360 / 90)) * 90 : -targetPiece.getRotation(), Vector3.up); } #else go = (GameObject)GameObject.Instantiate(prefab, new Vector3(), Quaternion.AngleAxis(randomPiecesRotation ? ((int)(UnityEngine.Random.value * 360 / 90)) * 90 : -targetPiece.getRotation(), Vector3.up)); #endif go.transform.position = transformPosition + new Vector3(ix * mazeEngine.mazePieceWidth, 0, -iy * mazeEngine.mazePieceHeight); Vector3 scale = go.transform.localScale; go.transform.parent = transform; go.transform.localScale = scale; count++; instantiatingProgress = count / mazeSize; if (Time.realtimeSinceStartup - time > maxTime) { time = Time.realtimeSinceStartup; yield return(null); } } } transform.rotation = transformRotation; }