Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'Test application to tes the minmax algorithm, as well as alpha-beta pruning inside of it. A tic-tac--toe program that will never lose. By Keegan Parker
- Public Class Form1
- Public Const PLAYER_PIECE As String = "X"
- Public Const COMPUTER_PIECE As String = "O"
- Public Const HUMAN_WIN As Integer = -1
- Public Const COMPUTER_WIN As Integer = 1
- Public Const TIE As Integer = 0
- Public Const COMPUTER As Boolean = True
- Public Const HUMAN As Boolean = False
- Public Game_Ended As Boolean = False
- Public Turn As String = "Human"
- Public Board(2, 2) As Board
- 'Sets all objects up (mostly labels, and the board)
- Private Sub On_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- Dim intindex As Integer
- Dim intindex2 As Integer
- For intindex = 0 To 2
- For intindex2 = 0 To 2
- Dim Label As New Label
- Label.Name = "lbl" & intindex & intindex2
- Label.AutoSize = False
- Label.TextAlign = ContentAlignment.MiddleCenter
- Label.Font = New Font("Arial", 48, FontStyle.Bold)
- Label.Size = New System.Drawing.Size(100, 100)
- Label.Location = New System.Drawing.Point(intindex * 100, intindex2 * 100)
- Label.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
- Board(intindex, intindex2).lbl = Label
- Board(intindex, intindex2).posX = intindex
- Board(intindex, intindex2).posY = intindex2
- Me.Controls.Add(Label)
- AddHandler Board(intindex, intindex2).lbl.Click, AddressOf Player_Move
- Next
- Next
- End Sub
- 'If a player clicks on one of the labels, it will attmpt to put a player piece on that tile, and direct the game to the computer's turn.
- Sub Player_Move(ByVal sender As System.Object, ByVal e As System.EventArgs)
- Dim Current_Board As Board = GetBoard(sender)
- Dim Best As Best
- If Current_Board.owner = Nothing Then
- Board(Current_Board.posX, Current_Board.posY).owner = PLAYER_PIECE
- Board(Current_Board.posX, Current_Board.posY).lbl.Text = PLAYER_PIECE
- Call Check_Board(Board, False)
- If Game_Ended = False Then
- Turn = "Computer"
- Best = Get_Computer_Move(COMPUTER, Board)
- Board(Best.MovePosX, Best.MovePosY).owner = COMPUTER_PIECE
- Board(Best.MovePosX, Best.MovePosY).lbl.Text = COMPUTER_PIECE
- Call Check_Board(Board, False)
- End If
- Game_Ended = False
- Turn = "Human"
- End If
- End Sub
- 'Checks win/tie conditions. If it is a simulation (for ai), then it will return a number. If it is for legitimate checking, it will call the win function, or tie.
- Function Check_Board(ByVal opBoard(,) As Board, ByVal simulation As Boolean)
- Dim intindex As Integer
- Dim intindex2 As Integer
- 'Vertical Check
- For intindex = 0 To 2
- If opBoard(intindex, 0).owner = opBoard(intindex, 1).owner And opBoard(intindex, 1).owner = opBoard(intindex, 2).owner And opBoard(intindex, 0).owner <> Nothing Then
- If simulation = False Then
- Win()
- Else
- Return 1
- End If
- End If
- Next
- 'Horizantal Check
- For intindex = 0 To 2
- If opBoard(0, intindex).owner = opBoard(1, intindex).owner And opBoard(1, intindex).owner = opBoard(2, intindex).owner And opBoard(0, intindex).owner <> Nothing Then
- If simulation = False Then
- Win()
- Else
- Return 1
- End If
- End If
- Next
- 'Diagonal Check
- Dim intoppindex As Integer
- Dim intoppindex2 As Integer
- For intindex = 0 To 2 Step 2
- For intindex2 = 0 To 2 Step 2
- If intindex = 0 Then
- intoppindex = 2
- Else
- intoppindex = 0
- End If
- If intindex2 = 0 Then
- intoppindex2 = 2
- Else
- intoppindex2 = 0
- End If
- If opBoard(intindex, intindex2).owner = opBoard(1, 1).owner And opBoard(1, 1).owner = opBoard(intoppindex, intoppindex2).owner And opBoard(intindex, intindex2).owner <> Nothing Then
- If simulation = False Then
- Win()
- Else
- Return 1
- End If
- End If
- Next
- Next
- 'Full Board
- Dim movedcount As Integer
- For intindex = 0 To 2
- For intindex2 = 0 To 2
- If opBoard(intindex, intindex2).owner <> Nothing Then
- movedcount += 1
- End If
- Next
- Next
- If movedcount = 9 Then
- If simulation = False Then
- MessageBox.Show("It is a tie. Resetting the board.")
- For intindex = 0 To 2
- For intindex2 = 0 To 2
- Board(intindex, intindex2).owner = Nothing
- Board(intindex, intindex2).lbl.Text = Nothing
- Next
- Next
- Game_Ended = True
- Else
- Return 0
- End If
- End If
- Return Nothing
- End Function
- 'Allows labels to be processed in to the board
- Public Function GetBoard(ByVal sender As Label)
- Dim intindex As Integer
- Dim intindex2 As Integer
- For intindex = 0 To 2
- For intindex2 = 0 To 2
- If Board(intindex, intindex2).lbl.Name = sender.Name Then
- Return Board(intindex, intindex2)
- End If
- Next
- Next
- Return Nothing
- End Function
- 'If a player wins, it will display a message box and reset the board
- Sub Win()
- MessageBox.Show(Turn & " has won. Resetting the board.")
- Dim intindex As Integer
- Dim intindex2 As Integer
- For intindex = 0 To 2
- For intindex2 = 0 To 2
- Board(intindex, intindex2).owner = Nothing
- Board(intindex, intindex2).lbl.Text = Nothing
- Next
- Next
- Game_Ended = True
- End Sub
- 'Minmax algorithm that tries to get best possible move by accessing every possible scenario in the game tree. NOT WORKING. Returns a "best" object, that is then used to place the computer's piece.
- Public Function Get_Computer_Move(ByVal side As Boolean, ByVal opBoard(,) As Board)
- Dim mybest As New Best
- Dim reply As Best
- Dim LegalMoves As New List(Of LegalMove)
- LegalMoves = Get_Legal_Moves(opBoard)
- Dim oppside As Boolean
- If side = COMPUTER Then
- oppside = HUMAN
- Else
- oppside = COMPUTER
- End If
- If Check_Board(opBoard, True) <> Nothing Then
- mybest.Score = Check_Board(opBoard, True)
- Return mybest
- End If
- If side = COMPUTER Then
- mybest.Score = -2
- Else
- mybest.Score = 2
- End If
- For Each LegalMove In LegalMoves
- If side = COMPUTER Then
- opBoard(LegalMove.posX, LegalMove.posY).owner = COMPUTER_PIECE
- Else
- opBoard(LegalMove.posX, LegalMove.posY).owner = PLAYER_PIECE
- End If
- reply = Get_Computer_Move(oppside, opBoard)
- opBoard(LegalMove.posX, LegalMove.posY).owner = Nothing
- If (side = COMPUTER And reply.Score > mybest.Score) Or (side = HUMAN And reply.Score < mybest.Score) Then
- mybest.MovePosX = LegalMove.posX
- mybest.MovePosY = LegalMove.posY
- mybest.Score = reply.Score
- End If
- Next
- Return mybest
- End Function
- 'Returns potential legal moves on the board
- Public Function Get_Legal_Moves(ByVal opboard(,) As Board)
- Dim intindex As Integer
- Dim intindex2 As Integer
- Dim legalmoves As New List(Of LegalMove)
- For intindex = 0 To 2
- For intindex2 = 0 To 2
- If opboard(intindex, intindex2).owner = Nothing Then
- Dim legalmove As New LegalMove
- legalmove.posX = intindex
- legalmove.posY = intindex2
- legalmoves.Add(legalmove)
- End If
- Next
- Next
- Return legalmoves
- End Function
- End Class
- Public Structure Board
- Public lbl As Label
- Public owner As String
- Public posX As Integer
- Public posY As Integer
- End Structure
- Public Structure LegalMove
- Public posX As Integer
- Public posY As Integer
- End Structure
- Public Structure Best
- Public MovePosX As Integer
- Public MovePosY As Integer
- Public Score As Integer
- End Structure
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement