abc123 / crossword-app /backend-py /test-integration /test_intersection_issues.py
vimalk78's picture
Add complete Python backend with AI-powered crossword generation
38c016b
raw
history blame
9.72 kB
#!/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()