|
|
|
""" |
|
Test to identify and fix word boundary issues causing unwanted prefixes/suffixes. |
|
""" |
|
|
|
import sys |
|
from pathlib import Path |
|
|
|
|
|
project_root = Path(__file__).parent.parent |
|
sys.path.insert(0, str(project_root)) |
|
|
|
from src.services.crossword_generator_fixed import CrosswordGeneratorFixed |
|
|
|
def test_word_boundary_violations(): |
|
"""Test for word boundary violations that create unwanted prefixes/suffixes.""" |
|
|
|
generator = CrosswordGeneratorFixed(vector_service=None) |
|
|
|
|
|
print("🧪 Testing word boundary violations...\n") |
|
|
|
|
|
grid = [["." for _ in range(10)] for _ in range(10)] |
|
|
|
|
|
placed_words = [] |
|
|
|
|
|
if generator._can_place_word(grid, "MACHINE", 5, 2, "horizontal"): |
|
original_state = generator._place_word(grid, "MACHINE", 5, 2, "horizontal") |
|
placed_words.append({ |
|
"word": "MACHINE", |
|
"row": 5, |
|
"col": 2, |
|
"direction": "horizontal", |
|
"number": 1 |
|
}) |
|
print("✅ Placed MACHINE horizontally") |
|
print_grid_section(grid, 4, 7, 0, 10) |
|
else: |
|
print("❌ Cannot place MACHINE") |
|
return False |
|
|
|
|
|
|
|
test_words = [ |
|
("CAR", 3, 4, "vertical"), |
|
("ACE", 4, 3, "vertical"), |
|
("RIG", 6, 7, "vertical"), |
|
] |
|
|
|
for word, row, col, direction in test_words: |
|
print(f"\n🔍 Testing placement of '{word}' at ({row}, {col}) {direction}") |
|
|
|
if generator._can_place_word(grid, word, row, col, direction): |
|
|
|
print(f"✅ Can place '{word}' - checking for boundary violations...") |
|
|
|
|
|
test_grid = [row[:] for row in grid] |
|
test_original = generator._place_word(test_grid, word, row, col, direction) |
|
|
|
print_grid_section(test_grid, 2, 9, 0, 10) |
|
|
|
|
|
violations = check_word_boundary_violations(test_grid, word, row, col, direction, placed_words) |
|
if violations: |
|
print(f"❌ Boundary violations detected: {violations}") |
|
else: |
|
print(f"✅ No boundary violations for '{word}'") |
|
|
|
|
|
generator._remove_word(test_grid, test_original) |
|
else: |
|
print(f"❌ Cannot place '{word}' at ({row}, {col}) {direction}") |
|
|
|
print("\n" + "="*50) |
|
return True |
|
|
|
def print_grid_section(grid, start_row, end_row, start_col, end_col): |
|
"""Print a section of the grid for visualization.""" |
|
print("Grid section:") |
|
for r in range(start_row, min(end_row, len(grid))): |
|
row_str = "" |
|
for c in range(start_col, min(end_col, len(grid[0]))): |
|
if grid[r][c] == ".": |
|
row_str += ". " |
|
else: |
|
row_str += f"{grid[r][c]} " |
|
print(f"Row {r:2d}: {row_str}") |
|
print() |
|
|
|
def check_word_boundary_violations(grid, new_word, row, col, direction, existing_words): |
|
"""Check if placing a word creates unintended word extensions.""" |
|
violations = [] |
|
|
|
|
|
if direction == "horizontal": |
|
|
|
if col > 0 and grid[row][col - 1] != ".": |
|
violations.append(f"Unwanted prefix: letter '{grid[row][col - 1]}' before '{new_word}'") |
|
|
|
|
|
if col + len(new_word) < len(grid[0]) and grid[row][col + len(new_word)] != ".": |
|
violations.append(f"Unwanted suffix: letter '{grid[row][col + len(new_word)]}' after '{new_word}'") |
|
|
|
|
|
for i, letter in enumerate(new_word): |
|
letter_col = col + i |
|
|
|
|
|
above_letters = [] |
|
below_letters = [] |
|
|
|
|
|
r = row - 1 |
|
while r >= 0 and grid[r][letter_col] != ".": |
|
above_letters.insert(0, grid[r][letter_col]) |
|
r -= 1 |
|
|
|
|
|
r = row + 1 |
|
while r < len(grid) and grid[r][letter_col] != ".": |
|
below_letters.append(grid[r][letter_col]) |
|
r += 1 |
|
|
|
|
|
if above_letters or below_letters: |
|
full_vertical_word = "".join(above_letters) + letter + "".join(below_letters) |
|
if len(full_vertical_word) > 1: |
|
|
|
intended = False |
|
for existing in existing_words: |
|
if (existing["direction"] == "vertical" and |
|
existing["col"] == letter_col and |
|
existing["word"] == full_vertical_word): |
|
intended = True |
|
break |
|
|
|
if not intended and len(full_vertical_word) > 1: |
|
violations.append(f"Unintended vertical word '{full_vertical_word}' at column {letter_col}") |
|
|
|
else: |
|
|
|
if row > 0 and grid[row - 1][col] != ".": |
|
violations.append(f"Unwanted prefix: letter '{grid[row - 1][col]}' above '{new_word}'") |
|
|
|
|
|
if row + len(new_word) < len(grid) and grid[row + len(new_word)][col] != ".": |
|
violations.append(f"Unwanted suffix: letter '{grid[row + len(new_word)][col]}' below '{new_word}'") |
|
|
|
|
|
for i, letter in enumerate(new_word): |
|
letter_row = row + i |
|
|
|
|
|
left_letters = [] |
|
right_letters = [] |
|
|
|
|
|
c = col - 1 |
|
while c >= 0 and grid[letter_row][c] != ".": |
|
left_letters.insert(0, grid[letter_row][c]) |
|
c -= 1 |
|
|
|
|
|
c = col + 1 |
|
while c < len(grid[0]) and grid[letter_row][c] != ".": |
|
right_letters.append(grid[letter_row][c]) |
|
c += 1 |
|
|
|
|
|
if left_letters or right_letters: |
|
full_horizontal_word = "".join(left_letters) + letter + "".join(right_letters) |
|
if len(full_horizontal_word) > 1: |
|
|
|
intended = False |
|
for existing in existing_words: |
|
if (existing["direction"] == "horizontal" and |
|
existing["row"] == letter_row and |
|
existing["word"] == full_horizontal_word): |
|
intended = True |
|
break |
|
|
|
if not intended and len(full_horizontal_word) > 1: |
|
violations.append(f"Unintended horizontal word '{full_horizontal_word}' at row {letter_row}") |
|
|
|
return violations |
|
|
|
def test_enhanced_boundary_checking(): |
|
"""Test enhanced boundary checking logic.""" |
|
print("🧪 Testing enhanced boundary checking logic...\n") |
|
|
|
generator = CrosswordGeneratorFixed(vector_service=None) |
|
|
|
|
|
|
|
grid = [["." for _ in range(12)] for _ in range(12)] |
|
|
|
|
|
generator._place_word(grid, "MACHINE", 5, 2, "horizontal") |
|
placed_words = [{ |
|
"word": "MACHINE", "row": 5, "col": 2, "direction": "horizontal", "number": 1 |
|
}] |
|
|
|
print("Initial grid with MACHINE:") |
|
print_grid_section(grid, 4, 7, 0, 12) |
|
|
|
|
|
|
|
problem_placements = [ |
|
("RYOT", 5, 9, "horizontal"), |
|
("CAR", 3, 8, "vertical"), |
|
] |
|
|
|
for word, row, col, direction in problem_placements: |
|
print(f"\n🔍 Testing problematic placement: '{word}' at ({row}, {col}) {direction}") |
|
|
|
|
|
can_place = generator._can_place_word(grid, word, row, col, direction) |
|
print(f"Current _can_place_word result: {can_place}") |
|
|
|
if can_place: |
|
|
|
test_grid = [row[:] for row in grid] |
|
generator._place_word(test_grid, word, row, col, direction) |
|
print("Result grid:") |
|
print_grid_section(test_grid, 3, 8, 0, 12) |
|
|
|
|
|
violations = check_word_boundary_violations(test_grid, word, row, col, direction, placed_words) |
|
if violations: |
|
print(f"❌ This placement creates violations: {violations}") |
|
else: |
|
print("✅ No violations detected") |
|
|
|
if __name__ == "__main__": |
|
print("🔍 Testing Word Boundary Issues\n") |
|
|
|
test_word_boundary_violations() |
|
print("\n" + "="*60 + "\n") |
|
test_enhanced_boundary_checking() |
|
|
|
print("\n🎯 Analysis complete. Check output for boundary violation patterns.") |