File size: 10,228 Bytes
38c016b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
#!/usr/bin/env python3
"""
Test to identify and fix word boundary issues causing unwanted prefixes/suffixes.
"""
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 test_word_boundary_violations():
"""Test for word boundary violations that create unwanted prefixes/suffixes."""
generator = CrosswordGeneratorFixed(vector_service=None)
# Test case 1: Simple word placement with boundary checking
print("π§ͺ Testing word boundary violations...\n")
# Create a grid and place a word
grid = [["." for _ in range(10)] for _ in range(10)]
# Place "MACHINE" horizontally at row 5, col 2
placed_words = []
# First, place MACHINE
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
# Now try to place a word that might create boundary violations
# Try placing "CAR" vertically intersecting with "A" in MACHINE
test_words = [
("CAR", 3, 4, "vertical"), # Should intersect at 'A' in MACHINE
("ACE", 4, 3, "vertical"), # Should intersect at 'C' in MACHINE
("RIG", 6, 7, "vertical"), # Should intersect at 'I' in MACHINE
]
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):
# Check if this placement would create boundary issues
print(f"β
Can place '{word}' - checking for boundary violations...")
# Simulate the placement
test_grid = [row[:] for row in grid] # Deep copy
test_original = generator._place_word(test_grid, word, row, col, direction)
print_grid_section(test_grid, 2, 9, 0, 10)
# Check if any unintended words are formed
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}'")
# Restore grid
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 = []
# Check the immediate boundaries of the new word
if direction == "horizontal":
# Check before the word
if col > 0 and grid[row][col - 1] != ".":
violations.append(f"Unwanted prefix: letter '{grid[row][col - 1]}' before '{new_word}'")
# Check after the 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}'")
# Check perpendicular extensions at each letter
for i, letter in enumerate(new_word):
letter_col = col + i
# Check above and below each letter for unintended words
above_letters = []
below_letters = []
# Collect letters above
r = row - 1
while r >= 0 and grid[r][letter_col] != ".":
above_letters.insert(0, grid[r][letter_col])
r -= 1
# Collect letters below
r = row + 1
while r < len(grid) and grid[r][letter_col] != ".":
below_letters.append(grid[r][letter_col])
r += 1
# Check if this forms an unintended word
if above_letters or below_letters:
full_vertical_word = "".join(above_letters) + letter + "".join(below_letters)
if len(full_vertical_word) > 1:
# Check if this is an intended word from existing placements
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: # vertical
# Check before the word (above)
if row > 0 and grid[row - 1][col] != ".":
violations.append(f"Unwanted prefix: letter '{grid[row - 1][col]}' above '{new_word}'")
# Check after the word (below)
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}'")
# Check perpendicular extensions at each letter
for i, letter in enumerate(new_word):
letter_row = row + i
# Collect letters to the left and right
left_letters = []
right_letters = []
# Collect letters to the left
c = col - 1
while c >= 0 and grid[letter_row][c] != ".":
left_letters.insert(0, grid[letter_row][c])
c -= 1
# Collect letters to the right
c = col + 1
while c < len(grid[0]) and grid[letter_row][c] != ".":
right_letters.append(grid[letter_row][c])
c += 1
# Check if this forms an unintended word
if left_letters or right_letters:
full_horizontal_word = "".join(left_letters) + letter + "".join(right_letters)
if len(full_horizontal_word) > 1:
# Check if this is an intended word from existing placements
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)
# Test problematic scenario from the images
# Create a scenario where MACHINE might get extended to MACHINERY
grid = [["." for _ in range(12)] for _ in range(12)]
# Place MACHINE first
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)
# Now try to place words that might create the "RY" suffix issue
# Place "Y" somewhere that might extend MACHINE
problem_placements = [
("RYOT", 5, 9, "horizontal"), # This would make MACHINE -> MACHINERYOT
("CAR", 3, 8, "vertical"), # This might create unwanted extensions
]
for word, row, col, direction in problem_placements:
print(f"\nπ Testing problematic placement: '{word}' at ({row}, {col}) {direction}")
# Check current can_place_word logic
can_place = generator._can_place_word(grid, word, row, col, direction)
print(f"Current _can_place_word result: {can_place}")
if can_place:
# Show what would happen
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)
# Check for violations manually
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.") |