From c09ddcb1a29e8ca6978ee6f7695266cd93debec6 Mon Sep 17 00:00:00 2001 From: 2ManyProjects Date: Sat, 8 Mar 2025 02:59:57 -0600 Subject: [PATCH] fixed crash on board size change and turn interaction with explosive cards --- Systems/Cards/Explosiveboots.gd | 2 + Systems/DeckManager.gd | 12 +- Systems/Game/ChessGame.gd | 120 +++++-- Systems/Game/Map/MapGenerator.gd | 79 ++++- Systems/Game/Menu/MenuContainer.gd | 5 + Systems/Game/WinConditionManager.gd | 297 ++++++++++++++++++ Systems/Game/WinConditionManager.gd.uid | 1 + .../StateMachine/GameStates/AttachCards.gd | 2 +- .../StateMachine/GameStates/CleanupPhase.gd | 2 +- Systems/StateMachine/GameStates/Movement.gd | 2 +- .../StateMachine/GameStates/PostMovePhase.gd | 1 - Systems/StateMachine/StateMachine.gd | 2 + Utils/Utils.gd | 15 +- 13 files changed, 498 insertions(+), 42 deletions(-) create mode 100644 Systems/Game/WinConditionManager.gd create mode 100644 Systems/Game/WinConditionManager.gd.uid diff --git a/Systems/Cards/Explosiveboots.gd b/Systems/Cards/Explosiveboots.gd index a32b684..1af3718 100644 --- a/Systems/Cards/Explosiveboots.gd +++ b/Systems/Cards/Explosiveboots.gd @@ -17,6 +17,7 @@ func reset(): valid = false func apply_effect(target_piece = null, board_flow = null, game_state = null): + print("EXPLOSIVE apply_effect", ) attached_piece = target_piece stored_board_flow = board_flow stored_game_state = game_state @@ -26,6 +27,7 @@ func apply_effect(target_piece = null, board_flow = null, game_state = null): setup_persistent_effect(game_state) # dont apply on card attachment if !valid: + print("EXPLOSIVE apply_effect INVALID", ) return true var piece_pos = target_piece.get_parent().name.split("-") var piece_x = int(piece_pos[0]) diff --git a/Systems/DeckManager.gd b/Systems/DeckManager.gd index 410d7f5..fa919c3 100644 --- a/Systems/DeckManager.gd +++ b/Systems/DeckManager.gd @@ -25,14 +25,14 @@ func _init(): func initializeStartingDeck(): deck.clear(); # for i in range(2): - # deck.append(DoubleTimeCard.new()) - deck.append(HopscotchCard.new()) - deck.append(FieryCapeCard.new()) - deck.append(FieryTrailCard.new()) + # deck.append(DoubleTimeCard.new()) + # deck.append(HopscotchCard.new()) + # deck.append(FieryCapeCard.new()) + # deck.append(FieryTrailCard.new()) deck.append(ExplosiveBootsCard.new()) deck.append(DoubleTimeCard.new()) - deck.append(DrunkDrivingCard.new()) - deck.append(SupernovaCard.new()) + # deck.append(DrunkDrivingCard.new()) + # deck.append(SupernovaCard.new()) func initializeStartingBank(): # sample diff --git a/Systems/Game/ChessGame.gd b/Systems/Game/ChessGame.gd index 29bbe5f..c5d1077 100644 --- a/Systems/Game/ChessGame.gd +++ b/Systems/Game/ChessGame.gd @@ -1,7 +1,6 @@ class_name ChessGame extends Control # Constants -const PieceContainer = preload("res://Systems/PieceContainer.gd") const WHITE = "white" const BLACK = "black" const StockfishController = preload("res://Systems/FairyStockfish/StockfishClient.gd") @@ -60,6 +59,10 @@ var currentNode = null; @onready var menuContainer = get_node_or_null("/root/Board/MenuContainer") @onready var mapContainer = get_node_or_null("/root/Board/MapScreen") +var winConditionManager: WinConditionManager +var currentWinCondition = Utils.WinConditionType.CAPTURE_UNIT +var currentLossCondition = Utils.LossConditionType.UNIT_LOST + # Export parameters @export var boardXSize = 12 @@ -109,16 +112,20 @@ func _on_new_game_requested(options = {}): cpuElo = options.metadata.elo if cameraController: cameraController.reset_view() + if options and "metadata" in options: + if winConditionManager: + winConditionManager.load_condition_from_metadata(options.metadata) + currentNode = options print("ChessGame FEN ", currentFen) print("ChessGame DIMENSIONS ", get_board_dimensions(currentFen)) if is_initialized: resetBoard() initializeDeckSystem() + initializeBoard() if cardDisplay: cardDisplay.visible = true if stateMachine: - stateMachine.start() stateMachine.transitionToNextState(Constants.WHITE_TURN) else: initialize_game_system() @@ -126,6 +133,7 @@ func _on_new_game_requested(options = {}): stockfishController.start_board(cpuElo, get_board_dimensions(currentFen)) else: stockfishController.start_board(cpuElo, "8x8") + resetHighlights() func initialize_game_system(): print("Initializing game system") # Set up basic styles first @@ -140,6 +148,11 @@ func initialize_game_system(): add_child(stockfishController) stockfishController.connect_to_engine(stockfishPath, self) + winConditionManager = WinConditionManager.new(self) + add_child(winConditionManager) + winConditionManager.connect("win_condition_met", Callable(self, "_on_win_condition_met")) + winConditionManager.connect("loss_condition_met", Callable(self, "_on_loss_condition_met")) + # Start the state machine if stateMachine: stateMachine.start() @@ -217,9 +230,10 @@ func initializeDeckSystem() -> void: deckManager.shuffleDeck() deckManager.drawStartingHand() # Initialize the deck manager and card display - cardDisplay = CardDisplay.new() - add_child(deckManager) - add_child(cardDisplay) + if cardDisplay == null: + cardDisplay = CardDisplay.new() + add_child(cardDisplay) + add_child(deckManager) # Set up signals for card interaction if !deckManager.has_user_signal("card_pressed"): @@ -301,7 +315,17 @@ func get_base_style(is_white: bool) -> StyleBoxFlat: # =========================================================================== func createBoard() -> void: - boardContainer.add_to_group("Flow") + + for child in boardContainer.get_children(): + boardContainer.remove_child(child) + child.queue_free() + + # Reset container size + boardContainer.size = Vector2.ZERO + + # Add to group if not already in it + if not boardContainer.is_in_group("Flow"): + boardContainer.add_to_group("Flow") var numberX = 0 var numberY = 0 var isWhite = true @@ -461,7 +485,6 @@ func _unhandled_input(event: InputEvent) -> void: func resetBoard() -> void: clearSelection() clearBoard() - setupPiecesFromFEN() Turn = 0 currentPlayer = WHITE p1Points = 0 @@ -558,20 +581,48 @@ func executeMove(targetLocation: String) -> void: hasMoved = true currentlyMovingPiece = piece resetHighlights() + if winConditionManager: + winConditionManager.on_piece_moved(piece, old_location, targetLocation) + + +# Additional helper function to check if a specific tile has been reached +func is_tile_reached(location: String, piece_name: String = "") -> bool: + var container = get_node("Flow/" + location) as PieceContainer + if container and container.has_piece(): + var piece = container.get_piece() + if piece_name == "" or piece.name == piece_name: + return piece.Item_Color == 0 # Player's piece + return false + + +# func resolveMoveEffects() -> void: +# # Resolve effects after a move is made +# print("resolveMoveEffects", currentlyMovingPiece) +# togglePieceChessEffect() + +# selectedNode = "" +# Turn = 1 if Turn == 0 else 0 +# updateTurnIndicator() +# resetHighlights() +# hasMoved = false +# currentlyMovingPiece = null +# emit_signal("turn_changed") func resolveMoveEffects() -> void: # Resolve effects after a move is made print("resolveMoveEffects", currentlyMovingPiece) togglePieceChessEffect() - selectedNode = "" - Turn = 1 if Turn == 0 else 0 - updateTurnIndicator() resetHighlights() hasMoved = false currentlyMovingPiece = null emit_signal("turn_changed") + Turn = 1 if Turn == 0 else 0 + updateTurnIndicator() + +func endTurn() -> void: + print("turn_changed") func togglePieceChessEffect() -> void: @@ -687,27 +738,56 @@ func isNull(location: String) -> bool: func updatePointsAndCapture(capturedPiece: Pawn, animate: bool = true) -> void: # Update points and handle piece capture - if Turn == 0: - + print(Turn, " updatePointsAndCapture ", capturedPiece.Item_Color) + if animate: + animatePieceCapture(capturedPiece) + if Turn == 0: # Player's turn gold += capturedPiece.Points; p1Points += capturedPiece.Points p1String.text = str(p1Points) - else: + + # Player captured an enemy piece + print("winConditionManager and capturedPiece.Item_Color == 1") + if winConditionManager and capturedPiece.Item_Color == 1: # Enemy piece (black) + print("Player captured an enemy piece ") + winConditionManager.on_piece_captured(capturedPiece) + else: # Enemy's turn p2Points += capturedPiece.Points p2String.text = str(p2Points) - if animate: - animatePieceCapture(capturedPiece) + + # Enemy captured a player piece + print("winConditionManager and capturedPiece.Item_Color == 0") + if winConditionManager and capturedPiece.Item_Color == 0: # Player piece (white) + print("ENemy captured an player piece ") + winConditionManager.on_piece_lost(capturedPiece) if capturedPiece.name == "King": print("Game Over!") - emit_signal("node_completed", { - "node": currentNode, - "completed": true, - "success": true - }) gamecheckMate = true + + +func _on_win_condition_met(condition_data): + print("Win condition met: ", condition_data) + emit_signal("node_completed", { + "node": currentNode, + "completed": true, + "success": true, + "condition": condition_data + }) + # endRound() + +func _on_loss_condition_met(condition_data): + print("Loss condition met: ", condition_data) + emit_signal("node_completed", { + "node": currentNode, + "completed": true, + "success": false, + "condition": condition_data + }) + # endRound() + func animatePieceCapture(capturedPiece: Pawn) -> void: # Animate the capture of a piece var container = capturedPiece.get_parent() as PieceContainer diff --git a/Systems/Game/Map/MapGenerator.gd b/Systems/Game/Map/MapGenerator.gd index 4ca53f6..69d53e3 100644 --- a/Systems/Game/Map/MapGenerator.gd +++ b/Systems/Game/Map/MapGenerator.gd @@ -299,7 +299,7 @@ func generate_boss_data(node): "is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false, "fen": fen + fen_ending, "game_type": "chess", - "win_condition": Utils.WinCondition.King, + "win_condition": Utils.WinConditionType.CAPTURE_UNIT, "reward": { "gold": 50 * node.level, "cards": [], @@ -309,8 +309,7 @@ func generate_boss_data(node): "elo": node.elo, } - - + func generate_shop_data(node): var num_shop_cards = min(randi_range(5, 7), Utils.CardTypes.size()) return { @@ -346,7 +345,7 @@ func generate_event_data(node): "is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false, "fen": "8/4p3/8/8/8/8 w KQkq - 0 1", "game_type": "maze", - "win_condition": Utils.WinCondition.Tile, + "win_condition": Utils.WinConditionType.TILE_REACHED, "elo": node.elo, } # "rnbqkbnr1/pppppppp1/9/9/9/9/9/PPPPPPPP1/RNBQKBNR1 w KQkq - 0 1" @@ -384,17 +383,83 @@ func generate_chess_data(node): fen += pawn_string.to_upper() + "/" + unit_string.to_upper() var fen_ending = " w KQkq - 0 1" # print("generate_chess_data ", fen + fen_ending) - return { + var win_condition = Utils.WinConditionType.CAPTURE_UNIT # Default + var loss_condition = Utils.LossConditionType.UNIT_LOST # Default + + # Randomly select a win condition with increasing variety at higher levels + var rng_val = _rng.randf() + var conditions_pool = [Utils.WinConditionType.CAPTURE_UNIT] # Default pool + + # # Add more varied win conditions at higher levels + # if node.level >= 3: + # conditions_pool.append(Utils.WinConditionType.BOARD_CLEARED) + # if node.level >= 5: + # conditions_pool.append(Utils.WinConditionType.TILE_REACHED) + # if node.level >= 7: + # conditions_pool.append(Utils.WinConditionType.TURN_NUMBER) + + # # For certain special nodes, always use specific conditions + # if node.type == Utils.RoomType.EVENT: + # win_condition = Utils.WinConditionType.TILE_REACHED + # elif node.type == Utils.RoomType.BOSS and node.level > 5: + # # Bosses at higher levels have more varied win conditions + # win_condition = conditions_pool[_rng.randi() % conditions_pool.size()] + # else: + # # Regular nodes have weighted randomness + # if rng_val < 0.7: # 70% chance of default capture king + # win_condition = Utils.WinConditionType.CAPTURE_UNIT + # else: + # # Pick randomly from the conditions pool + # win_condition = conditions_pool[_rng.randi() % conditions_pool.size()] + + # Create additional metadata for specific win conditions + var additional_metadata = {} + + # match win_condition: + # Utils.WinConditionType.TILE_REACHED: + # # Generate target tiles for the Tile win condition + # var target_tiles = [] + # var target_count = 1 # Default to 1 target tile + + # # Determine target unit (default is any piece) + # var target_unit = "" + # if _rng.randf() < 0.5: # 50% chance of specific piece + # var pieces = ["Pawn", "Knight", "Bishop", "Rook", "Queen"] + # target_unit = pieces[_rng.randi() % pieces.size()] + + # # Create target tiles at the enemy's back rank + # var target_x = _rng.randi() % unit_string.length() + # target_tiles.append(str(target_x) + "-0") # Top row + + # additional_metadata["target_tiles"] = target_tiles + # additional_metadata["target_unit"] = target_unit + + # Utils.WinConditionType.TURN_NUMBER: + # # Set a target turn number + # additional_metadata["target_turn"] = (node.level * 2) + _rng.randi_range(5, 10) + + # # Also add a turn limit for loss condition + # loss_condition = Utils.LossConditionType.TURN_NUMBER + # additional_metadata["turn_limit"] = additional_metadata["target_turn"] + _rng.randi_range(5, 15) + + # Build the result metadata + var result = { "is_escape": node.metadata.is_escape if node.metadata.has("is_escape") else false, "fen": fen + fen_ending, "game_type": "chess", - "win_condition": Utils.WinCondition.King, + "win_condition": win_condition, + "loss_condition": loss_condition, "elo": node.elo, "reward": { "gold": 50 * node.level } } - + + # Merge additional metadata + for key in additional_metadata: + result[key] = additional_metadata[key] + + return result func map_to_array_index(current_value, min_value, max_value, min_index, max_index): # Ensure the current value is within bounds diff --git a/Systems/Game/Menu/MenuContainer.gd b/Systems/Game/Menu/MenuContainer.gd index e64822a..32a55a2 100644 --- a/Systems/Game/Menu/MenuContainer.gd +++ b/Systems/Game/Menu/MenuContainer.gd @@ -4,6 +4,7 @@ class_name MenuContainer const VERSION_FILE_PATH = "res://Game.json" # Signal to notify parent when a new game is requested # signal new_game_requested +signal reward_closed signal new_game_requested(options) signal shop_open_requested(options) signal reward_open_requested(options) @@ -28,6 +29,10 @@ signal card_purchased(card, price) # back up if game isn't loaded yet? var player_gold = 10 var back_to_map = false +var winConditionManager: WinConditionManager +var currentWinCondition = Utils.WinConditionType.CAPTURE_UNIT +var currentLossCondition = Utils.LossConditionType.UNIT_LOST + func _ready(): # Connect menu option signals diff --git a/Systems/Game/WinConditionManager.gd b/Systems/Game/WinConditionManager.gd new file mode 100644 index 0000000..7395a2e --- /dev/null +++ b/Systems/Game/WinConditionManager.gd @@ -0,0 +1,297 @@ +extends Node +class_name WinConditionManager + +# Signals +signal win_condition_met(condition_data) +signal loss_condition_met(condition_data) +signal condition_progress_updated(progress_data) + +# References +var chess_game: ChessGame +var tile_manager: TileManager + +# Condition configuration +var win_condition: Utils.WinConditionType = Utils.WinConditionType.CAPTURE_UNIT +var loss_condition: Utils.LossConditionType = Utils.LossConditionType.UNIT_LOST +var win_condition_data: Dictionary = {} +var loss_condition_data: Dictionary = {} + +# Progress tracking +var captured_pieces = [] +var turn_count = 0 +var target_tiles = [] +var condition_progress = {} + +func _init(game: ChessGame): + chess_game = game + if chess_game: + tile_manager = chess_game.tileManager + # Connect to relevant signals + chess_game.connect("turn_changed", Callable(self, "_on_turn_changed")) + chess_game.connect("game_initialized", Callable(self, "_on_game_initialized")) + +func _on_game_initialized(): + reset_conditions() + +func reset_conditions(): + captured_pieces.clear() + turn_count = 0 + target_tiles.clear() + condition_progress.clear() + + # Setup initial progress tracking + match win_condition: + Utils.WinConditionType.BOARD_CLEARED: + condition_progress["total_enemy_pieces"] = count_enemy_pieces() + condition_progress["remaining_enemy_pieces"] = condition_progress["total_enemy_pieces"] + Utils.WinConditionType.TILE_REACHED: + if "target_tiles" in win_condition_data: + target_tiles = win_condition_data["target_tiles"] + highlight_target_tiles() + condition_progress["tiles_reached"] = [] + Utils.WinConditionType.TURN_NUMBER: + if "target_turn" in win_condition_data: + condition_progress["target_turn"] = win_condition_data["target_turn"] + condition_progress["current_turn"] = 0 + +func highlight_target_tiles(): + # Highlight target tiles on the board with a special visual style + for tile_loc in target_tiles: + if tile_manager: + # Create a goal tile if needed + var container = chess_game.get_node("Flow/" + tile_loc) as PieceContainer + if container: + # Create a visual indicator - use a styled container + var style = StyleBoxFlat.new() + style.bg_color = Color(0.2, 0.8, 0.2, 0.4) # Green translucent + style.border_width_all = 2 + style.border_color = Color(0.3, 1.0, 0.3, 0.8) + + # Apply the style while respecting chess pattern + var coord = tile_loc.split("-") + var isWhiteSquare = (int(coord[0]) + int(coord[1])) % 2 == 0 + var baseStyle = chess_game.lightStyle if isWhiteSquare else chess_game.darkStyle + var combinedStyle = StyleBoxFlat.new() + combinedStyle.bg_color = baseStyle.bg_color + style.bg_color + combinedStyle.border_width_all = style.border_width_all + combinedStyle.border_color = style.border_color + + container.add_theme_stylebox_override("normal", combinedStyle) + +func set_win_condition(type: Utils.WinConditionType, data: Dictionary = {}): + win_condition = type + win_condition_data = data + reset_conditions() + +func set_loss_condition(type: Utils.LossConditionType, data: Dictionary = {}): + loss_condition = type + loss_condition_data = data + reset_conditions() + +func _on_turn_changed(): + turn_count += 1 + + # Update progress for turn-based conditions + if win_condition == Utils.WinConditionType.TURN_NUMBER: + condition_progress["current_turn"] = turn_count + emit_signal("condition_progress_updated", condition_progress) + + if "target_turn" in win_condition_data and turn_count >= win_condition_data["target_turn"]: + emit_signal("win_condition_met", { + "type": Utils.WinConditionType.TURN_NUMBER, + "message": "Turn limit reached!" + }) + + if loss_condition == Utils.LossConditionType.TURN_NUMBER: + if "turn_limit" in loss_condition_data and turn_count >= loss_condition_data["turn_limit"]: + emit_signal("loss_condition_met", { + "type": Utils.LossConditionType.TURN_NUMBER, + "message": "Turn limit exceeded!" + }) + + # Check all conditions after turn change + check_conditions() + +func on_piece_captured(piece): + # First verify this is an enemy piece (with opposite color to current player) + var is_enemy_piece = piece.Item_Color == (1 if chess_game.Turn == 0 else 0) + print("on_piece_captured ISEnemy ", is_enemy_piece) + if is_enemy_piece: + captured_pieces.append(piece) + + # Update progress for board-cleared condition + if win_condition == Utils.WinConditionType.BOARD_CLEARED: + condition_progress["remaining_enemy_pieces"] -= 1 + emit_signal("condition_progress_updated", condition_progress) + + if condition_progress["remaining_enemy_pieces"] <= 0: + emit_signal("win_condition_met", { + "type": Utils.WinConditionType.BOARD_CLEARED, + "message": "Board cleared of enemy pieces!" + }) + + # Check for specific unit capture (default: King) + if win_condition == Utils.WinConditionType.CAPTURE_UNIT: + var target_unit = win_condition_data.get("unit", "King") + if piece.name == target_unit: + emit_signal("win_condition_met", { + "type": Utils.WinConditionType.CAPTURE_UNIT, + "message": "Enemy " + target_unit + " captured!" + }) + + # Check all conditions after capture + check_conditions() + +func on_piece_lost(piece): + # First verify this is a player piece (same color as current player) + var is_player_piece = piece.Item_Color == (0 if chess_game.Turn == 0 else 1) + print("on_piece_lost isPlayer ", is_player_piece) + + if is_player_piece: + # Check for unit loss (default: King) + if loss_condition == Utils.LossConditionType.UNIT_LOST: + var target_unit = loss_condition_data.get("unit", "King") + if piece.name == target_unit: + emit_signal("loss_condition_met", { + "type": Utils.LossConditionType.UNIT_LOST, + "message": "Your " + target_unit + " was captured!" + }) + + # Check all conditions after loss + check_conditions() + +func on_piece_moved(piece, from_location, to_location): + # Check for tile reached condition + if win_condition == Utils.WinConditionType.TILE_REACHED: + # Verify this is a player's piece (white if Turn==0, black if Turn==1) + var is_player_piece = piece.Item_Color == (0 if chess_game.Turn == 0 else 1) + + if is_player_piece and target_tiles.has(to_location): + # If specific unit is required + if "unit" in win_condition_data and win_condition_data["unit"] != "": + if piece.name == win_condition_data["unit"]: + if not condition_progress.has("tiles_reached"): + condition_progress["tiles_reached"] = [] + + # Avoid duplicates + if not condition_progress["tiles_reached"].has(to_location): + condition_progress["tiles_reached"].append(to_location) + emit_signal("condition_progress_updated", condition_progress) + + if condition_progress["tiles_reached"].size() >= target_tiles.size(): + emit_signal("win_condition_met", { + "type": Utils.WinConditionType.TILE_REACHED, + "message": "Target tile reached by " + piece.name + "!" + }) + else: + # Any player unit can reach the tile + if not condition_progress.has("tiles_reached"): + condition_progress["tiles_reached"] = [] + + # Avoid duplicates + if not condition_progress["tiles_reached"].has(to_location): + condition_progress["tiles_reached"].append(to_location) + emit_signal("condition_progress_updated", condition_progress) + + if condition_progress["tiles_reached"].size() >= target_tiles.size(): + emit_signal("win_condition_met", { + "type": Utils.WinConditionType.TILE_REACHED, + "message": "Target tile reached!" + }) + + # Check all conditions after move + check_conditions() + +func check_conditions(): + # This allows for custom condition checking beyond the standard events + + # Check board cleared condition + if win_condition == Utils.WinConditionType.BOARD_CLEARED: + var remaining = count_enemy_pieces() + if remaining <= 0: + emit_signal("win_condition_met", { + "type": Utils.WinConditionType.BOARD_CLEARED, + "message": "Board cleared of enemy pieces!" + }) + + # Update the UI with current progress + emit_signal("condition_progress_updated", condition_progress) + +func count_enemy_pieces() -> int: + var count = 0 + + # Determine enemy color based on current turn + # In your system: + # - White pieces have Item_Color == 0 + # - Black pieces have Item_Color == 1 + # - Turn == 0 means white's turn, Turn == 1 means black's turn + var enemy_color = 1 if chess_game.Turn == 0 else 0 + + # Iterate through the board to count enemy pieces + for y in range(chess_game.boardYSize): + for x in range(chess_game.boardXSize): + var piece = chess_game.board[y][x] + if piece != null and piece.Item_Color == enemy_color: + count += 1 + + return count + +# Helper methods for game integration + +func load_condition_from_metadata(metadata: Dictionary): + if metadata.has("win_condition"): + match metadata["win_condition"]: + Utils.WinConditionType.CAPTURE_UNIT: + set_win_condition(Utils.WinConditionType.CAPTURE_UNIT, {"unit": "King"}) + Utils.WinConditionType.TILE_REACHED: + # Get target tiles from metadata if available + var target_tiles = metadata.get("target_tiles", []) + set_win_condition(Utils.WinConditionType.TILE_REACHED, {"target_tiles": target_tiles, "unit": metadata.get("target_unit", "")}) + Utils.WinConditionType.BOARD_CLEARED: + set_win_condition(Utils.WinConditionType.BOARD_CLEARED) + Utils.WinConditionType.TURN_NUMBER: + set_win_condition(Utils.WinConditionType.TURN_NUMBER, {"target_turn": metadata.get("target_turn", 20)}) + + if metadata.has("loss_condition"): + match metadata["loss_condition"]: + Utils.LossConditionType.UNIT_LOST: + set_loss_condition(Utils.LossConditionType.UNIT_LOST, {"unit": "King"}) + Utils.LossConditionType.TURN_NUMBER: + set_loss_condition(Utils.LossConditionType.TURN_NUMBER, {"turn_limit": metadata.get("turn_limit", 50)}) + +# Debug methods + +func print_debug_info(): + print("=== WIN CONDITION SYSTEM DEBUG INFO ===") + print("Current win condition: ", _win_condition_type_to_string(win_condition)) + print("Current loss condition: ", _loss_condition_type_to_string(loss_condition)) + print("Win condition data: ", win_condition_data) + print("Loss condition data: ", loss_condition_data) + print("Turn count: ", turn_count) + print("Target tiles: ", target_tiles) + print("Captured pieces: ", captured_pieces.size()) + print("Condition progress: ", condition_progress) + print("Enemy pieces remaining: ", count_enemy_pieces()) + print("=====================================") + +func _win_condition_type_to_string(type: Utils.WinConditionType) -> String: + match type: + Utils.WinConditionType.CAPTURE_UNIT: + return "CAPTURE_UNIT" + Utils.WinConditionType.BOARD_CLEARED: + return "BOARD_CLEARED" + Utils.WinConditionType.TILE_REACHED: + return "TILE_REACHED" + Utils.WinConditionType.TURN_NUMBER: + return "TURN_NUMBER" + _: + return "UNKNOWN" + +func _loss_condition_type_to_string(type: Utils.LossConditionType) -> String: + match type: + Utils.LossConditionType.UNIT_LOST: + return "UNIT_LOST" + Utils.LossConditionType.TURN_NUMBER: + return "TURN_NUMBER" + _: + return "UNKNOWN" \ No newline at end of file diff --git a/Systems/Game/WinConditionManager.gd.uid b/Systems/Game/WinConditionManager.gd.uid new file mode 100644 index 0000000..f79701d --- /dev/null +++ b/Systems/Game/WinConditionManager.gd.uid @@ -0,0 +1 @@ +uid://mgoqcb66wpc3 diff --git a/Systems/StateMachine/GameStates/AttachCards.gd b/Systems/StateMachine/GameStates/AttachCards.gd index 8ddbb0a..1a52bfc 100644 --- a/Systems/StateMachine/GameStates/AttachCards.gd +++ b/Systems/StateMachine/GameStates/AttachCards.gd @@ -1,6 +1,6 @@ extends "res://Systems/StateMachine/ChessGameState.gd" -const ATTACHMENT_PHASE_DURATION = 15 # Duration in seconds +const ATTACHMENT_PHASE_DURATION = 8 # Duration in seconds var timer: Timer var tile_pressed_connection: Signal diff --git a/Systems/StateMachine/GameStates/CleanupPhase.gd b/Systems/StateMachine/GameStates/CleanupPhase.gd index 791dea8..ed966f4 100644 --- a/Systems/StateMachine/GameStates/CleanupPhase.gd +++ b/Systems/StateMachine/GameStates/CleanupPhase.gd @@ -2,7 +2,7 @@ extends "res://Systems/StateMachine/ChessGameState.gd" func enter(_previous: String, data := {}) -> void: print("ENTERING STATE ", Constants.CLEANUP) - game.cleanupPhase() + game.endTurn() if "endCondition" in data: finished.emit(Constants.ROUND_END) diff --git a/Systems/StateMachine/GameStates/Movement.gd b/Systems/StateMachine/GameStates/Movement.gd index 73e2120..ee55a7a 100644 --- a/Systems/StateMachine/GameStates/Movement.gd +++ b/Systems/StateMachine/GameStates/Movement.gd @@ -321,7 +321,7 @@ func handleRegularMove(node: PieceContainer, consume: bool, generated: bool = f func moveAndConsume(node: PieceContainer, consume: bool) -> void: var sourceContainer = game.get_node("Flow/" + game.selectedNode) as PieceContainer var piece = sourceContainer.get_piece() - print("Removing Piece 1") + # print("Removing Piece 1") node.animate_movement(sourceContainer, piece); game.currentlyMovingPiece = piece if consume: diff --git a/Systems/StateMachine/GameStates/PostMovePhase.gd b/Systems/StateMachine/GameStates/PostMovePhase.gd index 1999f4c..37e8abc 100644 --- a/Systems/StateMachine/GameStates/PostMovePhase.gd +++ b/Systems/StateMachine/GameStates/PostMovePhase.gd @@ -2,7 +2,6 @@ extends "res://Systems/StateMachine/ChessGameState.gd" func enter(_previous: String, _data := {}) -> void: print("ENTERING STATE ", Constants.POST_MOVE) - # game.resolveMoveEffects() if (game.isPlayerTurn()): game.updateEffectDurations() diff --git a/Systems/StateMachine/StateMachine.gd b/Systems/StateMachine/StateMachine.gd index f0029a0..fb0d5f8 100644 --- a/Systems/StateMachine/StateMachine.gd +++ b/Systems/StateMachine/StateMachine.gd @@ -21,6 +21,8 @@ func start() -> void: await owner.ready state.enter("") +func enter() -> void: + state.enter("") func unhandledInput(event: InputEvent) -> void: # print("StateMachine received input:", event) diff --git a/Utils/Utils.gd b/Utils/Utils.gd index ebb1a88..99d1630 100644 --- a/Utils/Utils.gd +++ b/Utils/Utils.gd @@ -67,13 +67,18 @@ enum RoomType { EVENT } - -enum WinCondition{ - King, - Clear, - Tile, +enum WinConditionType { + CAPTURE_UNIT, # Default: King capture + BOARD_CLEARED, # Clear the board of all opponent pieces + TILE_REACHED, # Reach a specific tile with a specific unit + TURN_NUMBER # Reach a specific turn number } +# Loss condition types +enum LossConditionType { + UNIT_LOST, # Default: King loss + TURN_NUMBER # Turn limit reached +} static var CardTypes = [