I'm trying to make a tic tac toe but whenever you play a move you have to fight for it for other players in a 2D platformer shooter (like duck game). But the tic tac toe isn't working, I followed a tutorial ( Everything works except that when you come back from the shooter, sometimes the player repeats, meaning that if I start with X then a friend next to me plays O, then I play X, then he plays O, but when I go to play X it actually puts another O for some reason. This is the code for the tic tac toe:
extends Control
# DATA
# Holds board data such as x, o, and unmarked
var board : Array
# State of player, X or O
var player : String
# State for a winner or not
var is_winner: bool = false
# State for game over or not
var is_gameover: bool = false
# State for draw/tie or not
var is_draw: bool = false
# LOAD IMAGE FILES
# Button unpressed
var unpressed = preload("res://assets/unpressed-tile.png")
# Button for Player X
var player_x = preload("res://assets/player-x-tile.png")
# Button for Player O
var player_o = preload("res://assets/player-o-tile.png")
# Initiates board/game data
func initiate_board() -> void:
board = [
"0", "0", "0",
"0", "0", "0",
"0", "0", "0"
]
$Board/Row0/Button0.texture_normal = unpressed
$Board/Row0/Button1.texture_normal = unpressed
$Board/Row0/Button2.texture_normal = unpressed
$Board/Row1/Button3.texture_normal = unpressed
$Board/Row1/Button4.texture_normal = unpressed
$Board/Row1/Button5.texture_normal = unpressed
$Board/Row2/Button6.texture_normal = unpressed
$Board/Row2/Button7.texture_normal = unpressed
$Board/Row2/Button8.texture_normal = unpressed
is_gameover = false
is_winner = false
is_draw = false
# Initiates a player
func initiate_player() -> void:
player = "o"
# Runs automatically when scene is loaded
func _ready() -> void:
$GameOverMessage.hide()
initiate_board()
initiate_player()
if Utils.b0 == true && Utils.pb0 == "o":
player = "o"
make_move(0)
update_board(0, 0)
player = "x"
elif Utils.b0 == true && Utils.pb0 == "x":
player = "x"
make_move(0)
update_board(0, 0)
player = "o"
if Utils.b1 == true && Utils.pb1 == "o":
player = "o"
make_move(1)
update_board(0, 1)
player = "x"
elif Utils.b1 == true && Utils.pb1 == "x":
player = "x"
make_move(1)
update_board(0,1)
player = "o"
if Utils.b2 == true && Utils.pb2 == "o":
player = "o"
make_move(2)
update_board(0,2)
player = "x"
elif Utils.b2 == true && Utils.pb2 == "x":
player = "x"
make_move(2)
update_board(0,2)
player = "o"
if Utils.b3 == true && Utils.pb3 == "o":
player = "o"
make_move(3)
update_board(1,3)
player = "x"
elif Utils.b3 == true && Utils.pb3 == "x":
player = "x"
make_move(3)
update_board(1,3)
player = "o"
if Utils.b4 == true && Utils.pb4 == "o":
player = "o"
make_move(4)
update_board(1,4)
player = "x"
elif Utils.b4 == true && Utils.pb4 == "x":
player = "x"
make_move(4)
update_board(1,4)
player = "o"
if Utils.b5 == true && Utils.pb5 == "o":
player = "o"
make_move(5)
update_board(1,5)
player = "x"
elif Utils.b5 == true && Utils.pb5 == "x":
player = "x"
make_move(5)
update_board(1,5)
player = "o"
if Utils.b6 == true && Utils.pb6 == "o":
player = "o"
make_move(6)
update_board(2,6)
player = "x"
elif Utils.b6 == true && Utils.pb6 == "x":
player = "x"
make_move(6)
update_board(2,6)
player = "o"
if Utils.b7 == true && Utils.pb7 == "o":
player = "o"
make_move(7)
update_board(2,7)
player = "x"
elif Utils.b7 == true && Utils.pb7 == "x":
player = "x"
make_move(7)
update_board(2,7)
player = "o"
if Utils.b8 == true && Utils.pb8 == "o":
player = "o"
make_move(8)
update_board(2,8)
player = "x"
elif Utils.b8 == true && Utils.pb8 == "x":
player = "x"
make_move(8)
update_board(2,8)
player = "o"
# Next player's turn
func update_player() -> void:
if player == "x":
player = "o"
else:
player = "x"
# Check rows for a match 3
func is_row_matched() -> bool:
var offset = 0
for row in range(3):
for index in range(0 + offset, 3 + offset):
if board[index] == player:
is_winner = true
else:
is_winner = false
break
if is_winner:
return true
offset += 3
return false
# Check columns for a match 3
func is_col_matched() -> bool:
var offset = 0
for col in range(3):
for index in range(0 + offset, 7 + offset, 3):
if board[index] == player:
is_winner = true
else:
is_winner = false
break
if is_winner:
return true
offset += 1
return false
# Check diagonals for a match 3
func is_diag_matched() -> bool:
for i in range(0, 9, 4):
if board[i] == player:
is_winner = true
else:
is_winner = false
break
if is_winner:
return true
for i in range(2, 7, 2):
if board[i] == player:
is_winner = true
else:
is_winner = false
break
if is_winner:
return true
return false
# Check if board is full
func is_board_full() -> bool:
if board.has("0"):
return false
return true
# Check for win/draw conditions
func check_gameover() -> void:
if is_row_matched() || is_col_matched() || is_diag_matched():
is_gameover = true
add_gameover_message()
elif is_board_full():
is_gameover = true
is_draw = true
add_gameover_message()
# Show a gameover message
func add_gameover_message() -> void:
if is_draw:
$GameOverMessage/Container/Label.text = "Game is a draw!"
else:
$GameOverMessage/Container/Label.text = "Player " + player + " wins!"
$GameOverMessage.show()
# Mark player's move
func make_move(index: int) -> void:
board[index] = player
check_gameover()
# Check if button/square is free or open
func is_square_free(index: int) -> bool:
if board[index] == "0":
return true
return false
# Update board with X or O button image
func update_board(row: int, index: int) -> void:
var path = "Board/Row" + str(row) + "/Button" + str(index)
if player == "x":
get_node(path).texture_normal = player_x
elif player == "o":
get_node(path).texture_normal = player_o
update_player()
func _on_button_0_button_up() -> void:
if is_square_free(0) && !is_gameover:
Utils.b0 = true
Utils.pb0 = player
make_move(0)
update_board(0, 0)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_1_button_up() -> void:
if is_square_free(1) && !is_gameover:
Utils.b1 = true
Utils.pb1 = player
make_move(1)
update_board(0, 1)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_2_button_up() -> void:
if is_square_free(2) && !is_gameover:
Utils.b2 = true
Utils.pb2 = player
make_move(2)
update_board(0, 2)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_3_button_up() -> void:
if is_square_free(3) && !is_gameover:
Utils.b3 = true
Utils.pb3 = player
make_move(3)
update_board(1, 3)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_4_button_up() -> void:
if is_square_free(4) && !is_gameover:
Utils.b4 = true
Utils.pb4 = player
make_move(4)
update_board(1, 4)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_5_button_up() -> void:
if is_square_free(5) && !is_gameover:
Utils.b5 = true
Utils.pb5 = player
make_move(5)
update_board(1, 5)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_6_button_up() -> void:
if is_square_free(6) && !is_gameover:
Utils.b6 = true
Utils.pb6 = player
make_move(6)
update_board(2, 6)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_7_button_up() -> void:
if is_square_free(7) && !is_gameover:
Utils.b7 = true
Utils.pb7 = player
make_move(7)
update_board(2, 7)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_8_button_up() -> void:
if is_square_free(8) && !is_gameover:
Utils.b8 = true
Utils.pb8 = player
make_move(8)
update_board(2, 8)
get_tree().change_scene_to_file("res://scenes/main.tscn")
func _on_button_button_up() -> void:
$GameOverMessage.hide()
initiate_board()
initiate_player()
var _b0 = false
var _b1 = false
var _b2 = false
var _b3 = false
var _b4 = false
var _b5 = false
var _b6 = false
var _b7 = false
var _b8 = false
The "Utils." variables are global variables.
Thanks in advance!