tictactoe-in-go/opponent/minimax.go

86 lines
2.2 KiB
Go

package opponent
import (
"math"
"tictactoe/gamecontrol"
)
type NextMove struct {
Row int
Col int
score int
}
// iterative implementation of minimax algorithm
func Minimax(board [3][3]string, depth int, isMaximizingPlayer bool, player string) NextMove {
// check if the game has ended
if gamecontrol.PlayerHasWon(board, "X") {
return NextMove{score: -10 + depth}
} else if gamecontrol.PlayerHasWon(board, "O") {
return NextMove{score: 10 - depth}
} else if gamecontrol.BoardisFull(board) {
return NextMove{score: 0}
}
// check who's turn it is
if isMaximizingPlayer {
// set max score
bestScore := math.MinInt64
var bestMove NextMove
// iterate through all fields
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
// check if field is empty
if board[i][j] == " " {
// make a move on this field
board[i][j] = player
// continue with the other player
move := Minimax(board, depth+1, false, SwitchPlayer(player))
// reset the field again
board[i][j] = " "
// if this move was better then the move before change values
if move.score > bestScore {
bestScore = move.score
bestMove = NextMove{Row: i, Col: j, score: move.score}
}
}
}
}
// return best possible Move
return bestMove
} else {
// set min score
bestScore := math.MaxInt64
var bestMove NextMove
// iterate through all fields
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
// check if field is empty
if board[i][j] == " " {
// make a move on this field
board[i][j] = player
// continue with the other player
move := Minimax(board, depth+1, true, SwitchPlayer(player))
// reset the field again
board[i][j] = " "
// if this move was better then the move before change values
if move.score < bestScore {
bestScore = move.score
bestMove = NextMove{Row: i, Col: j, score: move.score}
}
}
}
}
// return best possible Move
return bestMove
}
}
// this function changes the player for the minimax algorthim
func SwitchPlayer(player string) string {
if player == "X" {
return "O"
} else {
return "X"
}
}