Question

I'm working on creating a Tic Tac Toe game in Visual Basic. I'm having lots of problems, but the one I'm focusing on right now is this:

There are 2 players, one human, and the other is the computer. What would be the simplest way to determine whose turn it is? I mean, clearly one player will be X and the other will be O, so I need to figure out how to determine whose turn it is so the program knows what letter to set as the text of the button.

Here is what I have for this portion of the code, but it's missing the part that would tell whether it places an X or an O since that's what my question is about.

    Public Class Form1

Private _currentPlayer As String = "O"
Private _gameArray As String
Dim turn As Integer = 1
Private _gameArray1 As Object

Private Property gameArray(p1 As Integer, p2 As Integer) As String
    Get
        Return _gameArray
    End Get
    Set(value As String)
        _gameArray = value
    End Set
End Property

Private Property gameArray(i As Integer) As Object
    Get
        Return _gameArray1
    End Get
    Set(value As Object)
        _gameArray1 = value
    End Set
End Property

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    MessageBox.Show("Welcome to Tic Tac Toe! Would you like to play a game?")
End Sub

Private Function nextPlayer() As String

    If _currentPlayer.Equals("O") Then
        _currentPlayer = "X"
        Return "O"
    Else
        _currentPlayer = "O"
        Return "X"
    End If

End Function

Private Sub printView()
    Console.WriteLine(btn1.Text & "|" & btn2.Text & "|" & btn3.Text)
    Console.WriteLine("----------------")
    Console.WriteLine(btn4.Text & "|" & btn5.Text & "|" & btn6.Text)
    Console.WriteLine("----------------")
    Console.WriteLine(btn7.Text & "|" & btn8.Text & "|" & btn9.Text)
End Sub

Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
    Console.WriteLine(e.KeyChar)

    Select Case e.KeyChar
        Case "1"
            btn1.Text = "X"
        Case "2"
            btn2.Text = "X"
        Case "3"
            btn3.Text = "X"
        Case "4"
            btn4.Text = "X"
        Case "5"
            btn5.Text = "X"
        Case "6"
            btn6.Text = "X"
        Case "7"
            btn7.Text = "X"
        Case "8"
            btn8.Text = "X"
        Case "9"
            btn9.Text = "X"
    End Select
    printView()
End Sub

Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
    If turn = 1 Or 3 Or 5 Or 7 Or 9 Then
        btn1.Text = "X"
        gameArray(0, 0) = "X"
        checkwin()
    ElseIf (Not String.IsNullOrEmpty(btn1.Text)) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn1.Text = "O"
    End If
    turn += 1
End Sub

Private Sub btn2_Click(sender As Object, e As EventArgs) Handles btn2.Click
    If turn = 1 Or 3 Or 5 Or 7 Or 9 Then
        btn2.Text = "X"
        gameArray(0, 2) = "X"
        checkwin()
    ElseIf (Not String.IsNullOrEmpty(btn1.Text)) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn2.Text = "O"
    End If
    turn += 1
End Sub

Private Sub btn3_Click(sender As Object, e As EventArgs) Handles btn3.Click
    If turn = 1 Or 3 Or 5 Or 7 Or 9 Then
        turn = 3
        btn3.Text = "X"
        gameArray(1, 0) = "X"
        checkwin()
    ElseIf (Not String.IsNullOrEmpty(btn1.Text)) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn3.Text = "O"
    End If

End Sub

Private Sub btn4_Click(sender As Object, e As EventArgs) Handles btn4.Click
    If Not String.IsNullOrEmpty(btn4.Text) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn4.Text = nextPlayer()
        gameArray(1, 0) = nextPlayer()
        checkwin()
    End If
End Sub

Private Sub btn5_Click(sender As Object, e As EventArgs) Handles btn5.Click
    If Not String.IsNullOrEmpty(btn5.Text) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn5.Text = nextPlayer()
        gameArray(1, 1) = nextPlayer()
        checkwin()
    End If
End Sub

Private Sub btn6_Click(sender As Object, e As EventArgs) Handles btn6.Click
    If Not String.IsNullOrEmpty(btn6.Text) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn6.Text = nextPlayer()
        gameArray(1, 2) = nextPlayer()
        checkwin()
    End If
End Sub

