package game import ( "tictactoe/gameControl" "tictactoe/opponent" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/dialog" "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, Window fyne.Window) *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, Window) gridContainer.Add(button) } } return gridContainer } // create the button grid and adds key press handler for each grid-button func CreateButton(row, col int, Window fyne.Window) *widget.Button { button := widget.NewButton(" ", nil) button.OnTapped = func() { if button.Text == " " { button.SetText(PLAYER_X) Gameloop(row, col, Window) } } 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) } // 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, Window fyne.Window) { const gameOverText string = "Game Over" // 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) { dialog.ShowInformation(gameOverText, "X has won!", Window) } // checking if the game is a draw if gameControl.BoardisFull(board) { dialog.ShowInformation(gameOverText, "It's a draw!", Window) } // 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) { dialog.ShowInformation(gameOverText, "O has won!", Window) DisableAllButtons(gridContainer) } // checking if the game is a draw if gameControl.BoardisFull(board) { dialog.ShowInformation(gameOverText, "It's a draw!", Window) DisableAllButtons(gridContainer) } } // 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() } } }