我不熟悉围棋游戏的规则/游戏玩法,所以我不确定您到底想要完成什么,但如果您认为洪水填充类型的算法是您所需要的,那么我至少可以就如何做到这一点提供一些建议。您的代码需要的首要任务是将其分解为更细粒度的方法。单击该面板时您尝试执行哪些步骤?当然,这不仅仅是一件事。有许多不同的事情正在发生——每一件事情都可以通过单独的专用方法来执行。例如,如果您有这样的方法:
Private Function GetGridPosition(board As Panel, cursorPosition As Point) As Point
Dim pt As Point = board.PointToClient(Cursor.Position)
Dim colWidth As Integer = (1 / (GridSize + 1)) * board.Size.Width
Dim rowHeight As Integer = (1 / (GridSize + 1)) * board.Size.Height
Return New Point(Math.Min(Math.Max((pt.X / colWidth) - 1, 0), GridSize - 1), Math.Min(Math.Max((pt.Y / rowHeight) - 1, 0), GridSize - 1))
End Function
然后,在Panel1_Click
事件处理程序,您可以大大简化代码的开头,如下所示:
Private Sub Panel1_Click(sender As Object, e As EventArgs) Handles Panel1.Click
Dim board As Panel = DirectCast(sender, Panel)
Dim gridPosition As Point = GetGridPosition(board, Cursor.Position)
' ...
当然,这使代码更有组织性并且更易于阅读,但这并不会让您更接近洪水填充算法,对吧?嗯,是的,这基本上是正确的,但是组织和可读性本身就是有价值的目标,所以无论如何我们都要继续...我们需要执行的下一步是让玩家移动,然后,如果移动成功,我们需要切换到另一个玩家。因此,我们首先创建切换玩家的方法:
Private Sub SwitchPlayer()
pass = False
cp = Not cp
passbtn.BackColor = GetPlayerForeColor(cp)
passbtn.ForeColor = GetPlayerBackColor(cp)
End Sub
Private Function GetPlayerForeColor(player as Boolean) As Color
If player Then
Return Color.White
Else
Return Color.Black
End If
End Function
Private Function GetPlayerBackColor(player as Boolean) As Color
If player Then
Return Color.Black
Else
Return Color.White
End If
End Function
你会注意到我偷偷溜走了(Chrome 自动拼写告诉我这不是一个单词,但我在美国的成长经历却有所不同)当我在那里的时候还有其他一些方法。我确信他们的目的很明显。但就停在那里吧。很明显?您会注意到注释消失了,但代码的含义仍然很明显。这就是我们所说的自文档化代码。当有必要时,注释是很好的,但当根本没有必要时,注释就更好了。
所以,假设现在我们有一个这样的方法:
Private Function MakeMove(gridPosition As Grid, player As Boolean) As Boolean
' return true if the move was successful
End Function
然后整个Panel1_Click
事件处理程序可能如下所示:
Private Sub Panel1_Click(sender As Object, e As EventArgs) Handles Panel1.Click
Dim board As Panel = DirectCast(sender, Panel)
Dim gridPosition As Point = GetGridPosition(board, Cursor.Position)
If MakeMove(gridPosition, cp) Then
SwitchPlayer()
Else
ShowIllegalMoveMessage()
End If
End Sub
Private Sub ShowIllegalMoveMessage()
illegalmovelbl.Show() 'Shows the "Illegal Move" Label
MsgBox("Place your stone in a vacant point") 'Displays error message
End Sub
好的,现在我们开始讨论重点了。那么,搬家时需要采取哪些步骤呢?嗯,我不知道,因为我不知道这个游戏。我把这个练习留给你,但是,如果你的倾向是正确的,并且你需要某种洪水填充算法,那么这可能意味着你需要某种PlaceStone
可以一遍又一遍地重复的动作,所以这应该是它自己的方法:
Private Sub PlaceStone(gridPosition As Point, player As Boolean)
' Do something
End Sub
显然Do something
是这一切的关键部分,也是我无法帮助你的部分。但是,如果它是洪水填充算法,我可以给你一个非常重要的提示。在它要做的所有其他事情中,它会调用PlaceStone
再次,将其传递给不同的网格位置(周围位置之一)。例如,这样的事情:
Private Sub PlaceStone(gridPosition As Point, player As Boolean)
Dim north As Position = GetNorthPosition(gridPosition)
If Floodable(north, player) Then
PlaceStone(north, player)
End If
' ...
End Sub
当一个方法像这样调用自身时,我们称之为递归。但是,除非您开始将代码拆分为专用的小方法,每个方法都有自己的封装任务,否则您无法真正添加递归。因此,首先组织起来,然后添加递归。