本质上,该程序的目的是进行修订。该程序将生成一个随机数学表达式,将其转换为二叉树的可视化表示,用户必须遍历二叉树。但是,当我运行此代码时,初始节点远离中心。我如何重新定位二进制树位于PictureBox的中间?这是我的代码: 公共班级BTT '已宣布的可变性不是故障 昏暗节点(7)作为对象
'maybe try to alter the form so that the user can only get two incorrect answers'
Dim operators(6) As String
Dim actualAnswer As String = ""
Dim ogEquation(11) As String
Dim newLabel As String = "" 'used to store the equation to be stored in the label'
Dim userAnswer As String
Dim myTime As Double
Dim traversal(3) As String
Dim selectedTraversal As String
Dim treeCounter As Integer = 0
Dim draw As Boolean = False
Structure tree
Dim name As String
Dim left As Integer
Dim right As Integer
End Structure
Dim TreeNode(7) As tree
Dim scoreValue As Integer = 0 'stores the user's score for the game just completed'
Dim updating As Boolean = False 'if there are already 10 scores, the first one will need to be removed, so updating = true'
Class node
Public lineColour As Color
Public lineWidth As Integer
Public posX As Integer
Public posY As Integer
Public radius As Integer
Public Sub draw(e As PaintEventArgs)
Dim myPen As New Pen(Me.lineColour, Me.lineWidth)
e.Graphics.DrawEllipse(myPen, Me.posX, Me.posY, Me.radius, Me.radius)
End Sub
End Class
Sub DrawTree()
'these are the coordinates of the top left of the PictureBox
Dim leftX As Integer = 171
Dim rightX As Integer = 171 + PictureBox1.Width 'will be set to the edge of the picturebox
Dim topY As Integer = 138
Dim bottomY As Integer = 138 + PictureBox1.Height 'will be that number of pixels down, WILL NEVER CHANGE
Dim currentNode As Integer = 1 'will initially be the root node
For i = 1 To treeCounter 'loops based on the number of nodes in the array'
'assigns the basic information common to all of the nodes
nodes(i) = New node
nodes(i).radius = 70
nodes(i).lineWidth = 2
nodes(i).lineColour = Color.Black
Next
'need to go through the binary tree and determine x & y positions, with labels inside the ellipses
ConstructTree(currentNode, leftX, rightX, topY, bottomY)
draw = True
PictureBox1.Refresh()
End Sub
Sub ConstructTree(ByRef currentNode As Integer, ByRef leftX As Integer, ByRef rightX As Integer, ByRef topY As Integer, ByRef bottomY As Integer)
'ASK ISABEL ABOUT DYNAMICALLY GENERATING A LABEL'
'e.g. Dim test As New Label
nodes(currentNode).posX = (leftX + rightX) / 2 'gets average of x coordinates'
nodes(currentNode).posY = topY + ((bottomY - topY) * (1 / 3)) 'gets number of pixels down between bottom of form & last node, goes a third of the way down
If TreeNode(currentNode).left <> 0 Then 'if there is a node to the left
ConstructTree(TreeNode(currentNode).left, leftX, (leftX + rightX) / 2, nodes(currentNode).posY, bottomY)
End If
If TreeNode(currentNode).right <> 0 Then 'if there is a node to the right
ConstructTree(TreeNode(currentNode).right, (leftX + rightX) / 2, rightX, nodes(currentNode).posY, bottomY) 'swaps the left and right x-coords which have been changed
End If
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If draw = True Then
For i = 1 To treeCounter
nodes(i).draw(e)
Next
'ALSO need to draw lines between the nodes, but IGNORE FOR NOW
End If
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
TextBox1.Text = myTime - (0.1)
myTime = TextBox1.Text
If myTime = 0 Then
Timer1.Enabled = False
MsgBox("Time is up!")
checkupdate()
resetForm()
End If
'add another if statement checking for two wrong answers, will stop the timer and tell the user that they have got too man questions wrong'
End Sub
Sub resetForm()
Score.Text = "Score:"
Label1.Text = ""
scoreValue = 0
End Sub
Sub writefile()
FileOpen(1, "BTTscores.txt", OpenMode.Output)
Select Case updating
Case True
For i = 2 To 11
WriteLine(1, scores(i))
Next
Case False
For i = 1 To numberOfScores + 1
WriteLine(1, scores(i))
Next
End Select
FileClose()
End Sub
Sub checkupdate()
'need to check whether there are already ten elements in the array. If so, then delete the first score, move all the indices of the other scores 1 to the left and add the new scores on the end'
numberOfScores = 0 'will need to be reset if the user carries on using the program'
FileOpen(1, "BTTscores.txt", OpenMode.Input) 'need to bubble sort values'
Dim line As String
Do Until EOF(1)
line = LineInput(1)
If line <> "" Then
numberOfScores = numberOfScores + 1
scores(numberOfScores) = line 'copies the line to the array'
End If
Loop
If numberOfScores = 10 Then 'if one needs to be updated, need to read all but the first line into the array'
updating = True
scores(11) = scoreValue
Else 'if there are less than 10 scores, the user's current score just needs to be added on the end'
updating = False
scores(numberOfScores + 1) = scoreValue
End If
FileClose(1)
writefile()
End Sub
Private Sub EnterButton_Click(sender As Object, e As EventArgs) Handles EnterButton.Click
userAnswer = Answer.Text
If actualAnswer.Replace(" ", "") = userAnswer.Replace(" ", "") Then
UpdateScore()
End If
Score.Text = ("Score: " & scoreValue)
Answer.Text = ""
InitialSetup()
End Sub
Sub UpdateScore()
Select Case difficulty
Case "Easy"
scoreValue = scoreValue + 10
Case "Medium"
scoreValue = scoreValue + 15
Case "Hard"
scoreValue = scoreValue + 20
End Select
End Sub
Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click
scoreValue = 0
Initialisation()
InitialSetup()
myTime = 60
Timer1.Enabled = True
End Sub
Sub InitialSetup()
Dim currentNode As Integer = 1 'will be root node'
actualAnswer = ""
GetEquation()
newLabel = ""
selectedTraversal = traversal(CInt(Math.Floor((3 - 1 + 1) * Rnd())) + 1) 'will choose a random traversal'
newLabel = "Traversal: " + selectedTraversal
Label1.Text = newLabel
If selectedTraversal = "Prefix" Then
PrefixConversion(currentNode)
ElseIf selectedTraversal = "Infix" Then
InfixConversion()
Else
RPConversion()
End If
DrawTree()
End Sub
Sub Initialisation()
operators(1) = "("
operators(2) = "-"
operators(3) = "+"
operators(4) = "*"
operators(5) = "/"
operators(6) = ")"
traversal(1) = "Prefix"
traversal(2) = "Infix"
traversal(3) = "Postfix"
End Sub
Sub GetEquation()
Select Case difficulty
'RANDOM NUMBER FORMAT: CInt(Math.Floor((upperbound - lowerbound + 1) * Rnd())) + lowerbound'
Case "Easy"
'FORMAT: 17 * 4'
treeCounter = 3
ogEquation(1) = CInt(Math.Floor((20 - 1 + 1) * Rnd())) + 1
ogEquation(2) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(3) = CInt(Math.Floor((20 - 1 + 1) * Rnd())) + 1
'initialising the binary tree iteration'
TreeNode(1).name = ogEquation(2) 'operator is the root'
TreeNode(1).left = 2
TreeNode(1).right = 3
TreeNode(2).name = ogEquation(1)
TreeNode(3).name = ogEquation(3)
'EG: * 17 4
Case "Medium"
treeCounter = 5
'FORMAT: 15 * (17 + 4)'
ogEquation(1) = CInt(Math.Floor((50 - 1 + 1) * Rnd())) + 1
ogEquation(2) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(3) = operators(1)
ogEquation(4) = CInt(Math.Floor((50 - 1 + 1) * Rnd())) + 1
ogEquation(5) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(6) = CInt(Math.Floor((50 - 1 + 1) * Rnd())) + 1
ogEquation(7) = operators(6)
'initialising the binary tree iteration'
TreeNode(1).name = ogEquation(2) 'root node'
TreeNode(1).left = 2
TreeNode(1).right = 3
TreeNode(2).name = ogEquation(1)
TreeNode(3).name = ogEquation(5)
TreeNode(3).left = 4
TreeNode(3).right = 5
TreeNode(4).name = ogEquation(4)
TreeNode(5).name = ogEquation(6)
'EG: * 15 + 17 4
Case "Hard"
'FORMAT: (17 + 4) * (20 / 10), random numbers are 1-150'
treeCounter = 7
ogEquation(1) = operators(1)
ogEquation(2) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(3) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(4) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(5) = operators(6)
ogEquation(6) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(7) = operators(1)
ogEquation(8) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(9) = operators(CInt(Math.Floor((5 - 2 + 1) * Rnd())) + 2)
ogEquation(10) = CInt(Math.Floor((150 - 1 + 1) * Rnd())) + 1
ogEquation(11) = operators(6)
'initialising the binary tree iteration'
TreeNode(1).name = ogEquation(6) 'root node'
TreeNode(1).left = 2
TreeNode(1).right = 5
TreeNode(2).name = ogEquation(3)
TreeNode(2).left = 3
TreeNode(2).right = 4
TreeNode(3).name = ogEquation(2)
TreeNode(4).name = ogEquation(4)
TreeNode(5).name = ogEquation(9)
TreeNode(5).left = 6
TreeNode(5).right = 7
TreeNode(6).name = ogEquation(8)
TreeNode(7).name = ogEquation(10)
'EG: * + 17 4 / 20 10
End Select
End Sub
'Traversal Solutions'
'Postfix Conversion'
Sub RPConversion()
Dim myStack As New Stack(15)
Dim empty As Boolean = True
Dim temp As String 'used to store the current part of the original equation'
Dim operatorNum As Integer
Dim peekNum As Integer
Dim stoploop As Boolean = True
For i = 1 To ogEquation.Count - 1 'will iterate through the total number of elements in the array ogEquation'
If myStack.Count = 0 Then empty = True
temp = ogEquation(i)
MatchTempOperation(myStack, temp, operatorNum)
If operatorNum > 1 And operatorNum < 6 Then 'if the value is an operator'
If myStack.Count <> 0 Then 'if the stack contains a value'
CheckPeek(myStack, peekNum)
If operatorNum > peekNum Then
myStack.Push(temp)
ElseIf operatorNum = peekNum Then
actualAnswer = actualAnswer + myStack.Pop()
myStack.Push(temp)
Else 'operatorNum < peekNum'
actualAnswer = actualAnswer + myStack.Pop()
Do
stoploop = True
CheckPeek(myStack, peekNum)
If operatorNum > peekNum Then
myStack.Push(temp)
ElseIf operatorNum = peekNum Then
actualAnswer = actualAnswer + myStack.Pop()
myStack.Push(temp)
Else
actualAnswer = actualAnswer + myStack.Pop()
stoploop = False
End If
Loop Until stoploop Or myStack.Count = 0
End If
Else
myStack.Push(temp)
End If
ElseIf temp = "(" Then
myStack.Push(temp)
ElseIf temp = ")" Then
Do
actualAnswer = actualAnswer + myStack.Pop()
Loop Until myStack.Peek() = "("
myStack.Pop()
Else
actualAnswer = actualAnswer + temp
End If
operatorNum = 0
Next
If myStack.Count > 0 Then
For i = 1 To myStack.Count
actualAnswer = actualAnswer + myStack.Pop()
Next
End If
End Sub
Sub CheckPeek(ByVal myStack As Stack, ByRef peekNum As Integer) 'does the same as MatchTempOperation but for the top of the stack'
For i = 2 To 5 'skip one and six because we know it isn't a left or right bracket'
If myStack.Peek() = operators(i) Then
peekNum = i
End If
Next
End Sub
Sub MatchTempOperation(ByVal myStack As Stack, ByVal temp As String, ByRef operatorNum As Integer) 'wants to look at the stack but not be able to change it'
For i = 1 To 6
If temp = operators(i) Then
operatorNum = i
End If
Next
End Sub
'Infix'
Sub InfixConversion()
For i = 1 To 11
'check each element for empty spaces / brackets'
If ogEquation(i) <> "" And ogEquation(i) <> "(" And ogEquation(i) <> ")" Then
actualAnswer = actualAnswer + ogEquation(i)
End If
Next
End Sub
'Prefix'
Sub PrefixConversion(ByRef currentNode As Integer)
actualAnswer = actualAnswer + TreeNode(currentNode).name
If TreeNode(currentNode).left <> 0 Then
PrefixConversion(TreeNode(currentNode).left)
End If
If TreeNode(currentNode).right <> 0 Then
PrefixConversion(TreeNode(currentNode).right)
End If
End Sub
Private Sub ExitButton_Click(sender As Object, e As EventArgs) Handles ExitButton.Click
Me.Hide()
End Sub
结束班
对于效率低下的道歉,请注意“难度”变量是公共的并存储在此表单之外。谢谢:)
输出: enter image description here 如您所见,根节点远离左下方的中心。