Files
wordpuzzles/tools/test_generator.py
T

50 lines
2.0 KiB
Python

# -*- coding: utf-8 -*-
import json, csv, copy, random
from collections import defaultdict
def validate_stage(stage):
grid_size = stage['gridSize']
clues = stage['clues']
grid = {}
if len(clues) < 3:
return False, f"Stage {stage.get('stageNumber')}: Too few clues ({len(clues)})"
word_connections = {c['id']: set() for c in clues}
for clue in clues:
word = clue['word']
length = clue['length']
r = clue['startRow']
c = clue['startCol']
direction = clue['direction']
if len(word) != length:
return False, f"Stage {stage.get('stageNumber')} Clue {clue['id']}: word '{word}' len {len(word)} != length {length}"
if length < 2:
return False, f"Stage {stage.get('stageNumber')} Clue {clue['id']}: 1-letter word '{word}' not allowed"
for i, ch in enumerate(word):
curr_r = r + (i if direction == 'DOWN' else 0)
curr_c = c + (i if direction == 'ACROSS' else 0)
if curr_r < 0 or curr_r >= grid_size or curr_c < 0 or curr_c >= grid_size:
return False, f"Stage {stage.get('stageNumber')} Clue {clue['id']}: '{word}' char '{ch}' at ({curr_r}, {curr_c}) out of bounds ({grid_size}x{grid_size})"
if (curr_r, curr_c) in grid:
existing_ch, existing_id = grid[(curr_r, curr_c)]
if existing_ch != ch:
return False, f"Stage {stage.get('stageNumber')} CLASH at ({curr_r}, {curr_c}): existing '{existing_ch}' ({existing_id}) vs '{ch}' in {clue['id']} ('{word}')"
word_connections[clue['id']].add(existing_id)
word_connections[existing_id].add(clue['id'])
else:
grid[(curr_r, curr_c)] = (ch, clue['id'])
for cid, conns in word_connections.items():
if not conns:
return False, f"Stage {stage.get('stageNumber')} Clue {cid} has no intersections!"
return True, "OK"
print("Test generator script ready.")