Example #1
0
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 number, clue in ipuz_dict.get('clues', {}).get('Across', []):
        crossword.clues.across[number] = clue
    for number, clue in ipuz_dict.get('clues', {}).get('Down', []):
        crossword.clues.down[number] = 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
Example #2
0
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