class_name ChessGame extends Control const WHITE = "white" const BLACK = "black" 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 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 @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() func _unhandled_input(event: InputEvent) -> void: stateMachine.unhandledInput(event) func _process(delta: float) -> void: stateMachine.process(delta) func initializeGame() -> void: setupStyles() initializeBoard() setupUI() initializeDeckSystem() # func initializeBoard() -> void: # setupStyles() # if boardXSize < 0 || boardYSize < 0: # return # var numberX = 0 # var numberY = 0 # var isWhite = true # board = [] # for i in range(8): # var row = [] # for j in range(8): # row.append(null) # board.append(row) # while numberY != boardYSize: # boardContainer.size.y += tileYSize + 5 # boardContainer.size.x += tileXSize + 5 # while numberX != boardXSize: # var tile = Button.new() # tile.set_custom_minimum_size(Vector2(tileXSize, tileYSize)) # if isWhite: # tile.add_theme_stylebox_override("normal", lightStyle) # else: # tile.add_theme_stylebox_override("normal", darkStyle) # isWhite = !isWhite # tile.pressed.connect(func(): _onTilePressed(tile.name)) # tile.set_name(str(numberX) + "-" + str(numberY)) # boardContainer.add_child(tile) # numberX += 1 # isWhite = !isWhite # numberY += 1 # numberX = 0 # setupPieces() # updateTurnIndicator() func initializeBoard() -> void: board = [] for i in range(8): var row = [] for j in range(8): row.append(null) board.append(row) createBoard() setupPieces() 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) 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.pressed.connect(func(): handleTileSelection(tile.name)) tile.set_name(str(x) + "-" + str(y)) boardContainer.add_child(tile) func handleTileSelection(location: String) -> void: # Deselect current piece if selectedNode == location: resetHighlights() selectedNode = "" return var node = get_node("Flow/" + location) parseLocation(location) # First selection of a piece if selectedNode == "" && node.get_child_count() != 0 && node.get_child(0).Item_Color == Turn: selectedNode = location getMovableAreas() # Castling elif isCastlingMove(node, location): handleCastling(node) # En Passant elif isEnPassantMove(node, location): handleEnPassant(node) # Reselect piece elif isReselectMove(node): selectedNode = location getMovableAreas() # Capture piece elif isCaptureMove(node): handleCapture(node) # Regular move elif isRegularMove(node): handleRegularMove(node) func isCastlingMove(node: Node, location: String) -> bool: return selectedNode != "" && node.get_child_count() != 0 && node.get_child(0).Item_Color == Turn && node.get_child(0).name == "Rook" func isEnPassantMove(node: Node, location: String) -> bool: return selectedNode != "" && node.get_child_count() != 0 && node.get_child(0).Item_Color != Turn && \ node.get_child(0).name == "Pawn" && specialArea.size() != 0 && specialArea[0] == node.name && \ node.get_child(0).get("En_Passant") == true func isReselectMove(node: Node) -> bool: return selectedNode != "" && node.get_child_count() != 0 && node.get_child(0).Item_Color == Turn func isCaptureMove(node: Node) -> bool: return selectedNode != "" && node.get_child_count() != 0 && node.get_child(0).Item_Color != Turn func isRegularMove(node: Node) -> bool: return selectedNode != "" && node.get_child_count() == 0 func handleCastling(node: Node) -> void: print("handleCastling") for i in areas: if i == node.name: var king = get_node("Flow/" + selectedNode).get_child(0) var rook = node.get_child(0) king.reparent(get_node("Flow/" + specialArea[1])) rook.reparent(get_node("Flow/" + specialArea[0])) king.position = Vector2(25, 25) rook.position = Vector2(25, 25) currentlyMovingPiece = king resolveMoveEffects() func handleEnPassant(node: Node) -> void: print("handleEnPassant") for i in specialArea: if i == node.name: var pawn = get_node("Flow/" + selectedNode).get_child(0) node.get_child(0).free() pawn.reparent(get_node("Flow/" + specialArea[1])) pawn.position = Vector2(25, 25) currentlyMovingPiece = pawn resolveMoveEffects() func handleCapture(node: Node) -> void: print("handleCapture") for i in areas: if i == node.name: var piece = get_node("Flow/" + selectedNode).get_child(0) var capturedPiece = node.get_child(0) updatePoints(capturedPiece) if capturedPiece.name == "King": print("Game Over!") capturedPiece.free() piece.reparent(node) piece.position = Vector2(25, 25) piece.position = Vector2(25, 25) currentlyMovingPiece = piece resolveMoveEffects() func handleRegularMove(node: Node) -> void: print("handleRegularMove") for i in areas: if i == node.name: var piece = get_node("Flow/" + selectedNode).get_child(0) piece.reparent(node) piece.position = Vector2(25, 25) currentlyMovingPiece = piece resolveMoveEffects() func updatePoints(capturedPiece: Node) -> void: if Turn == 0: p1Points += capturedPiece.Points p1String.text = str(p1Points) else: p2Points += capturedPiece.Points p2String.text = str(p2Points) 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 _onTilePressed(tileName: String) -> void: boardContainer.emit_signal("send_location", tileName) 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(8): 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(8): 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 prepareHand() -> void: pass func drawCards() -> void: pass func updateEffectDurations() -> void: pass func applyTileEffects() -> void: pass func attachSelectedCards() -> void: pass func applyCardEffects() -> void: pass 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 getMovableAreas() -> void: resetHighlights() areas.clear() specialArea.clear() var piece = get_node("Flow/" + selectedNode).get_child(0) # print("Flow/" + selectedNode) var flowNodes = get_tree().get_nodes_in_group("Flow") # print("Flow nodes:", flowNodes) 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") 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 resolveMoveEffects() -> void: print("resolveMoveEffects") print("currentlyMovingPiece", currentlyMovingPiece) 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 selectedNode = "" Turn = 1 if Turn == 0 else 0 updateTurnIndicator() resetHighlights() deckManager.updateCardDurations() hasMoved = false currentlyMovingPiece = null func resetHighlights(): for button in boardContainer.get_children(): 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 false func isDraw() -> bool: return false func endGame(reason: String) -> void: pass func cleanupPhase() -> void: pass func isNull(location: String) -> bool: return get_node_or_null("Flow/" + location) == null