views:

272

answers:

2

I'm having 2 problems with my game.

1.) Upon initialization, if I select multiplayer, the buttons are still disabled. I have to refresh to get it to work.

2.) When I'm doing single player, my AI is not working right. When the AI picks its square, it still lets me choose a square with the AI's symbol as if I'm playing a multiplayer game. I even specified in the AI sub class that turn = 1 when the AI's turn is done, meaning it should be my turn.

Public Class frmTicTacToe

Dim turn As Integer
Dim computer As Integer
Private Sub AI()
    Call Win()
    If turn <> 1 Then
        computer = Int(9 * Rnd()) + 1
    End If

    If computer = 1 Then
        btnOne.Text = "O"
        turn = 1
    End If

    If computer = 2 Then
        btnTwo.Text = "O"
        turn = 1
    End If

    If computer = 3 Then
        btnThree.Text = "O"
        turn = 1
    End If

    If computer = 4 Then
        btnFour.Text = "O"
        turn = 1
    End If

    If computer = 5 Then
        btnFive.Text = "O"
        turn = 1
    End If

    If computer = 6 Then
        btnSix.Text = "O"
        turn = 1
    End If

    If computer = 7 Then
        btnSeven.Text = "O"
        turn = 1
    End If

    If computer = 8 Then
        btnEight.Text = "O"
        turn = 1
    End If

    If computer = 9 Then
        btnNine.Text = "O"
        turn = 1
    End If

End Sub
Private Sub Win()
    If btnOne.Text = "X" And btnTwo.Text = "X" And btnThree.Text = "X" Then
        txtSummary.Text = "Player 1 Wins"
        MsgBox("Player 1 Wins")
        Call disablebuttons()

    ElseIf btnOne.Text = "X" And btnFour.Text = "X" And btnSeven.Text = "X" Then
        txtSummary.Text = "Player 1 Wins!"
        MsgBox("Player 1 Wins")
        Call disablebuttons()

    ElseIf btnOne.Text = "X" And btnFive.Text = "X" And btnNine.Text = "X" Then
        txtSummary.Text = "Player 1 Wins!"
        MsgBox("Player 1 Wins")
        Call disablebuttons()

    ElseIf btnThree.Text = "X" And btnSix.Text = "X" And btnNine.Text = "X" Then
        txtSummary.Text = "Player 1 Wins!"
        MsgBox("Player 1 Wins")
        Call disablebuttons()

    ElseIf btnSeven.Text = "X" And btnEight.Text = "X" And btnNine.Text = "X" Then
        txtSummary.Text = "Player 1 Wins!"
        MsgBox("Player 1 Wins")
        Call disablebuttons()

    ElseIf btnFour.Text = "X" And btnFive.Text = "X" And btnSix.Text = "X" Then
        txtSummary.Text = "Player 1 Wins!"
        MsgBox("Player 1 Wins")
        Call disablebuttons()

    ElseIf btnTwo.Text = "X" And btnFive.Text = "X" And btnEight.Text = "X" Then
        txtSummary.Text = "Player 1 Wins!"
        MsgBox("Player 1 Wins")
        Call disablebuttons()

    ElseIf btnThree.Text = "X" And btnFive.Text = "X" And btnSeven.Text = "X" Then
        txtSummary.Text = "Player 1 Wins!"
        MsgBox("Player 1 Wins")
        Call disablebuttons()
    End If

    If btnOne.Text = "O" And btnTwo.Text = "O" And btnThree.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()

    ElseIf btnOne.Text = "O" And btnFour.Text = "O" And btnSeven.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()

    ElseIf btnOne.Text = "O" And btnFive.Text = "O" And btnNine.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()

    ElseIf btnThree.Text = "O" And btnSix.Text = "O" And btnNine.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()

    ElseIf btnSeven.Text = "O" And btnEight.Text = "O" And btnNine.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()

    ElseIf btnFour.Text = "O" And btnFive.Text = "O" And btnSix.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()

    ElseIf btnTwo.Text = "O" And btnFive.Text = "O" And btnEight.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()

    ElseIf btnThree.Text = "O" And btnFive.Text = "O" And btnSeven.Text = "O" Then
        txtSummary.Text = "Player 2 Wins!"
        MsgBox("Player 2 Wins")
        Call disablebuttons()
    End If
