#rem True Prim's Algorithm - Maze From the book - Mazes for programmers - #end Import mojo Class cell Field x:Int,y:Int Field north:Bool,east:Bool Field south:Bool,west:Bool Field visited:Bool=False Field value:Int Method New(x:Int,y:Int) Self.x = x Self.y = y End Method End Class Class trueprimsmaze Field width:Int,height:Int Field tilewidth:Float,tileheight:Float Field map:cell[][] Method New(mazewidth:Int,mazeheight:Int,sw:Int,sh:Int) Self.width = mazewidth Self.height = mazeheight map = New cell[width][] For Local i=0 Until width map[i] = New cell[height] Next For Local y=0 Until height For Local x=0 Until width map[x][y] = New cell Next Next tilewidth = Float(sw)/Float(mazewidth) tileheight = Float(sh)/Float(mazeheight) trueprimsmaze End Method ' ' This method creates the maze ' ' You have a list for neighbors. You put ' a start position in the list from the map. ' On the map each cell has a random value. ' We pick a cell from the neighbor list with the lowest ' value. We then create a list with the directions around ' the current position if they are unvisited. ' We select to carve into this new direction. The one ' With the lowest value. Put the new position on the neighbor ' list. ' If there was no direction to go around the current cell ' then remove this position from the neighbor list. ' When the list is empty then the maze is done. ' Method trueprimsmaze() ' This is the list with neighbor cells Local availneighbors:Stack<cell> = New Stack<cell> ' Put a random value on each of the cells in the map. For Local y=0 Until height For Local x=0 Until width map[x][y].value = Rnd(0,100) Next Next ' These hold the start position Local x:Int,y:Int ' Find start position. The position on the map ' with the lowest value Local lowest:Int=100 For Local y1=0 Until height For Local x1=0 Until width If map[x1][y1].value < lowest Then x = x1 y = y1 lowest = map[x1][y1].value End If Next Next ' push to the neighbor list availneighbors.Push(New cell(x,y)) availneighbors.Top.value = map[x][y].value ' mark visited map[x][y].visited = True ' loop until the list is emtpy While availneighbors.IsEmpty = False ' get the position on the map with the lowest ' value. Local lowest:Int=100 ' We need to remember the item position on the list ' we select. So we can delete it later on. Local itemtodelete:Int For Local i = 0 Until availneighbors.Length If availneighbors.Get(i).value < lowest lowest = availneighbors.Get(i).value x = availneighbors.Get(i).x y = availneighbors.Get(i).y itemtodelete = i End If Next ' make list for positions around the current cell Local dirs:Stack<Int> = New Stack<Int> ' put cells on the dirs list if unvisited and ' on the map. If y-1 >= 0 And map[x][y-1].visited = False Then dirs.Push(0) If x+1 < width And map[x+1][y].visited = False Then dirs.Push(1) If y+1 < height And map[x][y+1].visited = False Then dirs.Push(2) If x-1 >= 0 And map[x-1][y].visited = False Then dirs.Push(3) ' if there are directions we can go into If dirs.Length > 0 ' from all positions around the current cell ' select the direction with the lowest value Local s:Int=-1 Local lowest:Int=500 For Local i = 0 Until dirs.Length If dirs.Get(i) = 0 If map[x][y-1].value < lowest Then lowest = map[x][y-1].value s = 0 End If End If If dirs.Get(i) = 1 If map[x+1][y].value < lowest Then lowest = map[x+1][y].value s = 1 End If End If If dirs.Get(i) = 2 If map[x][y+1].value < lowest Then lowest = map[x][y+1].value s = 2 End If End If If dirs.Get(i) = 3 If map[x-1][y].value < lowest Then lowest = map[x-1][y].value s = 3 End If End If Next ' carve into direction and set x,y with new value Select s Case 0'north map[x][y].north = True y-=1 map[x][y].south = True Case 1'east map[x][y].east = True x+=1 map[x][y].west = True Case 2'south map[x][y].south = True y+=1 map[x][y].north = True Case 3'west map[x][y].west = True x-=1 map[x][y].east = True End Select ' mark new position as visited map[x][y].visited = True ' push new position to the availneighbors ' list availneighbors.Push(New cell(x,y)) ' Set the value of the item availneighbors.Top.value = map[x][y].value Else ' if no neighbors then remove active item from ' availneighbors list availneighbors.Remove(itemtodelete) End If Wend End Method ' ' Draw the maze ' Method draw() For Local y=0 Until height For Local x=0 Until width Local x1:Int=x*tilewidth Local y1:Int=y*tileheight SetColor 255,255,255 If map[x][y].north = False DrawLine x1,y1,x1+tilewidth,y1 End If If map[x][y].east = False DrawLine x1+tilewidth,y1,x1+tilewidth,y1+tileheight End If If map[x][y].south = False DrawLine x1,y1+tileheight,x1+tilewidth,y1+tileheight End If If map[x][y].west = False DrawLine x1,y1,x1,y1+tileheight End If Next Next End Method End Class Global maze:trueprimsmaze Class MyGame Extends App Method OnCreate() SetUpdateRate(1) maze = New trueprimsmaze(10,10,500,400) End Method Method OnUpdate() If MouseHit(MOUSE_LEFT) maze = New trueprimsmaze(10,10,500,400) End If End Method Method OnRender() Cls 0,0,0 SetColor 255,255,255 maze.draw DrawText "True Prim's Algorithm Maze",0,480-40 DrawText "Press Mouse or Touch to create new maze",0,480-20 End Method End Class Function Main() New MyGame() End Function
Artificial intelligence/templates/examples/rts/rpg/strategy ect. in MonkeyX/CerberusX language. You can download the free version of MonkeyX from itch.io or Cerberus-x.com The Flash applets will stop working in around 2020.
Thursday, April 13, 2017
Monkey-X - Maze - True Prim's Algorithm - code example
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.