//... skipped
while (iCellCount < iTotalCells) { // get neighbor cells ... aCellDirections = myDungeon.getPossibleDirections(pCurrentCell); // set the cell if (aCellDirections.length != 0) { /* old way no direction modification used iRndCell = rnd.Range(0, (aCellNeighbors.length - 1)); iRndDir = Dir.getDirFromPoint(pCurrentCell, aCellNeighbors[iRndCell]); */ iRndDir = this.getFactoredRandomDir(iLastDir, aCellDirections, iDirChange); pNextCell = myDungeon.getNextPos(pCurrentCell, iRndDir); iLastDir = iRndDir; // remove walls myDungeon.cell(pCurrentCell).setWall (iRndDir, WallType.OPEN); // old way: myDungeon.cell(aCellNeighbors[iRndCell]).setWall(Dir.getOppositeDir(iRndDir), WallType.OPEN); myDungeon.cell(pNextCell).setWall(Dir.getOppositeDir(iRndDir), WallType.OPEN); // store for later use ... aCellStack.push(new Point(pCurrentCell.x, pCurrentCell.y)); // old way: pCurrentCell = new Point(aCellNeighbors[iRndCell].x, aCellNeighbors[iRndCell].y); pCurrentCell = new Point(pNextCell.x, pNextCell.y); iCellCount++; } else { pPopCell = aCellStack.pop(); pCurrentCell = new Point(pPopCell.x, pPopCell.y); } } // while
private function getFactoredRandomDir (iLastDir:int, aListDir:Array, iFactor:int = 50):int { var rnd:MersenneTwister = MersenneTwister.getInstance(); var bChangeDir:Boolean = (rnd.Range(0, 99) < iFactor); var iReturn:int = iLastDir; // the last used dir is not in the list of possible new directions, so we need to pick a random one ... if (aListDir.toString().lastIndexOf(iLastDir.toString()) == -1) { iReturn = aListDir[rnd.Range(0, (aListDir.length -1))]; } else { // we must change direction AND have at least 2 choices if (aListDir.length > 1) { if (bChangeDir) { while (iReturn == iLastDir) { iReturn = aListDir[rnd.Range(0, (aListDir.length -1))]; } } } else { // just pick what's left ... iReturn = aListDir[0]; } } return iReturn; }
public function removeDeadEnds (myDungeon:Dungeon, iRemoveDeadEnd:int = 20):Dungeon { var rnd:MersenneTwister = MersenneTwister.getInstance(); var i:int; var j:uint; var iDir:int; var iRndCell:int; var iDeadEndsToRemove:int = Math.ceil((myDungeon.iWidth * myDungeon.iHeight) * iRemoveDeadEnd / 100); var iDeadEndCount:int = 0; var bExit:Boolean = false; var aTmp:Array; // the worst case may only return one dead end per run, so // to be sure we run it as many times as we may max need for (i = 0; i < iDeadEndsToRemove; i++) { aTmp = myDungeon.getDeadEnds(); if (aTmp.length > 0 && !bExit) { while (aTmp.length > 0) { // this is to make sure that the cells are somewhat even // distributed if we do not use the whole lot iRndCell = rnd.Range(0, (aTmp.length - 1)); iDir = myDungeon.cell(aTmp[iRndCell]).getDeadEndDir(); myDungeon.cell(myDungeon.getNextPos(aTmp[iRndCell], iDir)).setWall(Dir.getOppositeDir(iDir), WallType.WALL); myDungeon.cell(aTmp[iRndCell]).setWalls(); aTmp.splice(iRndCell, 1); if (++iDeadEndCount >= iDeadEndsToRemove) { bExit = true; break; } } } else { break; } } return myDungeon; }
Disclaimer The opinions expressed herein are our own personal opinions and do not represent our client's views in any way.