【问题标题】:Where is my loop evaluating wrong?我的循环在哪里评估错误?
【发布时间】:2015-04-15 01:51:07
【问题描述】:

我正在编写一个 Visual Basic 程序来模拟井字游戏。据我所知,我有一种方法应该正确地绘制电路板并用 Xs 和 Os 适当地填充它。但是,当我测试它时,它只会将它们绘制在同一行中。

“子板”绘制一切,测试“x”和“o”的现有值并分别调用“drawX”或“drawO”,传递坐标进行绘制。

Sub Main()
    Dim start As String = String.Empty
    Dim x As ArrayList = New ArrayList
    Dim o As ArrayList = New ArrayList
    Dim choice As String = String.Empty
    o.Add("1")
    o.Add("5")
    o.Add("9")

    While True
        board(x, o)
        pause()
    End While
End Sub

Sub pause()
    Console.WriteLine("Press enter to continue...")
    Console.ReadLine()
End Sub

Sub board(x As ArrayList, o As ArrayList)
    Console.ForegroundColor = 8
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("**********************************************************")
    Console.WriteLine("**********************************************************")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("**********************************************************")
    Console.WriteLine("**********************************************************")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")
    Console.WriteLine("                  **                  **                  ")

    Dim ver As Integer = 1
    Dim hor As Integer = 4
    Dim vSpace As Integer = 11
    Dim hSpace As Integer = 20
    Dim vPos As Integer = 0
    Dim hPos As Integer = 0
    For i As Integer = 1 To 9
        If 1 <= i <= 3 Then
            vPos = ver
            Select Case i
                Case 1
                    hPos = hor
                Case 2
                    hPos = hor + hSpace
                Case 3
                    hPos = hor + (hSpace * 2)
                Case Else
            End Select
        End If
        If 4 <= i <= 6 Then
            vPos = ver + vSpace
            Select Case i
                Case 4
                    hPos = hor
                Case 5
                    hPos = hor + hSpace
                Case 6
                    hPos = hor + (hSpace * 2)
                Case Else
            End Select
        End If
        If 7 <= i <= 9 Then
            vPos = ver + (vSpace * 2)
            Select Case i
                Case 7
                    hPos = hor
                Case 8
                    hPos = hor + hSpace
                Case 9
                    hPos = hor + (hSpace * 2)
                Case Else
            End Select
        End If
        Select Case True
            Case x.Contains(CStr(i))
                drawX(hPos, vPos)
            Case o.Contains(CStr(i))
                drawO(hPos, vPos)
        End Select
    Next i
End Sub

Sub drawX(hPos As Integer, vPos As Integer)
    Console.ForegroundColor = 6
    Console.SetCursorPosition(hPos, vPos)
    Console.Write("**      **")
    Console.SetCursorPosition(hPos, vPos + 1)
    Console.Write(" **    **")
    Console.SetCursorPosition(hPos, vPos + 2)
    Console.Write("  **  **")
    Console.SetCursorPosition(hPos, vPos + 3)
    Console.Write("   ****")
    Console.SetCursorPosition(hPos, vPos + 4)
    Console.Write("  **  **")
    Console.SetCursorPosition(hPos, vPos + 5)
    Console.Write(" **    **")
    Console.SetCursorPosition(hPos, vPos + 6)
    Console.Write("**      **")

End Sub

Sub drawO(hPos As Integer, vPos As Integer)
    Console.ForegroundColor = 3
    Console.SetCursorPosition(hPos, vPos)
    Console.Write("  ******")
    Console.SetCursorPosition(hPos, vPos + 1)
    Console.Write(" ********")
    Console.SetCursorPosition(hPos, vPos + 2)
    Console.Write("**      **")
    Console.SetCursorPosition(hPos, vPos + 3)
    Console.Write("**      **")
    Console.SetCursorPosition(hPos, vPos + 4)
    Console.Write("**      **")
    Console.SetCursorPosition(hPos, vPos + 5)
    Console.Write(" ********")
    Console.SetCursorPosition(hPos, vPos + 6)
    Console.Write("  ******")
End Sub

