slightly improve crossword generation
This commit is contained in:
parent
5c08922bec
commit
d18c115a9c
@ -106,7 +106,7 @@ class LetterField(Field):
|
|||||||
|
|
||||||
|
|
||||||
class Grid(object):
|
class Grid(object):
|
||||||
def __init__(self, width: int, height: int, lang_code: str, density=0.8, difficulty: int = 0):
|
def __init__(self, width: int, height: int, lang_code: str, density=0.81, difficulty: int = 0):
|
||||||
self._width = width
|
self._width = width
|
||||||
self._height = height
|
self._height = height
|
||||||
self._lang_code = lang_code
|
self._lang_code = lang_code
|
||||||
|
@ -662,11 +662,11 @@ class GridCreationState(object):
|
|||||||
min_coord_max = min_xmax
|
min_coord_max = min_xmax
|
||||||
max_coord_max = max_xmax
|
max_coord_max = max_xmax
|
||||||
|
|
||||||
n_options = max_coord_max - min_coord_max + max_coord_min - min_coord_min
|
n_options = (max_coord_max - min_coord_max) * (max_coord_min - min_coord_min)
|
||||||
|
|
||||||
solved = False
|
solved = False
|
||||||
|
|
||||||
for _ in range(min(n_options, n_retries)):
|
for _ in range(int(n_options * 1.5)):
|
||||||
coord_min = random.randint(min_coord_min, max_coord_min)
|
coord_min = random.randint(min_coord_min, max_coord_min)
|
||||||
coord_max = random.randint(min_coord_max, max_coord_max)
|
coord_max = random.randint(min_coord_max, max_coord_max)
|
||||||
length = coord_max - coord_min
|
length = coord_max - coord_min
|
||||||
@ -733,13 +733,32 @@ class GridCreationState(object):
|
|||||||
return solved_state
|
return solved_state
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def fill_grid(self, target_density: float = 0.6, inner_retries: int = 5, conflict_retries: int = 10, conflict_solver_depth=5, min_length: int = 4, max_length: int = 10, max_iterations: int = 1000):
|
def fill_grid(self, target_density: float = 0.6, inner_retries: int = 5, conflict_solver_depth=5, min_length: int = 4, max_length: int = 10, max_iterations: int = 1000):
|
||||||
i = 0
|
i = 0
|
||||||
state = self.copy()
|
state = self.copy()
|
||||||
while i < max_iterations and state.get_density() < target_density:
|
current_density = state.get_density()
|
||||||
|
while i < max_iterations and current_density < target_density:
|
||||||
|
current_density = state.get_density()
|
||||||
i += 1
|
i += 1
|
||||||
new_state = state.copy()
|
new_state = state.copy()
|
||||||
conflicts = new_state.place_random_word(min_length, max_length)
|
|
||||||
|
|
||||||
|
# try semi-dynamic word length (try longer words at the beginning)
|
||||||
|
min_length_offset = 0
|
||||||
|
max_length_offset = 0
|
||||||
|
|
||||||
|
#min_length_offset = int((i / max_iterations) * (max_length - min_length))
|
||||||
|
|
||||||
|
#if current_density < 0.5 * target_density:
|
||||||
|
# min_length_offset = int(0.5 * (max_length - min_length) * (1 - (current_density / target_density)))
|
||||||
|
# #logging.info("mi %s",str(min_length_offset))
|
||||||
|
|
||||||
|
#if current_density > 0.9 * target_density:
|
||||||
|
# max_length_offset = - int(0.5 * (max_length - min_length) * ((current_density / target_density)))
|
||||||
|
# #logging.info("max %s",str(max_length_offset))
|
||||||
|
|
||||||
|
|
||||||
|
conflicts = new_state.place_random_word(min_length + min_length_offset, max_length + max_length_offset)
|
||||||
if conflicts is None:
|
if conflicts is None:
|
||||||
continue
|
continue
|
||||||
if len(conflicts) == 0:
|
if len(conflicts) == 0:
|
||||||
@ -752,8 +771,8 @@ class GridCreationState(object):
|
|||||||
if solved_state is not None:
|
if solved_state is not None:
|
||||||
state = solved_state
|
state = solved_state
|
||||||
|
|
||||||
logging.info("finished after %s iterations, with a density of %s", str(
|
logging.info("finished after %s iterations, with a density of %s (desired density: %s)", str(
|
||||||
i), str(state.get_density()))
|
i), str(state.get_density()), str(target_density))
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
@ -776,10 +795,11 @@ def create_word_grid(w: int,
|
|||||||
base_grid = GridCreationState(h=h, w=w, db=db, inverted_db=inverted_db)
|
base_grid = GridCreationState(h=h, w=w, db=db, inverted_db=inverted_db)
|
||||||
|
|
||||||
final_state = base_grid.fill_grid(target_density=target_density,
|
final_state = base_grid.fill_grid(target_density=target_density,
|
||||||
inner_retries=7,
|
inner_retries=10,
|
||||||
conflict_solver_depth=20,
|
conflict_solver_depth=10,
|
||||||
min_length=2,
|
min_length=3,
|
||||||
max_iterations=max(75 * (w+h)/2, 1000))
|
max_length=int(min(w,h) * 0.6),
|
||||||
|
max_iterations=5000)
|
||||||
|
|
||||||
# generate word hints
|
# generate word hints
|
||||||
|
|
||||||
@ -850,6 +870,8 @@ def create_word_grid(w: int,
|
|||||||
if aborted:
|
if aborted:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
logging.info("solution word: %s", str(random_word))
|
||||||
|
|
||||||
solution_word_locations = solution
|
solution_word_locations = solution
|
||||||
|
|
||||||
return final_state.letter_grid, word_hints, solution_word_locations
|
return final_state.letter_grid, word_hints, solution_word_locations
|
||||||
|
Loading…
Reference in New Issue
Block a user