【问题标题】:Simple Tic Tac Toe on excel VBAexcel VBA上的简单井字游戏
【发布时间】:2015-01-30 06:30:49
【问题描述】:

我正在尝试为我所拥有的课程制作一个非常简单的井字游戏,而不是 X 和 O,您将内部单元格着色为蓝色(用户)和红色(宏)并且没有 AI。

但每当我认为我得到它时,它就会进入无限循环

Sub Tic()

Dim r1 As Integer
Dim r2 As Integer


Do

r1 = Int(Rnd * 3) + 1
r2 = Int(Rnd * 3) + 1

If Cells(r1, r2).Interior.Color = xlNone Then   'with colorindex instead of color it fills before crashing



Cells(r1, r2).Interior.Color = vbRed


End If


Loop While Cells(r1, r2).Interior.Color = vbBlue Or Cells(r1, r2).Interior.Color <> vbRed

'tried removing the first condition but the result is the same, same with changing the second to equal


End Sub

现在我只允许使用我正在使用的功能,所以我不能改变太多

所以我认为它应该做的是检查单元格是否没有填充任何颜色,那么它应该将其着色为红色,如果它是蓝色或红色,那么它应该什么都不做并寻找另一个未填充的单元格。

不管我怎么看,我只是不知道哪一部分出了问题,所以如果你不能回答,如果有人指出哪一部分是错误的,我将不胜感激,这样我就可以专注于它

【问题讨论】:

  • 只是对扭转您接受的答案感到好奇;你还有什么要找的吗?

标签: vba excel infinite-loop tic-tac-toe


【解决方案1】:

如果循环命中蓝色单元格,那么您的 If 语句将不会执行并且您的 While 条件将得到满足,这意味着您会陷入循环。

也许您最好在进入循环之前设置一个非彩色单元格数量的计数器,然后在每次为单元格着色时减少它。然后你可以在计数器为0时退出循环。

所以如果你有 9 个单元格,你可以使用

Dim r1 As Integer
Dim r2 As Integer
Dim blankCells As Integer

blankCells = 9

Do

r1 = Int(Rnd * 3) + 1
r2 = Int(Rnd * 3) + 1

If Cells(r1, r2).Interior.Color = xlNone Then   'with colorindex instead of color it fills before crashing

   blankCells = blankCells - 1

   Cells(r1, r2).Interior.Color = vbRed


End If


Loop While blankCells > 0

【讨论】:

    【解决方案2】:

    我的方法与你的有点不同,但它仍然是非用户形式的 tictactoe :)

    游玩区域为 E4:G6,需要在代码中手动更改

    'This is saved on the worksheet itself
    
    Option Explicit
    'Public because any "= something" operation is executed on each cell-change
    'thus the value has to be defined outside the sub to not reset it each iteration,
    'breaking the loop that switches between X and O
    Public rCounter As Integer
    
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
        Dim rInt As Range
        Dim rCell As Range
        Dim msg As Variant
    
    
        Dim xOffset As Integer
        Dim yOffset As Integer
        
        'This is the center cell's position
        xOffset = 5
        yOffset = 6
        
        Set rInt = Intersect(Target, Range("E4:G6"))
        If Not rInt Is Nothing Then
            For Each rCell In rInt
            If rCell.Value = "X" Or rCell.Value = "O" Then
               msg = MsgBox("You can't choose this cell!", vbOKOnly + vbInformation)
               Else
               If rCounter Mod 2 Then
               'Change these to interior.color and you have colors instead, you would 
               'need to adjust the entire code to match that though
               rCell.Value = "X"
               Else
               rCell.Value = "O"
               End If
               End If
               
            Next
        End If
        
        
        If Cells(xOffset, yOffset).Value = "X" And Cells(xOffset + 1, yOffset).Value = "X" And Cells(xOffset - 1, yOffset).Value = "X" Or Cells(xOffset, yOffset).Value = "X" And Cells(xOffset - 1, yOffset + 1).Value = "X" And Cells(xOffset + 1, yOffset - 1).Value = "X" Or Cells(xOffset, yOffset).Value = "X" And Cells(xOffset - 1, yOffset - 1).Value = "X" And Cells(xOffset + 1, yOffset + 1).Value = "X" Or Cells(xOffset, yOffset - 1).Value = "X" And Cells(xOffset - 1, yOffset - 1).Value = "X" And Cells(xOffset + 1, yOffset - 1).Value = "X" Or Cells(xOffset, yOffset + 1).Value = "X" And Cells(xOffset - 1, yOffset + 1).Value = "X" And Cells(xOffset + 1, yOffset + 1).Value = "X" Then
        msg = MsgBox("Player X wins!", vbOKOnly)
        wClearTicTacToe
        End If
        If Cells(xOffset, yOffset).Value = "O" And Cells(xOffset + 1, yOffset).Value = "O" And Cells(xOffset - 1, yOffset).Value = "O" Or Cells(xOffset, yOffset).Value = "O" And Cells(xOffset - 1, yOffset + 1).Value = "O" And Cells(xOffset + 1, yOffset - 1).Value = "O" Or Cells(xOffset, yOffset).Value = "O" And Cells(xOffset - 1, yOffset - 1).Value = "O" And Cells(xOffset + 1, yOffset + 1).Value = "O" Or Cells(xOffset, yOffset - 1).Value = "O" And Cells(xOffset - 1, yOffset - 1).Value = "O" And Cells(xOffset + 1, yOffset - 1).Value = "O" Or Cells(xOffset, yOffset + 1).Value = "O" And Cells(xOffset - 1, yOffset + 1).Value = "O" And Cells(xOffset + 1, yOffset + 1).Value = "O" Then
        msg = MsgBox("Player O wins!", vbOKOnly)
        wClearTicTacToe
        End If
        
        Set rInt = Nothing
        Set rCell = Nothing
        rCounter = rCounter + 1
    End Sub
    
    Sub wClearTicTacToe()
    Range("E4:G6").Value = ""
    End Sub
    
    
    
    

    【讨论】:

      【解决方案3】:

      空单元格的颜色不是xlNone,而是vbWhite

      改变这一行:

      If Cells(r1, r2).Interior.Color = xlNone Then
      

      到:

      If Cells(r1, r2).Interior.Color = vbWhite Then
      

      并且您的代码有效。

      请注意,如果Cells(r1, r2) 是现有的红色单元格,那么您的代码不会向板上添加新的红色计数器。

      【讨论】:

        猜你喜欢
        • 2019-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多