【问题讨论】:

    标签: vb.net visual-studio-2013


    【解决方案1】:

    我会研究这种类型的构造:

    If 1 <= i <= 3 Then
    

    我很确定它会评估 1 &lt;= i,然后将 that 的结果与 3 进行比较。因为布尔表达式的结果要么是 -1,要么是 0假,该表达式将总是评估为真。

    你应该选择类似的东西:

    If 1 <= i And i <= 3 Then ' could also use AndAlso '
    

    (其他类似的行也是如此)。

    【讨论】:

    • 谢谢!不敢相信我没有想到这一点哈哈...我在 java 中花费的时间比 vb 还多,我认为它总是在 java 中工作。无论如何,我将其改编为 i
    【解决方案2】:

    下面的代码行(和其他类似的行)并没有按照您的想法进行:

    If 4 <= i <= 6 Then
    

    这里实际发生的是,首先只计算 4 &lt;= i 表达式。然后该表达式的 boolean 结果用于&lt;= 6 比较。为了进行这种比较,必须首先将布尔值转换为整数。布尔转换回整数会导致 0 (false) 或 -1 (true) (reference)。这两个都小于 6,因此这整行代码将总是导致True

    你需要这样写,而不是:

    If 4 <= i AndAlso i <= 6 Then
    

    顺便说一句,您确定Option Strict 已打开吗?因为它应该是,如果是的话,当您尝试将布尔值与整数进行比较时,我预计会出现编译器错误。不要在没有 Option Strict 或至少 Option Infer 的情况下编写代码。它们有助于避免此类错误。

    【讨论】:

      【解决方案3】:

      虽然到目前为止给出的答案是正确的 - 你应该使用 AndAlso - 还有另一种看待问题的方式。

      您的整个 For i As Integer = 1 To 9 循环可以简单地替换为:

          For Each i In x
              drawX(hor + hSpace * ((i - 1) Mod 3), ver + vSpace * ((i - 1) \ 3))
          Next
          For Each i In o
              drawO(hor + hSpace * ((i - 1) Mod 3), ver + vSpace * ((i - 1) \ 3))
          Next
      

      这是更直接的计算字母的位置。

      我什至会更进一步,像这样重写你的代码:

      Option Strict On
      
      Module Module1
      
          Sub Main()
              Dim x = New List(Of Integer)() From {2, 4, 7}
              Dim o = New List(Of Integer)() From {1, 5, 9}
              While True
                  board(x, o)
                  pause()
              End While
          End Sub
      
          Sub pause()
              Console.WriteLine("Press enter to continue...")
              Console.ReadLine()
          End Sub
      
          Sub board(x As List(Of Integer), o As List(Of Integer))
              Console.ForegroundColor = ConsoleColor.DarkGray
      
              Dim vSpace As Integer = 11
              Dim hSpace As Integer = 20
              Dim ver As Integer = 1
              Dim hor As Integer = 4
      
              For i = 1 To 2
                  For j = 0 To 3 * (vSpace - 1)
                      Console.SetCursorPosition(i * hSpace - 2, j)
                      Console.Write("**")
                  Next
              Next
      
              For j = 1 To 2
                  Console.SetCursorPosition(0, j * vSpace - 2)
                  Console.Write("".PadRight(3 * hSpace - 2, "*"c))
                  Console.SetCursorPosition(0, j * vSpace - 2 + 1)
                  Console.Write("".PadRight(3 * hSpace - 2, "*"c))
              Next
      
              For Each i In x
                  drawX(hor + hSpace * ((i - 1) Mod 3), ver + vSpace * ((i - 1) \ 3))
              Next
              For Each i In o
                  drawO(hor + hSpace * ((i - 1) Mod 3), ver + vSpace * ((i - 1) \ 3))
              Next
      
          End Sub
      
          Sub drawX(hPos As Integer, vPos As Integer)
              drawLetter(hPos, vPos, ConsoleColor.DarkYellow,
              {
                  "**      **",
                  " **    **",
                  "  **  **",
                  "   ****",
                  "  **  **",
                  " **    **",
                  "**      **"
              })
          End Sub
      
          Sub drawO(hPos As Integer, vPos As Integer)
              drawLetter(hPos, vPos, ConsoleColor.DarkCyan,
              {
                  "  ******",
                  " ********",
                  "**      **",
                  "**      **",
                  "**      **",
                  " ********",
                  "  ******"
              })
          End Sub
      
          Sub drawLetter(hPos As Integer, vPos As Integer, color As ConsoleColor, letter As String())
              Console.ForegroundColor = color
              For i = 0 To 6
                  Console.SetCursorPosition(hPos, vPos + i)
                  Console.Write(letter(i))
              Next
          End Sub
      
      End Module
      

      【讨论】:

      • 虽然我可能不会为这个特定的程序修改我的代码到这种程度,但我喜欢你的建议,并将在未来的发展中记住它们。 =) 我还要感谢您在此回复中投入的时间和精力。
      • @user3582362 - 没问题。这是一个有趣的重构练习。我希望您将来可以使用其中的一些技术。
      猜你喜欢
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 2017-01-20
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多