#!/usr/bin/env python3 """ Test to reproduce the exact intersection and boundary issues seen in the crossword images. """ import sys from pathlib import Path # Add project root to path project_root = Path(__file__).parent.parent # Go up from test-integration to backend-py sys.path.insert(0, str(project_root)) from src.services.crossword_generator_fixed import CrosswordGeneratorFixed def reproduce_image_issues(): """Try to reproduce the specific issues seen in the crossword images.""" print("šŸ” Reproducing crossword boundary issues from images...\n") generator = CrosswordGeneratorFixed(vector_service=None) # Test Case 1: Try to reproduce the "MACHINERY" extension issue print("=" * 60) print("TEST 1: Reproducing MACHINERY extension issue") print("=" * 60) grid = [["." for _ in range(15)] for _ in range(15)] placed_words = [] # Place MACHINE first if generator._can_place_word(grid, "MACHINE", 6, 3, "horizontal"): generator._place_word(grid, "MACHINE", 6, 3, "horizontal") placed_words.append({ "word": "MACHINE", "row": 6, "col": 3, "direction": "horizontal", "number": 1 }) print("āœ… Placed MACHINE") print_grid(grid, 4, 10, 0, 12) # Now try to place words that might create the extension test_placements = [ ("VERY", 4, 8, "vertical"), # V-E-R-Y going down, might intersect with E in MACHINE ("EXPERT", 5, 8, "horizontal"), # Horizontal word that might extend MACHINE ("PROTOTYPE", 6, 9, "horizontal"), # Direct extension after MACHINE ] for word, row, col, direction in test_placements: print(f"\nšŸ” Testing: '{word}' at ({row}, {col}) {direction}") can_place = generator._can_place_word(grid, word, row, col, direction) print(f"Can place: {can_place}") if can_place: # Make a copy and test the placement test_grid = [r[:] for r in grid] generator._place_word(test_grid, word, row, col, direction) print("After placement:") print_grid(test_grid, 4, 10, 0, 15) # Check if MACHINE now appears to be extended machine_row = 6 extended_word = "" for c in range(15): if test_grid[machine_row][c] != ".": extended_word += test_grid[machine_row][c] elif extended_word: break if extended_word != "MACHINE": print(f"āš ļø MACHINE appears extended to: '{extended_word}'") print("-" * 40) # Test Case 2: Check intersection logic specifically print("\n" + "=" * 60) print("TEST 2: Checking intersection calculation logic") print("=" * 60) # Test the intersection finding logic word1 = "MACHINE" word2 = "EXPERT" intersections = generator._find_word_intersections(word1, word2) print(f"Intersections between '{word1}' and '{word2}': {intersections}") for intersection in intersections: word_pos = intersection["word_pos"] placed_pos = intersection["placed_pos"] print(f" Letter '{word1[word_pos]}' at pos {word_pos} in '{word1}' matches") print(f" Letter '{word2[placed_pos]}' at pos {placed_pos} in '{word2}'") # Calculate where EXPERT would be placed to intersect with MACHINE machine_placement = {"word": "MACHINE", "row": 6, "col": 3, "direction": "horizontal"} placement = generator._calculate_intersection_placement( word2, placed_pos, machine_placement, word_pos ) if placement: print(f" EXPERT would be placed at: row={placement['row']}, col={placement['col']}, dir={placement['direction']}") # Check if this would be valid can_place = generator._can_place_word(grid, word2, placement['row'], placement['col'], placement['direction']) print(f" Valid placement: {can_place}") # Test Case 3: Multi-word intersection scenario print("\n" + "=" * 60) print("TEST 3: Multi-word intersection scenario") print("=" * 60) # Create a more complex scenario like in the images complex_grid = [["." for _ in range(15)] for _ in range(15)] complex_words = [] # Place several words to create intersection opportunities word_placements = [ ("MACHINE", 7, 4, "horizontal"), ("EXPERT", 5, 6, "vertical"), # Try to intersect at 'E' ("SMART", 6, 8, "vertical"), # Try to intersect at another letter ] for word, row, col, direction in word_placements: print(f"\nPlacing '{word}' at ({row}, {col}) {direction}") if generator._can_place_word(complex_grid, word, row, col, direction): generator._place_word(complex_grid, word, row, col, direction) complex_words.append({ "word": word, "row": row, "col": col, "direction": direction, "number": len(complex_words) + 1 }) print(f"āœ… Placed '{word}'") else: print(f"āŒ Cannot place '{word}'") print_grid(complex_grid, 4, 11, 2, 13) # Check for any unintended word formations print("\nChecking for unintended word formations:") check_unintended_words(complex_grid, complex_words) def print_grid(grid, start_row, end_row, start_col, end_col): """Print a section of the grid.""" print("Grid:") for r in range(max(0, start_row), min(end_row, len(grid))): row_str = f"R{r:2d}: " for c in range(max(0, start_col), min(end_col, len(grid[0]))): if grid[r][c] == ".": row_str += ". " else: row_str += f"{grid[r][c]} " print(row_str) print() def check_unintended_words(grid, placed_words): """Check for unintended word formations in the grid.""" unintended = [] # Check all horizontal sequences for r in range(len(grid)): current_word = "" start_col = None for c in range(len(grid[0])): if grid[r][c] != ".": if start_col is None: start_col = c current_word += grid[r][c] else: if current_word and len(current_word) > 1: # Check if this is an intended word intended = False for word_info in placed_words: if (word_info["direction"] == "horizontal" and word_info["row"] == r and word_info["col"] == start_col and word_info["word"] == current_word): intended = True break if not intended: unintended.append(f"Horizontal '{current_word}' at row {r}, col {start_col}") current_word = "" start_col = None # Check final word if row ends with letters if current_word and len(current_word) > 1: intended = False for word_info in placed_words: if (word_info["direction"] == "horizontal" and word_info["row"] == r and word_info["col"] == start_col and word_info["word"] == current_word): intended = True break if not intended: unintended.append(f"Horizontal '{current_word}' at row {r}, col {start_col}") # Check all vertical sequences for c in range(len(grid[0])): current_word = "" start_row = None for r in range(len(grid)): if grid[r][c] != ".": if start_row is None: start_row = r current_word += grid[r][c] else: if current_word and len(current_word) > 1: # Check if this is an intended word intended = False for word_info in placed_words: if (word_info["direction"] == "vertical" and word_info["col"] == c and word_info["row"] == start_row and word_info["word"] == current_word): intended = True break if not intended: unintended.append(f"Vertical '{current_word}' at row {start_row}, col {c}") current_word = "" start_row = None # Check final word if column ends with letters if current_word and len(current_word) > 1: intended = False for word_info in placed_words: if (word_info["direction"] == "vertical" and word_info["col"] == c and word_info["row"] == start_row and word_info["word"] == current_word): intended = True break if not intended: unintended.append(f"Vertical '{current_word}' at row {start_row}, col {c}") if unintended: print("āŒ Unintended words found:") for word in unintended: print(f" {word}") else: print("āœ… No unintended words detected") if __name__ == "__main__": reproduce_image_issues()