Sub AddWallToList
' param col, row - cell
' return nWalls - number of wall list
' return iWalls - index of wall list
' return colWalls[], rowWalls[] - wall list
' return colOpp[], rowOpp[] - cell list (on the opposite side)
For d = 0 To 3
colw = col + colAdj[d]
roww = row + rowAdj[d]
If 1 < colw And colw < cols And 1 < roww And roww < rows And cell[roww][colw] = WALL Then
i = colw + (roww - 1) * cols
' find i in wall list
FindWallInList()
If i = iFound Then ' found
' remove the wall
nWalls = nWalls - 1
iWalls[iPrev] = iWalls[iFound]
Else
' add the wall to wall list
nWalls = nWalls + 1
iNext = iWalls[0]
iWalls[0] = i
iWalls[i] = iNext
colWall[i] = colw ' wall
rowWall[i] = roww
colOpp[i] = colw + colAdj[d] ' cell on the opposite side
rowOpp[i] = roww + rowAdj[d]
colPath[i] = col ' for graph
rowPath[i] = row ' for graph
EndIf
EndIf
EndFor
EndSub
Sub BreadthFirstSearch
' param root - root number
visited = ""
Queue_Init()
node = root
Queue_Put()
Queue_Check()
While Not[isEmpty]
Queue_Get()
GrayNode()
moves = moves + 1
If node = goal Or maxmoves <= moves Then
isEmpty = "True"
Else
index = Array.GetAllIndices(edge[node])
n = Array.GetItemCount(edge[node])
from = node
For i = 1 To n
node = index[i]
If visited[node] Then
Else
Queue_Put()
edge[from][node] = ""
EndIf
EndFor
EndIf
EndWhile
EndSub
Sub DownArrow
' param bc - brush color
' param x, y - top left corner
' param width
' param height
GraphicsWIndow.BrushColor = bc
w = width * 0.45
GraphicsWindow.FillRectangle(x + (width - w) / 2, y, w, height / 2)
x1 = x
y1 = y + height / 2
x2 = x + width
y2 = y1
x3 = x + width / 2
y3 = y + height
GraphicsWindow.FillTriangle(x1, y1, x2, y2, x3, y3)
EndSub
Sub DrawStartAndGoal
x = 47
y = 20
width = 30
height = 60
bc = "Red"
DownArrow()
x = 551
y = 360
bc = "#0AB000"
DownArrow()
EndSub
Sub DumpCell
For j = 1 To rows
For i = 1 To cols
TextWindow.Write(cell[j][i])
EndFor
TextWindow.WriteLine("")
EndFor
EndSub
Sub DumpSparseMatrix
For j = 1 To rowsPassage * colsPassage
For i = 1 To rowsPassage * colsPassage
If edge[j][i] Then
TextWindow.Write("(" + j + "," + i + ") ")
EndIf
EndFor
TextWindow.WriteLine("")
EndFor
EndSub
Sub FindWallInList
' param i - index to remove of wall list
' return iPrev - previous index of i
' return iFound - i if found
iFound = 0
c = 1
While i <> iFound And c <= nWalls
c = c + 1
iPrev = iFound
iFound = iWalls[iFound]
EndWhile
EndSub
Sub ScanMaze
' Scan maze from the screen
' but this version is scanning following array maze[]
' return cell[][] - cell contains WALL or PASSAGE
' return edge[][] - sparse matrix for maze graph
maze[1] = "WSWWWWWWWWWWWWWWWWWWW"
maze[2] = "W W W W"
maze[3] = "W WWW W WWW W WWWWW W"
maze[4] = "W W W W W W W"
maze[5] = "W WWWWWWW WWW W W WWW"
maze[6] = "W W W W W W W"
maze[7] = "WWW W WWW W WWWWW W W"
maze[8] = "W W W W W"
maze[9] = "W WWWWW W WWWWW WWWWW"
maze[10] = "W W W W"
maze[11] = "WWWWWWWWWWWWWWWWWWWGW"
For row = 1 To rows
For col = 1 To cols
cell[row][col] = WALL
EndFor
EndFor
nWalls = 0
edge = "" ' sparse matrix for maze graph
For row = 2 To rows Step 2
For col = 2 To cols Step 2
cell[row][col] = PASSAGE
colw = col + 1
roww = row
If Text.GetSubText(maze[roww], colw, 1) = PASSAGE Then
cell[roww][colw] = PASSAGE
colp = col + 2 ' for graph
rowp = row ' for graph
node1 = (rowp / 2 - 1) * colsPassage + colp / 2 ' node # for graph
node2 = (row / 2 - 1) * colsPassage + col / 2 ' node # for graph
edge[node1][node2] = "True" ' one direction edge to maze graph
edge[node2][node1] = "True" ' opposite direction edge to maze graph
EndIf
colw = col
roww = row + 1
If Text.GetSubText(maze[roww], colw, 1) = PASSAGE Then
cell[roww][colw] = PASSAGE
colp = col ' for graph
rowp = row + 2 ' for graph
node1 = (rowp / 2 - 1) * colsPassage + colp / 2 ' node # for graph
node2 = (row / 2 - 1) * colsPassage + col / 2 ' node # for graph
edge[node1][node2] = "True" ' one direction edge to maze graph
edge[node2][node1] = "True" ' opposite direction edge to maze graph
EndIf
EndFor
EndFor
EndSub
Sub GetRandomIndex
' get random index of wall list
' return i - index
n = Math.GetRandomNumber(nWalls)
i = 0
For c = 1 To n
i = iWalls[i]
EndFor
EndSub
Sub Queue_Get
' return node
Queue_Check()
If Not[isEmpty] Then
outQ = outQ + 1
node = queue[outQ]
queue[outQ] = ""
EndIf
EndSub
Sub RemoveWallFromList
' param i - index to remove of wall list
' param wall[] - wall list
' param nWalls - number of wall list
FindWallInList()
If i = iFound Then ' found
iWalls[iPrev] = iWalls[iFound]
iWalls[iFound] = ""
nWalls = nWalls - 1
EndIf
EndSub
Sub SolveMaze
root = 1
goal = colsPassage * rowsPassage
moves = 0
maxmoves = goal * 2
BreadthFirstSearch()
If node = goal Then
While node <> root
Stack.PushValue("path", node)
index = Array.GetAllIndices(edge[node])
node = index[1]
EndWhile
EndIf
Turtle.PenDown()
GraphicsWindow.PenWidth = 4
GraphicsWindow.PenColor = "DarkCyan"
While 0 < Stack.GetCount("path")
node = Stack.PopValue("path")
Node2Pos()
Turtle.MoveTo(x, y)
EndWhile
Sound.PlayBellRing()
EndSub
Sub WaitButtonClick
bIdle = "True"
While bIdle
Program.Delay(300)
EndWhile
If Controls.LastClickedButton = oStart Then
bStart = "True"
Else
bStart = "False"
EndIf
EndSub