Godot Version
Godot 4.3
Question
So i’m coding a tic tac toe game where you can play ultimate tic tac toe or simple tic tac toe with AI functions and yourself functions… But i got it to when you win it shows a popup and you can go home:
But I want the text to be above the button and a little more displayed and I want it so when you click off of it won’t disappear.
That is my setup with SceneTree of AISimpleTicTacToe.tscn
Here is my AISimpleTicTacToe.gd script:
extends Control
Game variables
var current_player: String = “X”
var board: Array = # Array to store the state of the board (empty initially)
var buttons: Array = # Store references to the 9 buttons
var ai_difficulty: String = “Hard” # Set to “Easy”, “Medium”, or “Hard”
Called when the scene is loaded
func _ready():
# Initialize the game state
reset_game()
# Get all buttons from the GridContainer and connect them to the clicked function
buttons = $GridContainer.get_children()
for button in buttons:
button.connect("pressed", Callable(self, "_on_button_pressed").bind(button)) # Pass the button instance correctly
# Start the game with AI's turn if it's X's turn
if current_player == "O":
ai_turn()
Resets the game board
func reset_game():
board = [“”, “”, “”, “”, “”, “”, “”, “”, “”] # 9 empty slots
current_player = “X” # X starts first
for button in buttons:
button.text = “” # Clear button text
button.disabled = false # Re-enable the buttons
Called when a button is pressed
func _on_button_pressed(button: Button):
# Ensure it’s one of our buttons
if button in buttons: # Check if the pressed button is in our list
var index = buttons.find(button) # Get the index of the pressed button
# If the board slot is empty, place the current player's mark
if board[index] == "":
board[index] = current_player
button.text = current_player # Update the button text to show "X" or "O"
button.disabled = true # Disable the button after clicking
# Check for win condition
if check_for_win():
show_winner_popup(current_player)
disable_all_buttons()
return # End the function here
# Check for draw condition
if board.count("") == 0: # Check if there are no empty slots left
print("It's a draw!")
disable_all_buttons()
return # End the function here
# Switch player
current_player = "O" if current_player == "X" else "X"
# If it's now AI's turn, perform AI logic
if current_player == "O":
ai_turn()
AI turn logic
func ai_turn():
# AI Logic based on difficulty
if ai_difficulty == “Hard”:
hard_ai_turn()
elif ai_difficulty == “Medium”:
medium_ai_turn()
else: # Easy mode
easy_ai_turn()
AI turn for Hard mode
func hard_ai_turn():
# Block player if they are one move away from winning
for i in range(board.size()):
if board[i] == “”:
board[i] = “X” # Pretend to be the player
if check_for_win():
board[i] = “O” # Block the player
buttons[i].text = “O”
buttons[i].disabled = true
current_player = “X” # Switch back to player X
return
board[i] = “” # Reset the board slot
# Choose random available spot if no block is needed
choose_random_spot()
AI turn for Medium mode
func medium_ai_turn():
# Block player if they are one move away from winning
for i in range(board.size()):
if board[i] == “”:
board[i] = “X” # Pretend to be the player
if check_for_win():
board[i] = “O” # Block the player
buttons[i].text = “O”
buttons[i].disabled = true
current_player = “X” # Switch back to player X
return
board[i] = “” # Reset the board slot
# Choose random available spot
choose_random_spot()
AI turn for Easy mode (same as before)
func easy_ai_turn():
choose_random_spot()
Choose a random available spot for AI’s turn
func choose_random_spot():
var empty_indices =
for i in range(board.size()):
if board[i] == “”:
empty_indices.append(i)
if empty_indices.size() > 0:
var random_index = empty_indices[randi() % empty_indices.size()] # Get random index from empty_indices
board[random_index] = “O” # AI makes a move
buttons[random_index].text = “O” # Update button text to “O”
buttons[random_index].disabled = true # Disable the button after AI’s turn
# Check for win condition
if check_for_win():
show_winner_popup(current_player)
disable_all_buttons()
return # End the function here
# Switch back to player X
current_player = “X”
Show winner popup
func show_winner_popup(winner: String):
var popup = Popup.new() # Create a new Popup instance
popup.set_title(“Game Over”)
# Create a label to display the winner
var winner_label = Label.new()
winner_label.text = winner + " wins!" # Set the text to show the winner
popup.add_child(winner_label) # Add the label to the popup
# Add home button
var home_button = Button.new()
home_button.text = "Home"
home_button.connect("pressed", Callable(self, "_on_home_pressed").bind(popup)) # Bind the popup instance
popup.add_child(home_button) # Show the home button in the popup
# Add the popup to the current scene
get_tree().current_scene.add_child(popup) # Add the popup to the scene tree
popup.popup_centered() # Center the popup
# Disable input processing for the current scene
set_process_input(false) # Disable input until the popup is handled
Home button pressed
func _on_home_pressed(popup: Popup):
popup.hide() # Hide the popup before transitioning
# Wait a brief moment to ensure the popup is fully hidden (optional)
await get_tree().create_timer(0.1).timeout # Change from yield to await
get_tree().change_scene_to_file(“res://UI.tscn”) # Change to the home screen
Disables all buttons after the game ends
func disable_all_buttons():
for button in buttons:
button.disabled = true
Checks for win conditions
func check_for_win() → bool:
var win_conditions = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], # Rows
[0, 3, 6], [1, 4, 7], [2, 5, 8], # Columns
[0, 4, 8], [2, 4, 6] # Diagonals
]
for condition in win_conditions:
if board[condition[0]] == current_player and board[condition[1]] == current_player and board[condition[2]] == current_player:
return true
return false
Idk why the text is coming out like that lol
Please let me know if you need anymore code or anything else to help with this:
Thanks again!