tictactoe-in-go/game/gameloop.go

123 lines
3.0 KiB
Go

package game
import (
"tictactoe/gamecontrol"
"tictactoe/opponent"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
)
var board = [3][3]string{
{" ", " ", " "},
{" ", " ", " "},
{" ", " ", " "},
}
const (
PLAYER_X = "X"
PLAYER_O = "O"
)
var gridContainer *fyne.Container
// creates the button grid for the tictactoe game
func MakeButtonGrid(rows, cols int) *fyne.Container {
// generates layout and grid container
gridLayout := layout.NewGridLayout(cols)
gridContainer = container.New(gridLayout)
// create the 3x3 Button grid
for row := 0; row < rows; row++ {
for col := 0; col < cols; col++ {
button := CreateButton(row, col)
gridContainer.Add(button)
}
}
return gridContainer
}
// create the button grid and adds key press handler for each grid-button
func CreateButton(row, col int) *widget.Button {
button := widget.NewButton(" ", nil)
button.OnTapped = func() {
if button.Text == " " {
button.SetText(PLAYER_X)
Gameloop(row, col)
}
}
return button
}
// reset the game by clearing the buttons and the board array
func ResetButtonTexts(container *fyne.Container) {
for _, child := range container.Objects {
if btn, ok := child.(*widget.Button); ok {
btn.SetText(" ")
}
}
board = [3][3]string{
{" ", " ", " "},
{" ", " ", " "},
{" ", " ", " "},
}
EnableAllButtons(gridContainer)
TextLabel.SetText("TicTacToe")
}
// apply AI opponent text to the button
func ChangeButtonText(row, col int) {
gridContainer.Objects[col+row*3].(*widget.Button).SetText("O")
}
// gameloop function for the game process:
// human makes a move, AI counters
func Gameloop(row, col int) {
// starting with the human making a move
board[row][col] = PLAYER_X
// checking if the game has been won by the human player
if gamecontrol.PlayerHasWon(board, PLAYER_X) {
TextLabel.SetText("X Wins")
}
// checking if the game is a draw
if gamecontrol.BoardisFull(board) {
TextLabel.SetText("Draw")
}
// AI opponent makes a move
bestMove := opponent.Minimax(board, 0, true, PLAYER_O)
// add the move to the board
board[bestMove.Row][bestMove.Col] = PLAYER_O
ChangeButtonText(bestMove.Row, bestMove.Col)
// check if AI opponent has won the game
if gamecontrol.PlayerHasWon(board, PLAYER_O) {
TextLabel.SetText("O Wins")
DisableAllButtons(gridContainer)
}
// checking if the game is a draw
if gamecontrol.BoardisFull(board) {
TextLabel.SetText("Draw")
}
}
// function to disable all buttons inside the grid
func DisableAllButtons(container *fyne.Container) {
for _, child := range container.Objects {
if btn, ok := child.(*widget.Button); ok {
btn.Disable()
}
}
}
// function to enable all buttons inside the grid
func EnableAllButtons(container *fyne.Container) {
for _, child := range container.Objects {
if btn, ok := child.(*widget.Button); ok {
btn.Enable()
}
}
}