add difficulty parameter
This commit is contained in:
		| @ -2,6 +2,7 @@ import enum | ||||
| import json | ||||
| import logging | ||||
| import numpy as np | ||||
| from numpy.lib.function_base import diff | ||||
|  | ||||
| from . import crossword_generator | ||||
|  | ||||
| @ -105,10 +106,11 @@ class LetterField(Field): | ||||
|  | ||||
|  | ||||
| class Grid(object): | ||||
|     def __init__(self, width: int, height: int, lang_code: str, density=0.55): | ||||
|     def __init__(self, width: int, height: int, lang_code: str, density=0.55, difficulty: int = 0): | ||||
|         self._width = width | ||||
|         self._height = height | ||||
|         self._lang_code = lang_code | ||||
|         self._difficulty = difficulty | ||||
|         self._density = density | ||||
|         self._grid = [] | ||||
|         self._solution_locations = None | ||||
| @ -213,10 +215,11 @@ class Grid(object): | ||||
|         return status_update | ||||
|  | ||||
|     def check_and_reveal_word(self, x: int, y: int): | ||||
|         grid_update = self.check_and_reveal_horizontal(x, y) + self.check_and_reveal_vertical(x, y) | ||||
|         grid_update = self.check_and_reveal_horizontal( | ||||
|             x, y) + self.check_and_reveal_vertical(x, y) | ||||
|  | ||||
|         # check also the solution locations | ||||
|          | ||||
|  | ||||
|         is_solution_cell = False | ||||
|         for location in self._solution_locations: | ||||
|             ly = location[0] | ||||
| @ -228,10 +231,10 @@ class Grid(object): | ||||
|             if cell.get_user_content() != cell.get_content(): | ||||
|                 # not solved, nothing to do, return only grid update | ||||
|                 return grid_update | ||||
|          | ||||
|  | ||||
|         if not is_solution_cell: | ||||
|             return grid_update | ||||
|          | ||||
|  | ||||
|         solution_updates = [] | ||||
|         for location in self._solution_locations: | ||||
|             ly = location[0] | ||||
| @ -267,7 +270,7 @@ class Grid(object): | ||||
|  | ||||
|         cell.user_input(letter.lower()) | ||||
|  | ||||
|         revealed_changes = self.check_and_reveal_word(x,y) | ||||
|         revealed_changes = self.check_and_reveal_word(x, y) | ||||
|  | ||||
|         if len(revealed_changes) == 0: | ||||
|             return [{ | ||||
| @ -282,8 +285,11 @@ class Grid(object): | ||||
|         return self._solution_locations | ||||
|  | ||||
|     def _build_grid(self): | ||||
|         raw_grid, word_infos, solution_locations = crossword_generator.create_word_grid( | ||||
|             self._width - 1, self._height - 1, lang_code=self._lang_code, target_density=self._density) | ||||
|         raw_grid, word_infos, solution_locations = crossword_generator.create_word_grid(self._width - 1, | ||||
|                                                                                         self._height - 1, | ||||
|                                                                                         lang_code=self._lang_code, | ||||
|                                                                                         target_density=self._density, | ||||
|                                                                                         difficulty=self._difficulty) | ||||
|  | ||||
|         self._solution_locations = solution_locations | ||||
|         # fix solution locations offsets | ||||
| @ -334,10 +340,11 @@ class Grid(object): | ||||
|  | ||||
|  | ||||
| class Crossword(object): | ||||
|     def __init__(self, width: int, height: int, lang_code: str = "en"): | ||||
|     def __init__(self, width: int, height: int, lang_code: str = "en", difficulty: int = 0): | ||||
|         self._width = width | ||||
|         self._height = height | ||||
|         self._grid = Grid(width, height, lang_code) | ||||
|         self._difficulty = difficulty | ||||
|         self._grid = Grid(width, height, lang_code, difficulty=difficulty) | ||||
|  | ||||
|     def serialize(self): | ||||
|         return { | ||||
|  | ||||
| @ -31,7 +31,7 @@ class CrosswordConnection(json_websockets.JsonWebsocketConnection): | ||||
|  | ||||
|         self._session = None | ||||
|  | ||||
|     async def send_crossword(self, sessionId: str, lang: str = "en"): | ||||
|     async def send_crossword(self, sessionId: str, lang: str = "en", difficulty: int = 0): | ||||
|         if sessionId not in CrosswordConnection.sessions: | ||||
|             await self.send_error(msg="unknown session") | ||||
|             return | ||||
| @ -45,7 +45,7 @@ class CrosswordConnection(json_websockets.JsonWebsocketConnection): | ||||
|             await self.send_error(msg="you are not registered to given session") | ||||
|             return | ||||
|  | ||||
|         crossword = sess.get_crossword(lang=lang) | ||||
|         crossword = sess.get_crossword(lang=lang, difficulty=difficulty) | ||||
|         await self.send({ | ||||
|             'type': 'crossword', | ||||
|             'crossword': crossword.serialize() | ||||
| @ -70,7 +70,7 @@ class CrosswordConnection(json_websockets.JsonWebsocketConnection): | ||||
|                 'updates': update_message | ||||
|             }) | ||||
|  | ||||
|     async def register(self, sessionId: str = None, lang: str = "en"): | ||||
|     async def register(self, sessionId: str = None, lang: str = "en", difficulty: int = 0): | ||||
|  | ||||
|         if sessionId is None: | ||||
|  | ||||
| @ -85,7 +85,7 @@ class CrosswordConnection(json_websockets.JsonWebsocketConnection): | ||||
|             await self.send_error("unknown session id") | ||||
|  | ||||
|             # register with new id: | ||||
|             await self.register(lang=lang) | ||||
|             await self.register(lang=lang, difficulty=difficulty) | ||||
|             return | ||||
|  | ||||
|         sess = CrosswordConnection.sessions[sessionId] | ||||
| @ -98,7 +98,7 @@ class CrosswordConnection(json_websockets.JsonWebsocketConnection): | ||||
|             'sessionId': sessionId | ||||
|         }) | ||||
|  | ||||
|         await self.send_crossword(sessionId, lang=lang) | ||||
|         await self.send_crossword(sessionId, lang=lang, difficulty=difficulty) | ||||
|  | ||||
|         # clean up old session | ||||
|         CrosswordConnection.clean_sessions() | ||||
| @ -119,11 +119,14 @@ class CrosswordConnection(json_websockets.JsonWebsocketConnection): | ||||
|         if message['type'] == 'register': | ||||
|             sessionId = None | ||||
|             lang = "en" | ||||
|             difficulty = 0 | ||||
|             if 'sessionId' in message: | ||||
|                 sessionId = message['sessionId'] | ||||
|             if "lang" in message: | ||||
|                 lang = message['lang'] | ||||
|             await self.register(sessionId=sessionId, lang=lang) | ||||
|             if "difficulty" in message: | ||||
|                 difficulty = message["difficulty"] | ||||
|             await self.register(sessionId=sessionId, lang=lang, difficulty=difficulty) | ||||
|             return | ||||
|  | ||||
|         if self._session is None: | ||||
|  | ||||
| @ -6,6 +6,24 @@ import pathlib | ||||
| import logging | ||||
|  | ||||
|  | ||||
| def get_difficulty_threshold(lang: str, difficulty: int): | ||||
|     return get_difficulty_threshold.thresholds[lang][difficulty] | ||||
|  | ||||
|  | ||||
| get_difficulty_threshold.thresholds = { | ||||
|     'de': { | ||||
|         0: 12, | ||||
|         1: 6, | ||||
|         2: 0 | ||||
|     }, | ||||
|     'en': { | ||||
|         0: 200, | ||||
|         1: 100, | ||||
|         2: 10 | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| def get_database(lang: str = "en") -> dict: | ||||
|     if lang not in get_database._dbs: | ||||
|         current_folder = pathlib.Path(__file__).parents[0] | ||||
| @ -116,8 +134,15 @@ class WordInfo(object): | ||||
|         return self._is_vertical | ||||
|  | ||||
|  | ||||
| def create_word_grid(w: int, h: int, lang_code: str = "en", target_density=0.5): | ||||
|     logging.info("generate new crossword") | ||||
| def create_word_grid(w: int, h: int, lang_code: str = "en", target_density: float = 0.5, difficulty: int = 0): | ||||
|     logging.info("generate new crossword with params: w:%s h:%s lang:%s density:%s difficulty:%s", | ||||
|                  str(w), | ||||
|                  str(h), | ||||
|                  lang_code, | ||||
|                  str(target_density), | ||||
|                  str(difficulty)) | ||||
|  | ||||
|     t_num_translations = get_difficulty_threshold(lang = lang_code, difficulty = difficulty) | ||||
|  | ||||
|     database = get_database(lang=lang_code) | ||||
|     list_words = list(database.keys()) | ||||
| @ -145,9 +170,13 @@ def create_word_grid(w: int, h: int, lang_code: str = "en", target_density=0.5): | ||||
|         index = random.randint(0, n_words-1) | ||||
|         word = list_words[index][:] | ||||
|  | ||||
|         while len(word) >= max_length or not word.isalnum() or len(word) <= min_length: | ||||
|         num_translations = database[word]['num_translations'] | ||||
|         t = t_num_translations | ||||
|  | ||||
|         while len(word) >= max_length or not word.isalnum() or len(word) <= min_length or num_translations < t: | ||||
|             index = random.randint(0, n_words-1) | ||||
|             word = list_words[index][:] | ||||
|             num_translations = database[word]['num_translations'] | ||||
|  | ||||
|         return word | ||||
|  | ||||
|  | ||||
| @ -4,13 +4,13 @@ from . import crossword | ||||
|  | ||||
|  | ||||
| class Session(object): | ||||
|     def __init__(self, days_to_expire:int = 2) -> None: | ||||
|     def __init__(self, days_to_expire: int = 2) -> None: | ||||
|         self.crossword = None | ||||
|         self.datetime_created = dt.datetime.utcnow() | ||||
|         self.connected_sockets = set() | ||||
|         self.last_touched = self.datetime_created | ||||
|         self.days_to_expire = 2 | ||||
|      | ||||
|  | ||||
|     def cleanup(self): | ||||
|         sockets_to_remove = [] | ||||
|         for socket in self.connected_sockets: | ||||
| @ -22,7 +22,7 @@ class Session(object): | ||||
|  | ||||
|     def connect_socket(self, | ||||
|                        websocket: json_websockets.JsonWebsocketConnection) -> None: | ||||
|          | ||||
|  | ||||
|         self.cleanup() | ||||
|         self.connected_sockets.add(websocket) | ||||
|  | ||||
| @ -38,20 +38,21 @@ class Session(object): | ||||
|     def get_datetime_created(self) -> dt.datetime: | ||||
|         return self.datetime_created | ||||
|  | ||||
|     def create_crossword(self, width: int = 20, height: int = 20, lang: str = "en"): | ||||
|     def create_crossword(self, width: int = 20, height: int = 20, lang: str = "en", difficulty: int = 0): | ||||
|         self.crossword = crossword.Crossword(width=width, | ||||
|                                              height=height, | ||||
|                                              lang_code=lang) | ||||
|                                              lang_code=lang, | ||||
|                                              difficulty=difficulty) | ||||
|  | ||||
|     def get_crossword(self, lang: str = "en") -> crossword.Crossword: | ||||
|     def get_crossword(self, lang: str = "en", difficulty: int = 0) -> crossword.Crossword: | ||||
|         if self.crossword is None: | ||||
|             self.create_crossword(lang = lang) | ||||
|          | ||||
|             self.create_crossword(lang=lang, difficulty=difficulty) | ||||
|  | ||||
|         return self.crossword | ||||
|      | ||||
|  | ||||
|     def touch(self): | ||||
|         self.last_touched = dt.datetime.utcnow() | ||||
|      | ||||
|  | ||||
|     def is_expired(self): | ||||
|         self.cleanup() | ||||
|         if len(self.connected_sockets) > 0: | ||||
| @ -59,6 +60,5 @@ class Session(object): | ||||
|         now = dt.datetime.utcnow() | ||||
|         if (now - self.last_touched).days > self.days_to_expire: | ||||
|             return True | ||||
|          | ||||
|         return False | ||||
|  | ||||
|         return False | ||||
|  | ||||
		Reference in New Issue
	
	Block a user