class_name ChessGame extends Control 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 activeEffects: 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 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() stateMachine.transitionToNextState(Constants.WHITE_TURN) 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 = Button.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 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.get_child_count() > 0: child.get_child(0).queue_free() # func prepareHand() -> void: # if deckManager.hand.size() < 5: # deckManager.drawCard() # pass func updateEffectDurations() -> void: for effect in activeEffects: effect.duration -= 1 if effect.duration <= 0: activeEffects.erase(effect) func applyTileEffects() -> void: for piece in get_tree().get_nodes_in_group("Pieces"): var tile = piece.get_parent() if tile.has_effect(): tile.apply_effect(piece) 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) if node.get_child_count() == 0 || node.get_child(0).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: resetHighlights() areas.clear() specialArea.clear() var piece = get_node("Flow/" + selectedNode).get_child(0) var piece_id = piece.get_instance_id() 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() var moves = piece.getValidMoves(boardContainer, selectedNode) areas = moves.regular_moves specialArea = moves.special_moves highlightValidMoves() func highlightValidMoves() -> void: for move in areas: var button = boardContainer.get_node(move) 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 targetNode = get_node("Flow/" + targetLocation) var piece = get_node("Flow/" + selectedNode).get_child(0) # print("piece", piece) if targetNode.get_child_count() != 0: var capturedPiece = targetNode.get_child(0) if Turn == 0: p1Points += capturedPiece.Points p1String.text = str(p1Points) else: p2Points += capturedPiece.Points p2String.text = str(p2Points) capturedPiece.free() piece.reparent(targetNode) piece.position = Vector2(25, 25) # print("piece2", 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 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