slightly improve crossword generation
This commit is contained in:
		| @ -106,7 +106,7 @@ class LetterField(Field): | ||||
|  | ||||
|  | ||||
| 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._height = height | ||||
|         self._lang_code = lang_code | ||||
|  | ||||
| @ -662,11 +662,11 @@ class GridCreationState(object): | ||||
|                 min_coord_max = min_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 | ||||
|  | ||||
|             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_max = random.randint(min_coord_max, max_coord_max) | ||||
|                 length = coord_max - coord_min | ||||
| @ -733,13 +733,32 @@ class GridCreationState(object): | ||||
|                 return solved_state | ||||
|         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 | ||||
|         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 | ||||
|             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: | ||||
|                 continue | ||||
|             if len(conflicts) == 0: | ||||
| @ -752,8 +771,8 @@ class GridCreationState(object): | ||||
|                 if solved_state is not None: | ||||
|                     state = solved_state | ||||
|  | ||||
|         logging.info("finished after %s iterations, with a density of %s", str( | ||||
|             i), str(state.get_density())) | ||||
|         logging.info("finished after %s iterations, with a density of %s (desired density: %s)", str( | ||||
|             i), str(state.get_density()), str(target_density)) | ||||
|         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) | ||||
|  | ||||
|     final_state = base_grid.fill_grid(target_density=target_density, | ||||
|                                       inner_retries=7, | ||||
|                                       conflict_solver_depth=20, | ||||
|                                       min_length=2, | ||||
|                                       max_iterations=max(75 * (w+h)/2, 1000)) | ||||
|                                       inner_retries=10, | ||||
|                                       conflict_solver_depth=10, | ||||
|                                       min_length=3, | ||||
|                                       max_length=int(min(w,h) * 0.6), | ||||
|                                       max_iterations=5000) | ||||
|  | ||||
|     # generate word hints | ||||
|  | ||||
| @ -849,6 +869,8 @@ def create_word_grid(w: int, | ||||
|  | ||||
|         if aborted: | ||||
|             continue | ||||
|          | ||||
|         logging.info("solution word: %s", str(random_word)) | ||||
|  | ||||
|         solution_word_locations = solution | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user