End Sub
Private Sub disablebuttons()
    btnOne.Enabled = False
    btnTwo.Enabled = False
    btnThree.Enabled = False
    btnFour.Enabled = False
    btnFive.Enabled = False
    btnSix.Enabled = False
    btnSeven.Enabled = False
    btnEight.Enabled = False
    btnNine.Enabled = False
End Sub

Private Sub btnOne_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOne.Click
    If turn = 1 Then
        btnOne.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnOne.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnOne.Enabled = False

End Sub

Private Sub btnTwo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTwo.Click
    If turn = 1 Then
        btnTwo.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnTwo.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnTwo.Enabled = False
End Sub

Private Sub btnThree_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnThree.Click
    If turn = 1 Then
        btnThree.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnThree.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnThree.Enabled = False
End Sub

Private Sub btnFour_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFour.Click
    If turn = 1 Then
        btnFour.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnFour.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnFour.Enabled = False
End Sub

Private Sub btnFive_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFive.Click
    If turn = 1 Then
        btnFive.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnFive.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnFive.Enabled = False
End Sub

Private Sub btnSix_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSix.Click
    If turn = 1 Then
        btnSix.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnSix.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnSix.Enabled = False
End Sub

Private Sub btnSeven_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSeven.Click
    If turn = 1 Then
        btnSeven.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnSeven.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnSeven.Enabled = False
End Sub

Private Sub btnEight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEight.Click
    If turn = 1 Then
        btnEight.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnEight.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnEight.Enabled = False
End Sub

Private Sub btnNine_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNine.Click
    If turn = 1 Then
        btnNine.Text = "X"
        txtSummary.Text = "Player 2's Turn"
    Else
        btnNine.Text = "O"
        txtSummary.Text = "Player 1's Turn"
    End If
    turn += 1
    If turn > 2 Then
        turn = 1
    End If

    If rdoSinglePlayer.Checked Then Call AI()
    Call Win()
    btnNine.Enabled = False
End Sub

Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click
    btnOne.Text = ""
    btnOne.Enabled = True
    btnTwo.Text = ""
    btnTwo.Enabled = True
    btnThree.Text = ""
    btnThree.Enabled = True
    btnFour.Text = ""
    btnFour.Enabled = True
    btnFive.Text = ""
    btnFive.Enabled = True
    btnSix.Text = ""
    btnSix.Enabled = True
    btnSeven.Text = ""
    btnSeven.Enabled = True
    btnEight.Text = ""
    btnEight.Enabled = True
    btnNine.Text = ""
    btnNine.Enabled = True
    rdoSinglePlayer.Checked = False
    rdoMultiplayer.Checked = False
    If turn = 1 Then
        txtSummary.Text = "Player 1's Turn"
    Else
        txtSummary.Text = "Player 2's Turn"
    End If
End Sub

Private Sub frmTicTacToe_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    txtSummary.Text = "Select Single Player or Multiplayer"

    If rdoSinglePlayer.Checked = False And rdoMultiplayer.Checked = False Then
        Call disablebuttons()
    End If

    If rdoSinglePlayer.Checked = True Or rdoMultiplayer.Checked = True Then
        turn = 1
    End If

End Sub
Private Sub Start()
    btnOne.Text = ""
    btnOne.Enabled = True
    btnTwo.Text = ""
    btnTwo.Enabled = True
    btnThree.Text = ""
    btnThree.Enabled = True
    btnFour.Text = ""
    btnFour.Enabled = True
    btnFive.Text = ""
    btnFive.Enabled = True
    btnSix.Text = ""
    btnSix.Enabled = True
    btnSeven.Text = ""
    btnSeven.Enabled = True
    btnEight.Text = ""
    btnEight.Enabled = True
    btnNine.Text = ""
    btnNine.Enabled = True
    If turn = 1 Then
        txtSummary.Text = "Player 1's Turn"
    Else
        txtSummary.Text = "Player 2's Turn"
    End If
