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 < cols2 And 1 < roww And roww < rows2 And cell[colw][roww] = 1 Then
i = colw + (roww - 1) * cols2
' 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]
EndIf
EndIf
EndFor
EndSub
Sub ClearMaze
' param x0, y0
' param cols, rows
' param width
Program.Delay(int) ' to synchronize with Silverlight
GraphicsWindow.PenWidth = widthw
GraphicsWindow.PenColor = colorWall ' dummy for Silverlight
GraphicsWindow.DrawRectangle(x0, y0, widthp * cols, widthp * rows) ' dummy for Silverlight
GraphicsWindow.BrushColor = "Gray"
GraphicsWindow.FillRectangle(x0, y0, widthp * cols, widthp * rows)
check = GraphicsWindow.GetPixel(x0 - 1, y0 - 1) ' check for Silverlight
If Text.GetLength(check) = 9 Then ' check for Silverlight
check = "#" + Text.GetSubTextToEnd(check, 4) ' check for Silverlight
EndIf ' check for Sliverlight
If check = colorWall Then ' check for Silverlight
small = "False" ' check for Sliverlight
Else ' check for Sliverlight
small = "True" ' DrawRectangle is small ' check for Sliverlight
EndIf
col0 = 1 'Math.GetRandomNumber(cols) ' start cell of maze generate
row0 = 1 'Math.GetRandomNumber(rows)
x = x0 + (col0 - 1) * widthp
y = y0 + (row0 - 1) * widthp
GraphicsWindow.BrushColor = colorPassage
GraphicsWindow.FillRectangle(x + (widthw / 2), y + (widthw / 2), widthp - widthw, widthp - widthw) ' start cell
GraphicsWindow.PenColor = colorWall
If small Then ' for Silverlight
GraphicsWindow.DrawRectangle(x0 - (widthw / 2), y0 - (widthw / 2), widthp * cols + widthw, widthp * rows + widthw) ' for Silverlight
Else ' for Silverlight
GraphicsWindow.DrawRectangle(x0, y0, widthp * cols, widthp * rows)
EndIf ' for Silverlight
y1 = y0 + widthp * rows
For col = 1 To cols - 1
x = x0 + widthp * col
GraphicsWindow.DrawLine(x, y0, x, y1)
EndFor
x1 = x0 + widthp * cols
For row = 1 To rows - 1
y = y0 + widthp * row
GraphicsWindow.DrawLine(x0, y, x1, y)
EndFor
For row = 1 To rows2
For col = 1 To cols2
cell[col][row] = 1
EndFor
EndFor
cell[2 * col0][2 * row0] = 0 ' generate start
nWalls = 0
EndSub
Sub FindPassage
xt = Turtle.X
yt = Turtle.Y
back = Math.Remainder(Turtle.Angle + 180, 360)
Turtle.TurnRight()
nturn = 1
IsWall()
If bWall Then
Turtle.TurnLeft()
nturn = nturn - 1
IsWall()
EndIf
While bWall
Turtle.TurnRight()
nturn = nturn + 1
IsWall()
EndWhile
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 GenerateMaze
' Generate maze with randomized Prim's algorithm
' param x0, y0
' param cols, rows
' param width
' 1. Start with a grid full of walls.
ClearMaze()
' 2. Pick a cell, mark it as part of the maze. Add the walls of the cell to the wall list.
col = 2 * col0
row = 2 * row0
AddWallToList()
' 3. While there are walls in the list:
While nWalls > 0
' 1. Pick a random wall from the list. If the cell on the opposite side isn't in the maze yet:
GetRandomIndex()
col = colOpp[i]
row = rowOpp[i]
If cell[col][row] = 1 Then
' 1. Make the wall a passage and mark the cell on the opposite side as part of the maze.
colw = colWall[i]
roww = rowWall[i]
RemoveWallFromList()
cell[colw][roww] = 0 ' wall
cell[col][row] = 0 ' cell on the opposite side
KnockDownWall()
' 2. Add the neighboring walls of the cell to the wall list.
AddWallToList()
Else
' 2. If the cell on the opposite side already was in the maze, remove the wall from the list.
RemoveWallFromList()
EndIf
EndWhile
DrawGoal()
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 IsWall
' param xt - x coodinate of Turtle
' param yt - y coodinate of Turtle
' return a - angle of Turtle
' return bWall - "True" if wall is in front of Turtle
a = Math.Remainder(Turtle.Angle, 360)
If a = back And nturn <= 2 Then
bWall = "True"
Else
x = Math.Floor(xt + (widthp / 2) * Math.Sin(a / 180 * Math.Pi))
y = Math.Floor(yt - (widthp / 2) * Math.Cos(a / 180 * Math.Pi))
color = GraphicsWindow.GetPixel(x, y)
If Text.GetLength(color) = 9 Then ' for Silverlight
color = "#" + Text.GetSubText(color, 4, 6)
EndIf
If color = colorWall Then
bWall = "True"
Else
bWall = "False"
EndIf
EndIf
EndSub
Sub IsWall2
' param AT_x - x coodinate of player Turtle
' param AT_y - y coodinate of player Turtle
' return a2 - angle of player Turtle
' return bWall2 - "True" if wall is in front of Turtle
a2 = Math.Remainder(AT_angle, 360)
x2 = Math.Floor(AT_x + (widthp / 2) * Math.Sin(a2 / 180 * Math.Pi))
y2 = Math.Floor(AT_y - (widthp / 2) * Math.Cos(a2 / 180 * Math.Pi))
color2 = GraphicsWindow.GetPixel(x2, y2)
If Text.GetLength(color2) = 9 Then ' for Silverlight
color2 = "#" + Text.GetSubText(color2, 4, 6)
EndIf
If color2 = colorWall Then
bWall2 = "True"
Else
bWall2 = "False"
EndIf
EndSub
Sub Move
' param a - angle of CPU Turtle
' return pos - Turtle position
Turtle.Move(widthp)
If a = 0 Then
pos = pos - (cols + 1)
ElseIf a = 90 Then
pos = pos + 1
ElseIf a = 180 Then
pos = pos + (cols + 1)
ElseIf a = 270 Then
pos = pos - 1
EndIf
EndSub
Sub Move2
' param a2 - angle of player Turtle
' return pos2 - Turtle position
' return moves2 - number of moves
distance = widthp
AT_Move()
If a2 = 0 Then
pos2 = pos2 - (cols + 1)
ElseIf a2 = 90 Then
pos2 = pos2 + 1
ElseIf a2 = 180 Then
pos2 = pos2 + (cols + 1)
ElseIf a2 = 270 Then
pos2 = pos2 - 1
EndIf
EndSub
Sub OnKeyDown
GraphicsWindow.KeyDown = DoNothing
key = GraphicsWindow.LastKey
angle = dir[key] - AT_angle
Math_AdjustAngle()
If angle <> 0 Then
AT_Turn()
EndIf
IsWall2()
If bWall2 = "False" Then
Move2()
EndIf
GraphicsWindow.KeyDown = OnKeyDown
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 AT_MoveTo
' Another Turtle | Move to given position
' param x
' param y
Stack.PushValue("local", x)
Stack.PushValue("local", y)
x = x - AT_x
y = y - AT_y
Math_CartesianToPolar()
angle = a + 90 - AT_angle
distance = r
AT_Turn()
AT_Move()
y = Stack.PopValue("local")
x = Stack.PopValue("local")
EndSub
Sub AT_Turn
' Another Turtle | Turn given angle
' param angle
Stack.PushValue("local", angle)
angle = AT_angle + angle
Math_AdjustAngle()
If AT_angle < angle Then
sa = 1
Else
sa = -1
EndIf
For _a = AT_angle To angle Step sa
Shapes.Rotate(AT_obj, _a)
Program.Delay(5)
EndFor
AT_angle = angle
angle = Stack.PopValue("local")
EndSub
Sub AT_TurnRight
' Another Turtle | Turn Right
For angle = AT_angle To AT_angle + 90
Shapes.Rotate(AT_obj, a)
Program.Delay(5)
EndFor
AT_angle = angle - 1
EndSub
Sub Math_AdjustAngle
' Math | adjust angle [0, 360) degree
' param angle
' return angle
angle = Math.Remainder(angle, 360)
If angle < 0 Then
angle = angle + 360
EndIf
EndSub
Sub Math_CartesianToPolar
' Math | convert cartesian coodinate to polar coordinate
' param x, y - cartesian coordinate
' return r, a - polar coordinate
r = Math.SquareRoot(x * x + y * y)
If x = 0 And y > 0 Then
a = 90 ' [degree]
ElseIf x = 0 And y < 0 Then
a = -90
Else
a = Math.ArcTan(y / x) * 180 / Math.Pi
EndIf
If x < 0 Then
a = a + 180
ElseIf x > 0 And y < 0 Then
a = a + 360
EndIf
EndSub