Private Sub btn7_Click(sender As Object, e As EventArgs) Handles btn7.Click
    If Not String.IsNullOrEmpty(btn7.Text) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn7.Text = nextPlayer()
        gameArray(2, 0) = nextPlayer()
        checkwin()
    End If
End Sub

Private Sub btn8_Click(sender As Object, e As EventArgs) Handles btn8.Click
    If Not String.IsNullOrEmpty(btn8.Text) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn8.Text = nextPlayer()
        gameArray(2, 1) = nextPlayer()
        checkwin()
    End If
End Sub

Private Sub btn9_Click(sender As Object, e As EventArgs) Handles btn9.Click
    If Not String.IsNullOrEmpty(btn9.Text) Then
        MessageBox.Show("This position has already been taken, please select an empty square.")
    Else
        btn9.Text = nextPlayer()
        gameArray(2, 2) = nextPlayer()
        checkwin()
    End If
End Sub

Private Sub checkwin()

    If (btn1.Text = "X") And (btn2.Text = "X") And (btn3.Text = "X") Then MsgBox("X WINS!")
    If (btn4.Text = "X") And (btn5.Text = "X") And (btn6.Text = "X") Then MsgBox("X WINS!")
    If (btn7.Text = "X") And (btn8.Text = "X") And (btn9.Text = "X") Then MsgBox("X WINS!")
    If (btn1.Text = "X") And (btn4.Text = "X") And (btn7.Text = "X") Then MsgBox("X WINS!")
    If (btn2.Text = "X") And (btn5.Text = "X") And (btn8.Text = "X") Then MsgBox("X WINS!")
    If (btn3.Text = "X") And (btn6.Text = "X") And (btn9.Text = "X") Then MsgBox("X WINS!")
    If (btn1.Text = "X") And (btn5.Text = "X") And (btn9.Text = "X") Then MsgBox("X WINS!")
    If (btn3.Text = "X") And (btn5.Text = "X") And (btn7.Text = "X") Then MsgBox("X WINS!")

    If (btn1.Text = "O") And (btn2.Text = "O") And (btn3.Text = "O") Then MsgBox("O WINS!")
    If (btn4.Text = "O") And (btn5.Text = "O") And (btn6.Text = "O") Then MsgBox("O WINS!")
    If (btn7.Text = "O") And (btn8.Text = "O") And (btn9.Text = "O") Then MsgBox("O WINS!")
    If (btn1.Text = "O") And (btn4.Text = "O") And (btn7.Text = "O") Then MsgBox("O WINS!")
    If (btn2.Text = "O") And (btn5.Text = "O") And (btn8.Text = "O") Then MsgBox("O WINS!")
    If (btn3.Text = "O") And (btn6.Text = "O") And (btn9.Text = "O") Then MsgBox("O WINS!")
    If (btn1.Text = "O") And (btn5.Text = "O") And (btn9.Text = "O") Then MsgBox("O WINS!")
    If (btn3.Text = "O") And (btn5.Text = "O") And (btn7.Text = "O") Then MsgBox("O WINS!")
End Sub


End Class
Was it helpful?

Solution

Have a private variable in the main class:

Private _currentPlayer as String = "O"

This sets the initial player as O

Then have a simple function that flips between X and O output:

Private Function nextPlayer() As String

    If _currentPlayer.Equals("O") Then
        _currentPlayer = "X"
        Return "O"
    Else
        _currentPlayer = "O"
        Return "X"
    End If

End Function

Then change your function to use this new helper:

Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
    If btn1.Text <> Nothing Then
        btn1.Text = nextPlayer()
         gameArray(0, 0) = nextPlayer()
    Else
        MessageBox.Show("This position has already been taken, please select an empty square.")
    End If
End Sub

OTHER TIPS

I would suggest storing the players in an array, and having a reference to the first player.

Sorry I can't remember VB syntax very well:

Private _players As List Of Player

When you initialise

_players.Add(new HumanPlayer(...))
_players.Add(new ComputerPlayer(...))

then store a reference to whichever one is currently playing, possibly with a EndTurn() function that advances the turn.

Private currentPlayer as IPlayer = _players.First()

Then a little function to advance it to the next player.

Apologies for my code being invalid VB I haven't done any VB for years.

This pattern makes your program a bit more flexible and easier to read, it also addresses the separation of concerns if you classes and interfaces correctly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top