class_name ChessGame extends Control const PieceContainer = preload("res://Systems/PieceContainer.gd") const WHITE = "white" const BLACK = "black" signal tile_pressed(location: String) signal send_location(location: String) signal turn_changed var currentPlayer: String = WHITE var board: Array var currentHand: Array var selectedNode: String = "" var locationX: String = "" var locationY: String = "" var areas: PackedStringArray var specialArea: PackedStringArray var gamecheckMate: bool = false var gamedraw: bool = false var hasMoved: bool = false var currentlyMovingPiece = null var p1Points: int = 0 var p2Points: int = 0 var Turn: int = 0 @onready var turnIndicator: ColorRect = $TurnIndicator @onready var p1String: RichTextLabel = $Player1Points @onready var p2String: RichTextLabel = $Player2Points @onready var deckManager: DeckManager @onready var tileManager: TileManager @onready var cardDisplay: CardDisplay @onready var cardPreview: CardPreview @export var boardXSize = 8 @export var boardYSize = 8 @export var tileXSize: int = 50 @export var tileYSize: int = 50 @onready var boardContainer: FlowContainer = $Flow @onready var stateMachine: StateMachine = $StateMachine var lightStyle = null var darkStyle = null var highlightStyle = null func _ready() -> void: initializeGame() initializeTiles() stateMachine.transitionToNextState(Constants.WHITE_TURN) func initializeTiles() -> void: tileManager = TileManager.new($Flow, self) add_child(tileManager) await get_tree().process_frame tileManager.initialize(boardContainer) tileManager.place_random_game_tiles() func get_base_style(is_white: bool) -> StyleBoxFlat: return lightStyle if is_white else darkStyle func _unhandled_input(event: InputEvent) -> void: stateMachine.unhandledInput(event) func _process(delta: float) -> void: stateMachine.process(delta) func initializeGame() -> void: setupStyles() initializeBoard() setupUI() initializeDeckSystem() initializeCardPreview() func initializeCardPreview() -> void: cardPreview = CardPreview.new() add_child(cardPreview) func initializeBoard() -> void: board = [] for i in range(boardXSize): var row = [] for j in range(boardYSize): row.append(null) board.append(row) createBoard() setupPieces() if !boardContainer.has_user_signal("tile_pressed"): boardContainer.add_user_signal("tile_pressed") if !boardContainer.has_user_signal("send_location"): boardContainer.add_user_signal("send_location") func setupUI() -> void: p1String.text = "0" p2String.text = "0" updateTurnIndicator() func initializeDeckSystem() -> void: deckManager = DeckManager.new() cardDisplay = CardDisplay.new() add_child(deckManager) add_child(cardDisplay) if !deckManager.has_user_signal("card_pressed"): deckManager.add_user_signal("card_pressed") if !deckManager.has_user_signal("hand_updated"): deckManager.add_user_signal("hand_updated") cardDisplay.update_hand(deckManager.hand) deckManager.connect("hand_updated", func(hand): cardDisplay.update_hand(hand)) func createBoard() -> void: boardContainer.add_to_group("Flow") var numberX = 0 var numberY = 0 var isWhite = true while numberY != boardYSize: boardContainer.size.y += tileYSize + 5 boardContainer.size.x += tileXSize + 5 while numberX != boardXSize: createTile(numberX, numberY, isWhite) isWhite = !isWhite numberX += 1 isWhite = !isWhite numberY += 1 numberX = 0 func createTile(x: int, y: int, isWhite: bool) -> void: # print("CreateTile x ", x, " y ", y); var tile = PieceContainer.new() tile.set_custom_minimum_size(Vector2(tileXSize, tileYSize)) tile.add_theme_stylebox_override("normal", lightStyle if isWhite else darkStyle) tile.set_name(str(x) + "-" + str(y)) # tile.pressed.connect(func(): handleTileSelection(tile.name)) tile.pressed.connect(func(): # tile_pressed.emit(tile.name) boardContainer.emit_signal("tile_pressed", tile.name) ) boardContainer.add_child(tile) func clearSelection() : resetHighlights() selectedNode = "" cardPreview.hide_preview() return func updatePoints(capturedPiece: Node) -> void: if Turn == 0: p1Points += capturedPiece.Points p1String.text = str(p1Points) else: p2Points += capturedPiece.Points p2String.text = str(p2Points) if capturedPiece.name == "King": print("Game Over!") gamecheckMate = true func parseLocation(location: String) -> void: var number = 0 locationX = "" while location.substr(number, 1) != "-": locationX += location.substr(number, 1) number += 1 locationY = location.substr(number + 1) func setupStyles() -> void: lightStyle = StyleBoxFlat.new() lightStyle.bg_color = Color(0.8, 0.8, 0.8, 1) darkStyle = StyleBoxFlat.new() darkStyle.bg_color = Color(0.2, 0.2, 0.2, 1) highlightStyle = StyleBoxFlat.new() highlightStyle.bg_color = Color(0, 0.3, 0, 1) func updateTurnIndicator(): if Turn == 0: # White's turn turnIndicator.color = Color(1, 1, 1, 1) # White else: # Black's turn turnIndicator.color = Color(0, 0, 0, 1) # Black func setupPieces() -> void: # White pieces placePiece("0-0", "Rook", 1) placePiece("1-0", "Knight", 1) placePiece("2-0", "Bishop", 1) placePiece("3-0", "Queen", 1) placePiece("4-0", "King", 1) placePiece("5-0", "Bishop", 1) placePiece("6-0", "Knight", 1) placePiece("7-0", "Rook", 1) for x in range(boardXSize): placePiece(str(x) + "-1", "Pawn", 1) # Black pieces placePiece("0-7", "Rook", 0) placePiece("1-7", "Knight", 0) placePiece("2-7", "Bishop", 0) placePiece("3-7", "Queen", 0) placePiece("4-7", "King", 0) placePiece("5-7", "Bishop", 0) placePiece("6-7", "Knight", 0) placePiece("7-7", "Rook", 0) for x in range(boardXSize): placePiece(str(x) + "-6", "Pawn", 0) func placePiece(position: String, pieceName: String, color: int) -> void: var piece = summonPiece(pieceName, color) # boardContainer.get_node(position).add_child(piece) var container = boardContainer.get_node(position) container.set_piece(piece) var coords = position.split("-") board[int(coords[1])][int(coords[0])] = piece func summonPiece(pieceName: String, color: int) -> Node: var piece match pieceName: "Pawn": piece = Pawn.new() piece.name = "Pawn" "King": piece = King.new() piece.name = "King" "Queen": piece = Queen.new() piece.name = "Queen" "Knight": piece = Knight.new() piece.name = "Knight" "Rook": piece = Rook.new() piece.name = "Rook" "Bishop": piece = Bishop.new() piece.name = "Bishop" piece.Item_Color = color piece.position = Vector2(tileXSize / 2, tileYSize / 2) return piece func clearBoard() -> void: for child in boardContainer.get_children(): if child is PieceContainer: child.remove_piece() # func prepareHand() -> void: # if deckManager.hand.size() < 5: # deckManager.drawCard() # pass func updateEffectDurations() -> void: deckManager.updateCardDurations() tileManager.update_tile_durations() func applyTileEffects() -> void: tileManager.apply_tile_effects() func applyCardEffects() -> void: pass func evaluatePosition() -> Dictionary: var status = { "checkmate": isCheckmate(), "draw": isDraw(), } return status func isValidMove(location: String) -> bool: var node = get_node("Flow/" + location) as PieceContainer var piece = node.get_piece() if piece == null || piece.Item_Color != Turn: for area in areas: if area == node.name: return true return false func resetBoard() -> void: clearSelection() clearBoard() setupPieces() Turn = 0 currentPlayer = WHITE p1Points = 0 p1String.text = str(p1Points) p2Points = 0 p2String.text = str(p2Points) gamecheckMate = false; gamedraw = false; deckManager.initializeStartingDeck() areas.clear() specialArea.clear() updateTurnIndicator() func getMovableAreas() -> void: # print("HIGHLIGHTING getMovableAreas 1") resetHighlights() areas.clear() specialArea.clear() var container = get_node("Flow/" + selectedNode) as PieceContainer var piece = container.get_piece() var piece_id = piece.get_instance_id() # print("HIGHLIGHTING getMovableAreas 2") if deckManager.attached_cards.has(piece_id): var card = deckManager.attached_cards[piece_id] cardPreview.show_card_preview(card) if stateMachine.state.name == Constants.MOVEMENT: var movement_state = stateMachine.state if piece_id in movement_state.moves_remaining: var moves_left = movement_state.moves_remaining[piece_id] - 1 cardPreview.update_moves_remaining(moves_left) else: cardPreview.hide_preview() # print("HIGHLIGHTING getMovableAreas 3") var moves = piece.getValidMoves(boardContainer, selectedNode) areas = moves.regular_moves specialArea = moves.special_moves # print("HIGHLIGHTING getMovableAreas 4") highlightValidMoves() func highlightValidMoves() -> void: for move in areas: var button = boardContainer.get_node(move) # If there's an active tile effect, combine with its current style instead if tileManager && tileManager.get_tile(move): var current_style = button.get_theme_stylebox("normal") var highlightedStyle = StyleBoxFlat.new() highlightedStyle.bg_color = current_style.bg_color + highlightStyle.bg_color button.add_theme_stylebox_override("normal", highlightedStyle) else: # Default chess pattern highlighting var isWhiteSquare = (int(move.split("-")[0]) + int(move.split("-")[1])) % 2 == 0 var baseStyle = lightStyle if isWhiteSquare else darkStyle var combinedStyle = StyleBoxFlat.new() combinedStyle.bg_color = baseStyle.bg_color + highlightStyle.bg_color button.add_theme_stylebox_override("normal", combinedStyle) func executeMove(targetLocation: String) -> void: print("executeMove ", targetLocation) var targetContainer = get_node("Flow/" + targetLocation) as PieceContainer var sourceContainer = get_node("Flow/" + selectedNode) as PieceContainer var piece = sourceContainer.get_piece() var old_location = selectedNode # Handle capture if there's a piece in target location if targetContainer.has_piece(): var capturedPiece = targetContainer.get_piece() if Turn == 0: p1Points += capturedPiece.Points p1String.text = str(p1Points) else: p2Points += capturedPiece.Points p2String.text = str(p2Points) targetContainer.remove_piece() # This handles freeing the captured piece # Move piece to new location sourceContainer.remove_piece(true) targetContainer.set_piece(piece) hasMoved = true currentlyMovingPiece = piece resetHighlights() func togglePieceChessEffect() -> void: var piece = currentlyMovingPiece if piece.name == "Pawn": if piece.Double_Start: piece.En_Passant = true piece.Double_Start = false elif piece.name == "King": piece.Castling = false elif piece.name == "Rook": piece.Castling = false func resolveMoveEffects() -> void: print("resolveMoveEffects", currentlyMovingPiece) togglePieceChessEffect() selectedNode = "" Turn = 1 if Turn == 0 else 0 updateTurnIndicator() resetHighlights() hasMoved = false currentlyMovingPiece = null emit_signal("turn_changed") func isPlayerTurn() -> bool: return currentPlayer == WHITE func resetHighlights(): for button in boardContainer.get_children(): if !button.name.contains("-"): continue # Skip if this tile has an active effect if tileManager && tileManager.get_tile(button.name): continue var coord = button.name.split("-") var isWhiteSquare = (int(coord[0]) + int(coord[1])) % 2 == 0 if isWhiteSquare: button.add_theme_stylebox_override("normal", lightStyle) else: button.add_theme_stylebox_override("normal", darkStyle) func isCheckmate() -> bool: return gamecheckMate func isDraw() -> bool: return gamedraw func endGame(reason: String) -> void: pass func cleanupPhase() -> void: pass func isNull(location: String) -> bool: return get_node_or_null("Flow/" + location) == null