abc123 / crossword-app /backend-py /debug_grid_direct.py
vimalk78's picture
Add complete Python backend with AI-powered crossword generation
38c016b
raw
history blame
10.4 kB
#!/usr/bin/env python3
"""
Direct grid generation test to identify word boundary/display issues.
"""
import sys
from pathlib import Path
# Add project root to path
project_root = Path(__file__).parent
sys.path.insert(0, str(project_root))
from src.services.crossword_generator_fixed import CrosswordGeneratorFixed
def test_direct_grid_generation():
"""Test grid generation directly with controlled words."""
print("🔍 Direct Grid Generation Test\n")
generator = CrosswordGeneratorFixed(vector_service=None)
# Test words that might cause the issues seen in the images
test_words = [
{"word": "MACHINE", "clue": "Device with moving parts"},
{"word": "COMPUTER", "clue": "Electronic device"},
{"word": "EXPERT", "clue": "Person with specialized knowledge"},
{"word": "SCIENCE", "clue": "Systematic study"},
{"word": "CAMERA", "clue": "Device for taking photos"},
{"word": "METHOD", "clue": "Systematic approach"}
]
print("=" * 60)
print("TEST 1: Direct grid creation")
print("=" * 60)
# Test the _create_grid method directly
result = generator._create_grid(test_words)
if result:
print("✅ Grid generation successful!")
grid = result["grid"]
placed_words = result["placed_words"]
clues = result["clues"]
print(f"Grid size: {len(grid)}x{len(grid[0])}")
print(f"Words placed: {len(placed_words)}")
print(f"Clues generated: {len(clues)}")
# Print the grid
print("\nGenerated Grid:")
print_grid_with_coordinates(grid)
# Print placed words details
print("\nPlaced Words:")
for i, word_info in enumerate(placed_words):
print(f" {i+1}. {word_info['word']} at ({word_info['row']}, {word_info['col']}) {word_info['direction']}")
# Print clues
print("\nGenerated Clues:")
for clue in clues:
print(f" {clue['number']}. {clue['direction']}: {clue['word']} - {clue['text']}")
# Analyze for potential issues
print("\n" + "=" * 60)
print("ANALYSIS")
print("=" * 60)
analyze_grid_issues(grid, placed_words, clues)
else:
print("❌ Grid generation failed")
# Test another scenario that might reproduce the image issues
print("\n" + "=" * 60)
print("TEST 2: Scenario with potential extension words")
print("=" * 60)
# Words that might create the "MACHINERY" type issue
extension_words = [
{"word": "MACHINE", "clue": "Device with moving parts"},
{"word": "MACHINERY", "clue": "Mechanical equipment"}, # Might cause confusion
{"word": "EXPERT", "clue": "Specialist"},
{"word": "TECHNOLOGY", "clue": "Applied science"},
]
result2 = generator._create_grid(extension_words)
if result2:
print("✅ Extension test grid generated!")
grid2 = result2["grid"]
placed_words2 = result2["placed_words"]
print("\nExtension Test Grid:")
print_grid_with_coordinates(grid2)
print("\nPlaced Words:")
for i, word_info in enumerate(placed_words2):
print(f" {i+1}. {word_info['word']} at ({word_info['row']}, {word_info['col']}) {word_info['direction']}")
# Check specifically for MACHINE vs MACHINERY issues
check_machine_machinery_issue(grid2, placed_words2)
else:
print("❌ Extension test grid generation failed")
def print_grid_with_coordinates(grid):
"""Print grid with row and column coordinates."""
if not grid:
print(" Empty grid")
return
# Print column headers
print(" ", end="")
for c in range(len(grid[0])):
print(f"{c:2d}", end="")
print()
# Print rows
for r in range(len(grid)):
print(f" {r:2d}: ", end="")
for c in range(len(grid[0])):
cell = grid[r][c]
if cell == ".":
print(" .", end="")
else:
print(f" {cell}", end="")
print()
def analyze_grid_issues(grid, placed_words, clues):
"""Analyze the grid for potential boundary/display issues."""
print("Checking for potential issues...")
issues = []
# Check 1: Verify each placed word actually exists in the grid
for word_info in placed_words:
word = word_info["word"]
row = word_info["row"]
col = word_info["col"]
direction = word_info["direction"]
grid_word = extract_word_from_grid(grid, row, col, direction, len(word))
if grid_word != word:
issues.append(f"Word mismatch: '{word}' expected at ({row},{col}) {direction}, but grid shows '{grid_word}'")
# Check 2: Look for unintended letter sequences
all_sequences = find_all_letter_sequences(grid)
intended_words = {(w["row"], w["col"], w["direction"]): w["word"] for w in placed_words}
for seq_info in all_sequences:
row, col, direction, seq_word = seq_info
key = (row, col, direction)
if key not in intended_words:
if len(seq_word) > 1: # Only care about multi-letter sequences
issues.append(f"Unintended sequence: '{seq_word}' at ({row},{col}) {direction}")
elif intended_words[key] != seq_word:
issues.append(f"Sequence mismatch: expected '{intended_words[key]}' but found '{seq_word}' at ({row},{col}) {direction}")
# Check 3: Verify clue consistency
for clue in clues:
clue_word = clue["word"]
pos = clue["position"]
clue_row = pos["row"]
clue_col = pos["col"]
clue_direction = clue["direction"]
# Convert direction format if needed
direction_map = {"across": "horizontal", "down": "vertical"}
normalized_direction = direction_map.get(clue_direction, clue_direction)
grid_word = extract_word_from_grid(grid, clue_row, clue_col, normalized_direction, len(clue_word))
if grid_word != clue_word:
issues.append(f"Clue mismatch: clue says '{clue_word}' at ({clue_row},{clue_col}) {clue_direction}, but grid shows '{grid_word}'")
# Report results
if issues:
print("❌ Issues found:")
for issue in issues:
print(f" {issue}")
else:
print("✅ No issues detected - grid appears consistent")
def extract_word_from_grid(grid, row, col, direction, expected_length):
"""Extract word from grid at given position and direction."""
if row >= len(grid) or col >= len(grid[0]) or row < 0 or col < 0:
return "OUT_OF_BOUNDS"
word = ""
if direction in ["horizontal", "across"]:
for i in range(expected_length):
if col + i >= len(grid[0]):
return word + "[TRUNCATED]"
word += grid[row][col + i]
elif direction in ["vertical", "down"]:
for i in range(expected_length):
if row + i >= len(grid):
return word + "[TRUNCATED]"
word += grid[row + i][col]
return word
def find_all_letter_sequences(grid):
"""Find all letter sequences (horizontal and vertical) in the grid."""
sequences = []
# 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:
sequences.append((r, start_col, "horizontal", current_word))
current_word = ""
start_col = None
# Handle end of row
if current_word and len(current_word) > 1:
sequences.append((r, start_col, "horizontal", current_word))
# 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:
sequences.append((start_row, c, "vertical", current_word))
current_word = ""
start_row = None
# Handle end of column
if current_word and len(current_word) > 1:
sequences.append((start_row, c, "vertical", current_word))
return sequences
def check_machine_machinery_issue(grid, placed_words):
"""Specifically check for MACHINE vs MACHINERY confusion."""
print("\nChecking for MACHINE/MACHINERY issue:")
machine_words = [w for w in placed_words if "MACHINE" in w["word"]]
if not machine_words:
print(" No MACHINE-related words found")
return
for word_info in machine_words:
word = word_info["word"]
row = word_info["row"]
col = word_info["col"]
direction = word_info["direction"]
print(f" Found: '{word}' at ({row},{col}) {direction}")
# Check what's actually in the grid at this location
grid_word = extract_word_from_grid(grid, row, col, direction, len(word))
print(f" Grid shows: '{grid_word}'")
# Check if there are extra letters that might create confusion
if direction == "horizontal":
# Check for letters after the word
end_col = col + len(word)
if end_col < len(grid[0]) and grid[row][end_col] != ".":
extra_letters = ""
check_col = end_col
while check_col < len(grid[0]) and grid[row][check_col] != ".":
extra_letters += grid[row][check_col]
check_col += 1
if extra_letters:
print(f" ⚠️ Extra letters after word: '{extra_letters}'")
print(f" This might make '{word}' appear as '{word + extra_letters}'")
if __name__ == "__main__":
test_direct_grid_generation()