def from_ipuz(ipuz_dict): for kind in ipuz_dict['kind']: if not kind.startswith("http://ipuz.org/crossword"): raise CrosswordException known_keys = ( "dimensions", "editor", "author", "date", "notes", "uniqueid", "publisher", "copyright", "title", "block", "empty", "clues", "puzzle", "solution", ) crossword = Crossword(ipuz_dict['dimensions']['width'], ipuz_dict['dimensions']['height']) crossword._format_identifier = Crossword.IPUZ crossword.meta.contributor = ipuz_dict.get('editor') crossword.meta.creator = ipuz_dict.get('author') crossword.meta.date = ipuz_dict.get('date') crossword.meta.description = ipuz_dict.get('notes') crossword.meta.identifier = ipuz_dict.get('uniqueid') crossword.meta.publisher = ipuz_dict.get('publisher') crossword.meta.rights = ipuz_dict.get('copyright') crossword.meta.title = ipuz_dict.get('title') crossword.block = ipuz_dict.get('block') crossword.empty = ipuz_dict.get('empty') for clues in ipuz_dict.get('clues', {}).get('Across', []): crossword.clues.across[clues['number']] = clues['clue'] for clues in ipuz_dict.get('clues', {}).get('Down', []): crossword.clues.down[clues['number']] = clues['clue'] for x, y in crossword.cells: crossword[x, y] = CrosswordCell() for key in ('puzzle', 'solution'): entry = ipuz_dict.get(key) for x, y in crossword.cells: try: crossword[x, y][key] = entry[y][x] except (IndexError, TypeError): crossword[x, y][key] = None for key, value in ipuz_dict.items(): if key not in known_keys: crossword._format[key] = value return crossword
def from_puz(puzzle): known_keys = ( "width", "height", "author", "copyright" "title", "clues", "solution", ) result = Crossword(puzzle.width, puzzle.height) result._format_identifier = Crossword.PUZ result.meta.creator = puzzle.author result.meta.rights = puzzle.copyright result.meta.title = puzzle.title result.block = '.' rows = [] for i in range(0, len(puzzle.solution), puzzle.width): rows.append(puzzle.solution[i:i + puzzle.width]) def is_across(x, y): if result[x, y].solution in ':.': return False start = x == 0 or (0 <= x - 1 and result[x - 1, y].solution in ':.') end = (x + 1 < puzzle.width and result[x + 1, y].solution not in ':.') return start and end def is_down(x, y): if result[x, y].solution in ':.': return False start = y == 0 or (y - 1 >= 0 and result[x, y - 1].solution in ':.') end = (y + 1 < puzzle.height and result[x, y + 1].solution not in ':.') return start and end for y, row in enumerate(rows): for x, cell in enumerate(row): result[x, y].cell = None result[x, y].solution = cell clue_index = 0 number = 0 for y, row in enumerate(rows): for x, cell in enumerate(row): is_xy_across = is_across(x, y) is_xy_down = is_down(x, y) if is_xy_across or is_xy_down: number += 1 if is_xy_across: result.clues.across[number] = puzzle.clues[clue_index] clue_index += 1 if is_xy_down: result.clues.down[number] = puzzle.clues[clue_index] clue_index += 1 for attr in dir(puzzle): if attr in known_keys: continue if attr.startswith('__'): continue if callable(getattr(puzzle, attr)): continue result._format[attr] = getattr(puzzle, attr) return result