我的循环在哪里评估错误?

时间:2015-04-15 01:51:07

标签: vb.net visual-studio-2013

我正在编写一个Visual Basic程序来模拟Tic Tac Toe游戏。据我所知,我有一种方法可以正确地绘制板并用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

3 个答案:

答案 0 :(得分:1)

我正在研究这种类型的构造:

If 1 <= i <= 3 Then

我非常肯定会评估1 <= i然后将 的结果与3进行比较。因为布尔表达式的结果是-1 true或0表示false,该表达式始终评估为true。

您应该选择以下内容:

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

(和其他类似的行一样)。

答案 1 :(得分:1)

下面的代码行(以及类似的其他行)不符合您的想法:

If 4 <= i <= 6 Then

这里实际发生的是,首先只评估4 <= i表达式。然后,该表达式的 boolean 结果用于<= 6比较。要进行此比较,必须首先将布尔值转换为整数。布尔转换回整数会导致0(假)或-1(真)(reference)。这两个都不到6,所以这整行代码将始终导致True

你需要这样写,而不是:

If 4 <= i AndAlso i <= 6 Then
顺便说一下,您确定Option Strict已开启吗?因为它应该是,并且当你试图将布尔值与整数进行比较时,我是否期望编译器错误。不要在没有Option Strict或至少Option Infer的情况下编写代码。它们有助于避免这样的错误。

答案 2 :(得分:1)

虽然到目前为止给出的答案是正确的 - 您应该使用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