lint fixes
Some checks failed
Continuous Integration / Code Formatting (pull_request) Successful in 27s
Continuous Integration / Code Quality Check (pull_request) Successful in 29s
Continuous Integration / Test Execution (pull_request) Failing after 33s
Continuous Integration / CI Summary (pull_request) Failing after 5s

This commit is contained in:
2025-09-28 19:16:20 +04:00
parent c1f3f9f708
commit eb99c6a18e
46 changed files with 2608 additions and 1304 deletions

View File

@@ -10,8 +10,6 @@ signal grid_state_loaded(grid_size: Vector2i, tile_types: int)
## PROCESSING: Detecting matches, clearing tiles, dropping new ones, checking cascades
enum GameState { WAITING, SELECTING, SWAPPING, PROCESSING }
var GRID_SIZE := Vector2i(8, 8)
var TILE_TYPES := 5
const TILE_SCENE := preload("res://scenes/game/gameplays/tile.tscn")
# Safety constants
@@ -32,6 +30,9 @@ const CASCADE_WAIT_TIME := 0.1
const SWAP_ANIMATION_TIME := 0.3
const TILE_DROP_WAIT_TIME := 0.2
var grid_size := Vector2i(8, 8)
var tile_types := 5
var grid: Array[Array] = []
var tile_size: float = 48.0
var grid_offset: Vector2 = Vector2.ZERO
@@ -71,7 +72,7 @@ func _ready() -> void:
DebugManager.log_debug("Match3 _ready() completed, calling debug structure check", "Match3")
# Notify UI that grid state is loaded
grid_state_loaded.emit(GRID_SIZE, TILE_TYPES)
grid_state_loaded.emit(grid_size, tile_types)
# Debug: Check scene tree structure
call_deferred("_debug_scene_structure")
@@ -83,12 +84,12 @@ func _calculate_grid_layout():
var available_height = viewport_size.y * SCREEN_HEIGHT_USAGE
# Calculate tile size based on available space
var max_tile_width = available_width / GRID_SIZE.x
var max_tile_height = available_height / GRID_SIZE.y
var max_tile_width = available_width / grid_size.x
var max_tile_height = available_height / grid_size.y
tile_size = min(max_tile_width, max_tile_height)
# Align grid to left side with margins
var total_grid_height = tile_size * GRID_SIZE.y
var total_grid_height = tile_size * grid_size.y
grid_offset = Vector2(
GRID_LEFT_MARGIN, (viewport_size.y - total_grid_height) / 2 + GRID_TOP_MARGIN
)
@@ -97,12 +98,12 @@ func _calculate_grid_layout():
func _initialize_grid():
# Create gem pool for current tile types
var gem_indices: Array[int] = []
for i in range(TILE_TYPES):
for i in range(tile_types):
gem_indices.append(i)
for y in range(GRID_SIZE.y):
for y in range(grid_size.y):
grid.append([])
for x in range(GRID_SIZE.x):
for x in range(grid_size.x):
var tile = TILE_SCENE.instantiate()
var tile_position = grid_offset + Vector2(x, y) * tile_size
tile.position = tile_position
@@ -113,7 +114,7 @@ func _initialize_grid():
tile.set_active_gem_types(gem_indices)
# Set tile type after adding to scene tree
var new_type = randi() % TILE_TYPES
var new_type = randi() % tile_types
tile.tile_type = new_type
# Connect tile signals
@@ -159,8 +160,8 @@ func _has_match_at(pos: Vector2i) -> bool:
func _check_for_matches() -> bool:
"""Scan entire grid to detect if any matches exist (used for cascade detection)"""
for y in range(GRID_SIZE.y):
for x in range(GRID_SIZE.x):
for y in range(grid_size.y):
for x in range(grid_size.x):
if _has_match_at(Vector2i(x, y)):
return true
return false
@@ -205,7 +206,7 @@ func _get_match_line(start: Vector2i, dir: Vector2i) -> Array:
var current = start + dir * offset
var steps = 0
# Safety limit prevents infinite loops in case of logic errors
while steps < GRID_SIZE.x + GRID_SIZE.y and _is_valid_grid_position(current):
while steps < grid_size.x + grid_size.y and _is_valid_grid_position(current):
if current.y >= grid.size() or current.x >= grid[current.y].size():
break
@@ -238,11 +239,11 @@ func _clear_matches() -> void:
var match_groups := []
var processed_tiles := {}
for y in range(GRID_SIZE.y):
for y in range(grid_size.y):
if y >= grid.size():
continue
for x in range(GRID_SIZE.x):
for x in range(grid_size.x):
if x >= grid[y].size():
continue
@@ -338,17 +339,18 @@ func _drop_tiles():
var moved = true
while moved:
moved = false
for x in range(GRID_SIZE.x):
# Fixed: Start from GRID_SIZE.y - 1 to avoid out of bounds
for y in range(GRID_SIZE.y - 1, -1, -1):
for x in range(grid_size.x):
# Fixed: Start from grid_size.y - 1 to avoid out of bounds
for y in range(grid_size.y - 1, -1, -1):
var tile = grid[y][x]
# Fixed: Check bounds before accessing y + 1
if tile and y + 1 < GRID_SIZE.y and not grid[y + 1][x]:
if tile and y + 1 < grid_size.y and not grid[y + 1][x]:
grid[y + 1][x] = tile
grid[y][x] = null
tile.grid_position = Vector2i(x, y + 1)
# You can animate position here using Tween for smooth drop:
# tween.interpolate_property(tile, "position", tile.position, grid_offset + Vector2(x, y + 1) * tile_size, 0.2)
# tween.interpolate_property(tile, "position", tile.position,
# grid_offset + Vector2(x, y + 1) * tile_size, 0.2)
tile.position = grid_offset + Vector2(x, y + 1) * tile_size
moved = true
@@ -361,16 +363,16 @@ func _fill_empty_cells():
# Create gem pool for current tile types
var gem_indices: Array[int] = []
for i in range(TILE_TYPES):
for i in range(tile_types):
gem_indices.append(i)
var tiles_created = 0
for y in range(GRID_SIZE.y):
for y in range(grid_size.y):
if y >= grid.size():
DebugManager.log_error("Grid row %d does not exist" % y, "Match3")
continue
for x in range(GRID_SIZE.x):
for x in range(grid_size.x):
if x >= grid[y].size():
DebugManager.log_error("Grid column %d does not exist in row %d" % [x, y], "Match3")
continue
@@ -394,10 +396,10 @@ func _fill_empty_cells():
DebugManager.log_warn("Tile missing set_active_gem_types method", "Match3")
# Set random tile type with bounds checking
if TILE_TYPES > 0:
tile.tile_type = randi() % TILE_TYPES
if tile_types > 0:
tile.tile_type = randi() % tile_types
else:
DebugManager.log_error("TILE_TYPES is 0, cannot set tile type", "Match3")
DebugManager.log_error("tile_types is 0, cannot set tile type", "Match3")
tile.queue_free()
continue
@@ -436,19 +438,19 @@ func _fill_empty_cells():
func regenerate_grid():
# Validate grid size before regeneration
if (
GRID_SIZE.x < MIN_GRID_SIZE
or GRID_SIZE.y < MIN_GRID_SIZE
or GRID_SIZE.x > MAX_GRID_SIZE
or GRID_SIZE.y > MAX_GRID_SIZE
grid_size.x < MIN_GRID_SIZE
or grid_size.y < MIN_GRID_SIZE
or grid_size.x > MAX_GRID_SIZE
or grid_size.y > MAX_GRID_SIZE
):
DebugManager.log_error(
"Invalid grid size for regeneration: %dx%d" % [GRID_SIZE.x, GRID_SIZE.y], "Match3"
"Invalid grid size for regeneration: %dx%d" % [grid_size.x, grid_size.y], "Match3"
)
return
if TILE_TYPES < 3 or TILE_TYPES > MAX_TILE_TYPES:
if tile_types < 3 or tile_types > MAX_TILE_TYPES:
DebugManager.log_error(
"Invalid tile types count for regeneration: %d" % TILE_TYPES, "Match3"
"Invalid tile types count for regeneration: %d" % tile_types, "Match3"
)
return
@@ -515,12 +517,12 @@ func set_tile_types(new_count: int):
)
return
if new_count == TILE_TYPES:
if new_count == tile_types:
DebugManager.log_debug("Tile types count unchanged, skipping regeneration", "Match3")
return
DebugManager.log_debug("Changing tile types from %d to %d" % [TILE_TYPES, new_count], "Match3")
TILE_TYPES = new_count
DebugManager.log_debug("Changing tile types from %d to %d" % [tile_types, new_count], "Match3")
tile_types = new_count
# Regenerate grid with new tile types (gem pool is updated in regenerate_grid)
await regenerate_grid()
@@ -548,12 +550,12 @@ func set_grid_size(new_size: Vector2i):
)
return
if new_size == GRID_SIZE:
if new_size == grid_size:
DebugManager.log_debug("Grid size unchanged, skipping regeneration", "Match3")
return
DebugManager.log_debug("Changing grid size from %s to %s" % [GRID_SIZE, new_size], "Match3")
GRID_SIZE = new_size
DebugManager.log_debug("Changing grid size from %s to %s" % [grid_size, new_size], "Match3")
grid_size = new_size
# Regenerate grid with new size
await regenerate_grid()
@@ -562,8 +564,8 @@ func set_grid_size(new_size: Vector2i):
func reset_all_visual_states() -> void:
# Debug function to reset all tile visual states
DebugManager.log_debug("Resetting all tile visual states", "Match3")
for y in range(GRID_SIZE.y):
for x in range(GRID_SIZE.x):
for y in range(grid_size.y):
for x in range(grid_size.x):
if grid[y][x] and grid[y][x].has_method("force_reset_visual_state"):
grid[y][x].force_reset_visual_state()
@@ -586,12 +588,12 @@ func _debug_scene_structure() -> void:
# Check tiles
var tile_count = 0
for y in range(GRID_SIZE.y):
for x in range(GRID_SIZE.x):
for y in range(grid_size.y):
for x in range(grid_size.x):
if y < grid.size() and x < grid[y].size() and grid[y][x]:
tile_count += 1
DebugManager.log_debug(
"Created %d tiles out of %d expected" % [tile_count, GRID_SIZE.x * GRID_SIZE.y], "Match3"
"Created %d tiles out of %d expected" % [tile_count, grid_size.x * grid_size.y], "Match3"
)
# Check first tile in detail
@@ -668,8 +670,8 @@ func _move_cursor(direction: Vector2i) -> void:
var new_pos = cursor_position + direction
# Bounds checking
new_pos.x = clamp(new_pos.x, 0, GRID_SIZE.x - 1)
new_pos.y = clamp(new_pos.y, 0, GRID_SIZE.y - 1)
new_pos.x = clamp(new_pos.x, 0, grid_size.x - 1)
new_pos.y = clamp(new_pos.y, 0, grid_size.y - 1)
if new_pos != cursor_position:
# Safe access to old tile
@@ -925,8 +927,8 @@ func serialize_grid_state() -> Array:
# Convert the current grid to a serializable 2D array
DebugManager.log_info(
(
"Starting serialization: grid.size()=%d, GRID_SIZE=(%d,%d)"
% [grid.size(), GRID_SIZE.x, GRID_SIZE.y]
"Starting serialization: grid.size()=%d, grid_size=(%d,%d)"
% [grid.size(), grid_size.x, grid_size.y]
),
"Match3"
)
@@ -939,9 +941,9 @@ func serialize_grid_state() -> Array:
var valid_tiles = 0
var null_tiles = 0
for y in range(GRID_SIZE.y):
for y in range(grid_size.y):
var row = []
for x in range(GRID_SIZE.x):
for x in range(grid_size.x):
if y < grid.size() and x < grid[y].size() and grid[y][x]:
row.append(grid[y][x].tile_type)
valid_tiles += 1
@@ -963,7 +965,7 @@ func serialize_grid_state() -> Array:
DebugManager.log_info(
(
"Serialized grid state: %dx%d grid, %d valid tiles, %d null tiles"
% [GRID_SIZE.x, GRID_SIZE.y, valid_tiles, null_tiles]
% [grid_size.x, grid_size.y, valid_tiles, null_tiles]
),
"Match3"
)
@@ -974,12 +976,11 @@ func get_active_gem_types() -> Array:
# Get active gem types from the first available tile
if grid.size() > 0 and grid[0].size() > 0 and grid[0][0]:
return grid[0][0].active_gem_types.duplicate()
else:
# Fallback to default
var default_types = []
for i in range(TILE_TYPES):
default_types.append(i)
return default_types
# Fallback to default
var default_types = []
for i in range(tile_types):
default_types.append(i)
return default_types
func save_current_state():
@@ -990,12 +991,12 @@ func save_current_state():
DebugManager.log_info(
(
"Saving match3 state: size(%d,%d), %d tile types, %d active gems"
% [GRID_SIZE.x, GRID_SIZE.y, TILE_TYPES, active_gems.size()]
% [grid_size.x, grid_size.y, tile_types, active_gems.size()]
),
"Match3"
)
SaveManager.save_grid_state(GRID_SIZE, TILE_TYPES, active_gems, grid_layout)
SaveManager.save_grid_state(grid_size, tile_types, active_gems, grid_layout)
func load_saved_state() -> bool:
@@ -1008,7 +1009,7 @@ func load_saved_state() -> bool:
# Restore grid settings
var saved_size = Vector2i(saved_state.grid_size.x, saved_state.grid_size.y)
TILE_TYPES = saved_state.tile_types_count
tile_types = saved_state.tile_types_count
var saved_gems: Array[int] = []
for gem in saved_state.active_gem_types:
saved_gems.append(int(gem))
@@ -1017,7 +1018,7 @@ func load_saved_state() -> bool:
DebugManager.log_info(
(
"[%s] Loading saved grid state: size(%d,%d), %d tile types, layout_size=%d"
% [instance_id, saved_size.x, saved_size.y, TILE_TYPES, saved_layout.size()]
% [instance_id, saved_size.x, saved_size.y, tile_types, saved_layout.size()]
),
"Match3"
)
@@ -1051,8 +1052,8 @@ func load_saved_state() -> bool:
return false
# Apply the saved settings
var old_size = GRID_SIZE
GRID_SIZE = saved_size
var old_size = grid_size
grid_size = saved_size
# Recalculate layout if size changed
if old_size != saved_size:
@@ -1107,9 +1108,9 @@ func _restore_grid_from_layout(grid_layout: Array, active_gems: Array[int]) -> v
await get_tree().process_frame
# Restore grid from saved layout
for y in range(GRID_SIZE.y):
for y in range(grid_size.y):
grid.append([])
for x in range(GRID_SIZE.x):
for x in range(grid_size.x):
var tile = TILE_SCENE.instantiate()
var tile_position = grid_offset + Vector2(x, y) * tile_size
tile.position = tile_position
@@ -1123,20 +1124,20 @@ func _restore_grid_from_layout(grid_layout: Array, active_gems: Array[int]) -> v
var saved_tile_type = grid_layout[y][x]
DebugManager.log_debug(
(
"Setting tile (%d,%d): saved_type=%d, TILE_TYPES=%d"
% [x, y, saved_tile_type, TILE_TYPES]
"Setting tile (%d,%d): saved_type=%d, tile_types=%d"
% [x, y, saved_tile_type, tile_types]
),
"Match3"
)
if saved_tile_type >= 0 and saved_tile_type < TILE_TYPES:
if saved_tile_type >= 0 and saved_tile_type < tile_types:
tile.tile_type = saved_tile_type
DebugManager.log_debug(
"✓ Restored tile (%d,%d) with saved type %d" % [x, y, saved_tile_type], "Match3"
)
else:
# Fallback for invalid tile types
tile.tile_type = randi() % TILE_TYPES
tile.tile_type = randi() % tile_types
DebugManager.log_error(
(
"✗ Invalid saved tile type %d at (%d,%d), using random %d"
@@ -1150,13 +1151,13 @@ func _restore_grid_from_layout(grid_layout: Array, active_gems: Array[int]) -> v
grid[y].append(tile)
DebugManager.log_info(
"Completed grid restoration: %d tiles restored" % [GRID_SIZE.x * GRID_SIZE.y], "Match3"
"Completed grid restoration: %d tiles restored" % [grid_size.x * grid_size.y], "Match3"
)
# Safety and validation helper functions
func _is_valid_grid_position(pos: Vector2i) -> bool:
return pos.x >= 0 and pos.y >= 0 and pos.x < GRID_SIZE.x and pos.y < GRID_SIZE.y
return pos.x >= 0 and pos.y >= 0 and pos.x < grid_size.x and pos.y < grid_size.y
func _validate_grid_integrity() -> bool:
@@ -1165,9 +1166,9 @@ func _validate_grid_integrity() -> bool:
DebugManager.log_error("Grid is not an array", "Match3")
return false
if grid.size() != GRID_SIZE.y:
if grid.size() != grid_size.y:
DebugManager.log_error(
"Grid height mismatch: %d vs %d" % [grid.size(), GRID_SIZE.y], "Match3"
"Grid height mismatch: %d vs %d" % [grid.size(), grid_size.y], "Match3"
)
return false
@@ -1176,9 +1177,9 @@ func _validate_grid_integrity() -> bool:
DebugManager.log_error("Grid row %d is not an array" % y, "Match3")
return false
if grid[y].size() != GRID_SIZE.x:
if grid[y].size() != grid_size.x:
DebugManager.log_error(
"Grid row %d width mismatch: %d vs %d" % [y, grid[y].size(), GRID_SIZE.x], "Match3"
"Grid row %d width mismatch: %d vs %d" % [y, grid[y].size(), grid_size.x], "Match3"
)
return false