End Sub
Private Sub rdoSinglePlayer_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rdoSinglePlayer.CheckedChanged
    Call Start()
End Sub

Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
    Me.Close()
End Sub

Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
    Dim AboutBox1 As New AboutBox1
    AboutBox1.Show()
End Sub

Private Sub ResetToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ResetToolStripMenuItem.Click
    btnOne.Text = ""
    btnOne.Enabled = True
    btnTwo.Text = ""
    btnTwo.Enabled = True
    btnThree.Text = ""
    btnThree.Enabled = True
    btnFour.Text = ""
    btnFour.Enabled = True
    btnFive.Text = ""
    btnFive.Enabled = True
    btnSix.Text = ""
    btnSix.Enabled = True
    btnSeven.Text = ""
    btnSeven.Enabled = True
    btnEight.Text = ""
    btnEight.Enabled = True
    btnNine.Text = ""
    btnNine.Enabled = True
    rdoSinglePlayer.Checked = False
    rdoMultiplayer.Checked = False
    If turn = 1 Then
        txtSummary.Text = "Player 1's Turn"
    Else
        txtSummary.Text = "Player 2's Turn"
    End If
End Sub

End Class

+2  A: 

Four problems I'm noticing off the bat:

  • Your AI() method can overwrite previously selected squares.
  • You probably want to disable the button the AI selects as well:
    If computer = 1 Then
        btnOne.Text = "O"
        turn = 1
        btnOne.Enabled = False
    End If
  • You're not resetting the text, so it looks like it's still player 2's turn after the AI goes:
    If computer = 1 Then
        btnOne.Text = "O"
        turn = 1
        txtSummary.Text = "Player 1's Turn"
        btnOne.Enabled = False
    End If
  • You're letting the AI go every time without checking win conditions first. The simplest would be to change Win() to a function returning boolean, then return true if game over, false if not. Then change your AI() call to the following:
    If Not Win() Then
         If rdoSinglePlayer.Checked Then Call AI()
    End If

Other suggestions include:

  • You have lots of repeated code. Think about refactoring it into a single method that is called multiple times. This makes your code much easier to maintain and much more readable. For one example, you could have (assuming Win() returns a boolean like above):
    Private Sub NextTurn()
        If Not Win() Then
            If turn = 1 Then
                txtSummary.Text = "Player 2's Turn"
                turn = 2
                If rdoSinglePlayer.Checked Then Call AI()
            Else
                txtSummary.Text = "Player 1's Turn"
                turn = 1
            End
        End If
    End Sub

    Private Sub btnOne_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOne.Click
        If turn = 1 Then
            btnOne.Text = "X"
            txtSummary.Text = "Player 2's Turn"
        Else
            btnOne.Text = "O"
            txtSummary.Text = "Player 1's Turn"
        End If
        turn += 1
        If turn > 2 Then
            turn = 1
        End If

        If rdoSinglePlayer.Checked Then Call AI()
        Call Win()
        btnOne.Enabled = False
        Call NextTurn()
    End Sub
lc
+3  A: 

Trust me on this one. You have more than 2 problems with your game.

With respect to (1), I don't see a handler for the multiplayer button. For the single player button, you re-enable the buttons, but for multiplayer you don't. Add a handler and do the multiplayer set up in it.

With respect to (2), you need to disable the button when the computer chooses it. As it is, the button is only disabled when it is clicked by the user. In the AI routine, after you change the button text, disable it.

To start you thinking: consider that there are really only 8 possible "winning" positions: 4 involve the center and 1 each for the side-center square on each side. You only need to test if any of these combinations have the same button text for all three squares involved in the combination. If you check after every move, the maker of the current move had better be the winner if there is one, so you really only need to check until you find a square in the combination that doesn't match the current move maker. This will greatly improve the speed of your Win() method.

tvanfosson