def test_check_answers_locked(self): '''Verify that we can check answers even when the solution is locked ''' p1 = puz.read('testfiles/nyt_locked.puz') p2 = puz.read('testfiles/nyt_locked.puz') p1.unlock_solution(7844) self.assertTrue(p2.is_solution_locked()) self.assertTrue(p2.check_answers(p1.solution))
def testCheckAnswersLocked(self): '''Verify that we can check answers even when the solution is locked ''' p1 = puz.read('testfiles/nyt_locked.puz') p2 = puz.read('testfiles/nyt_locked.puz') p1.unlock_solution(7844) self.assertTrue(p2.is_solution_locked()) self.assertTrue(p2.check_answers(p1.solution))
def test_puzzle_type(self): self.assertNotEqual( puz.read('testfiles/washpost.puz').puzzletype, puz.PuzzleType.Diagramless) self.assertNotEqual( puz.read('testfiles/nyt_locked.puz').puzzletype, puz.PuzzleType.Diagramless) self.assertEqual( puz.read('testfiles/nyt_diagramless.puz').puzzletype, puz.PuzzleType.Diagramless)
def testPuzzleType(self): self.assertFalse( puz.read('testfiles/washpost.puz').puzzletype == puz.PuzzleType.Diagramless) self.assertFalse( puz.read('testfiles/nyt_locked.puz').puzzletype == puz.PuzzleType.Diagramless) self.assertTrue( puz.read('testfiles/nyt_diagramless.puz').puzzletype == puz.PuzzleType.Diagramless)
def testMarkup(self): p = puz.read('testfiles/nyt_rebus_with_notes_and_shape.puz') self.assertTrue(p.has_markup()) m = p.markup() self.assertTrue(all(puz.GridMarkup.Circled == m.markup[i] for i in m.get_markup_squares())) # trigger save p.tostring() p = puz.read('testfiles/washpost.puz') self.assertFalse(p.has_markup()) m = p.markup() self.assertFalse(m.has_markup()) # trigger save p.tostring()
def test_to_ipuz_only_include_ipuz_specific_data(self): puz_object = puz.read('fixtures/puz/chronicle_20140815.puz') puzzle = crossword.from_puz(puz_object) ipuz_dict = crossword.to_ipuz(puzzle) self.assertNotIn('puzzletype', ipuz_dict) self.assertNotIn('fileversion', ipuz_dict) self.assertNotIn('extensions', ipuz_dict)
def get_clues(filename): p = puz.read(filename) # check if has a solution, otherwise skip if p.solution_state > 0: return [] solution = p.solution width = p.width numbering = p.clue_numbering() clues, answers, clue_answers = [], [], [] for elem in numbering.across: cell, length, clue = elem['cell'], elem['len'], elem['clue'].lower() answer = ''.join([solution[cell + i] for i in range(length)]).lower() clues.append(clue) answers.append(answer) clue_answers.append(answer + JOIN_STRING + clue) for elem in numbering.down: cell, length, clue = elem['cell'], elem['len'], elem['clue'].lower() answer = ''.join([solution[cell + i] for i in range(length)]).lower() clues.append(clue) answers.append(answer) clue_answers.append(answer + JOIN_STRING + clue) return pd.DataFrame(data={'clue': clues, 'answer': answers, 'merged': clue_answers})
def read_puzzle(board_name): try: p = puz.read(filename_from_board(board_name)) except FileNotFoundError: return None title = p.title numbering = p.clue_numbering() cells = dict() across = [] for clue in numbering.across: across.append([clue["num"], clue["clue"]]) cell = clue["cell"] cells[clue["num"]] = [cell // p.width, cell % p.width] down = [] for clue in numbering.down: down.append([clue["num"], clue["clue"]]) cell = clue["cell"] cells[clue["num"]] = [cell // p.width, cell % p.width] cells_array = [[cells[key], key] for key in cells.keys()] return { "title": title, "across": across, "down": down, "nums": cells_array, "solutions": p.solution, "dims": [p.height, p.width] }
def main(argv): if len(argv) <= 2: usage() command = argv[1] if command == 'extract': if len(argv) != 3: usage() p = puz.read(argv[2]) for line in clue_output(p): print(line) elif command == 'inject': if len(argv) != 4: usage() p = puz.read(argv[2]) with open(argv[3]) as f: p.clues = [c for i, j, c in sorted(read_clues(f))] sys.stdout.buffer.write(p.tobytes()) else: usage()
def test_markup(self): p = puz.read('testfiles/nyt_rebus_with_notes_and_shape.puz') self.assertTrue(p.has_markup()) m = p.markup() self.assertTrue( all(puz.GridMarkup.Circled == m.markup[i] for i in m.get_markup_squares())) # trigger save p.tobytes() p = puz.read('testfiles/washpost.puz') self.assertFalse(p.has_markup()) m = p.markup() self.assertFalse(m.has_markup()) # trigger save p.tobytes()
def test_read_puz_locked_puzzle(self): puz_object = puz.read('fixtures/puz/nyt_locked.puz') puzzle = crossword.from_puz(puz_object) for x, y in puzzle.cells: self.assertEqual(puzzle[x, y].cell, None) self.assertEqual(puzzle[0, 0].solution, 'B') self.assertEqual(puzzle[14, 14].solution, 'N')
def save_model(self, request, obj, form, change): # Create new object super(ProjectAdmin, self).save_model(request, obj, form, change) # Create constant grid preview if ("grid_file" in form.changed_data and path.splitext(str(obj.grid_file))[1] == ".puz"): # Read puzzle p = puz.read(settings.MEDIA_ROOT + "/" + str(obj.grid_file)) # Init image with the right size img = Image.new("RGB", (CELL_SIZE * p.width, CELL_SIZE * p.height), color="white") # Draw on image d = ImageDraw.Draw(img) print(p.width, p.height) for i in range(p.width): for j in range(p.height): cell = p.solution[j * p.width + i] if cell == ".": d.rectangle( [ CELL_SIZE * i, CELL_SIZE * j, CELL_SIZE * (i + 1) - 1, CELL_SIZE * (j + 1) - 1, ], fill="black", ) # Save image img_path = f"/preview/{obj.pk}.png" img.save(settings.MEDIA_ROOT + img_path)
def create_puzzle(date): path_name = "puzs/" + date + ".puz" if not os.path.isfile(path_name): save_puzzle(date) p = puz.read(path_name) return p
def __init__(self, address, puzzle): """Magic method to initialize a crossword server.""" self.address = address self.messages = queue.Queue() self.handlers = [] self.epoch = time.time() self.history = [] self.ownership = {} self.active = True self.data = SERVER_DATA.copy() self.puzzle = puz.read(puzzle) # For testing # puz.read self.puzzle.fill = list(self.puzzle.fill) self.puzzle.file = puzzle self.data["puzzle-author"] = self.puzzle.author self.data["puzzle-width"] = self.puzzle.width self.data["puzzle-height"] = self.puzzle.height self.data["puzzle-cells"] = self.puzzle.fill.count(LETTER) self.data["puzzle-words"] = len("".join(self.puzzle.fill).split(EMPTY)) self.numbering = self.puzzle.clue_numbering() for clue in self.numbering.across: clue.update({"dir": ACROSS}) for clue in self.numbering.down: clue.update({"dir": DOWN}) self.board = Board(self.puzzle, self.numbering) logging.log(INFO, "%s initialized", repr(self))
def test_read_and_write_round_trip(self): puz_object = puz.read('fixtures/puz/chronicle_20140815.puz') puzzle = crossword.from_puz(puz_object) new_puz_object = crossword.to_puz(puzzle) for attr in dir(puz_object): if not callable(getattr(puz_object, attr)): self.assertEqual(getattr(puz_object, attr), getattr(new_puz_object, attr))
def testUnlock(self): p = puz.read('testfiles/nyt_locked.puz') self.assertTrue(p.is_solution_locked()) self.assertFalse(p.unlock_solution(1234)) self.assertTrue(p.is_solution_locked()) # still locked self.assertTrue(p.unlock_solution(7844)) self.assertFalse(p.is_solution_locked()) # unlocked! self.assertTrue('LAKEONTARIO' in p.solution)
def testUnlockRelock(self): orig = file('testfiles/nyt_locked.puz', 'rb').read() p = puz.read('testfiles/nyt_locked.puz') self.assertTrue(p.is_solution_locked()) self.assertTrue(p.unlock_solution(7844)) p.lock_solution(7844) new = p.tostring() self.assertEqual(orig, new, 'nyt_locked.puz dit not found-trip')
def test_unlock_relock(self): with open('testfiles/nyt_locked.puz', 'rb') as fp: orig = fp.read() p = puz.read('testfiles/nyt_locked.puz') self.assertTrue(p.is_solution_locked()) self.assertTrue(p.unlock_solution(7844)) p.lock_solution(7844) new = p.tobytes() self.assertEqual(orig, new, 'nyt_locked.puz did not round-trip')
def test_unlock(self): p = puz.read('testfiles/nyt_locked.puz') self.assertTrue(p.is_solution_locked()) self.assertFalse(p.unlock_solution(1234)) self.assertTrue(p.is_solution_locked()) # still locked self.assertTrue(p.unlock_solution(7844)) self.assertFalse(p.is_solution_locked()) # unlocked! # We don't use assertIn for compatibility with Python 2.6 self.assertTrue('LAKEONTARIO' in p.solution)
def test_all_fixtures(self): for f in glob.glob('../puzfiles/*.puz'): puz_obj = puz.read(f) loaded_obj = crossword.to_puz(crossword.from_puz(puz_obj)) for attr in dir(puz_obj): if not callable(getattr(puz_obj, attr)): eq = getattr(puz_obj, attr) == getattr(loaded_obj, attr) if not eq: print(attr, eq)
def test_save_empty_puzzle(self): ''' confirm an empty Puzzle() can be saved to a file ''' p = puz.Puzzle() with tempfile.NamedTemporaryFile(suffix='.puz') as tmp: p.save(tmp.name) p2 = puz.read(tmp.name) self.assertEqual(p.puzzletype, p2.puzzletype) self.assertEqual(p.version, p2.version) self.assertEqual(p.scrambled_cksum, p2.scrambled_cksum)
def test_read_puz_to_crossword(self): puz_object = puz.read('fixtures/puz/chronicle_20140815.puz') puzzle = crossword.from_puz(puz_object) self.assertEqual(puzzle.meta.title, 'Que Pasa? - August 15, 2014') self.assertEqual(puzzle.meta.creator, 'by Ian Livengood / Edited by Brad Wilber ') self.assertEqual(puzzle.block, '.') self.assertEqual(puzzle.clues.across[67], 'Jupiter, but not Zeus') self.assertEqual(puzzle.clues.down[60], 'Cadenza automaker')
def main(): parser = argparse.ArgumentParser() parser.add_argument('PUZFILE', type=str, help='Across lite .puz file') parser.add_argument('--output', '-o', type=str, help='Output .txt path (default: replace ".puz" with %r)' % DEFAULT_SUFFIX) args = parser.parse_args() puzzle = puz.read(args.PUZFILE) default_output = '{}{}'.format(os.path.splitext(args.PUZFILE)[0], DEFAULT_SUFFIX) write_obscured(args.output or default_output, puzzle)
def load_puzzle(self, puzzle): """Load a puzzle to the window.""" self.puzzle = puz.read(puzzle) # puz.read self.puzzle.fill = list(self.puzzle.fill) self.numbering = self.puzzle.clue_numbering() for clue in self.numbering.across: clue.update({"dir": ACROSS}) for clue in self.numbering.down: clue.update({"dir": DOWN}) self.board = Board(self.puzzle, self.numbering) logging.log(DEBUG, "%s loaded puzzle", repr(self))
def test_read_and_write_round_trip(self): puz_object = puz.read('fixtures/puz/chronicle_20140815.puz') puzzle = crossword.from_puz(puz_object) new_puz_object = crossword.to_puz(puzzle) for attr in dir(puz_object): if not callable(getattr(puz_object, attr)): self.assertEqual( getattr(puz_object, attr), getattr(new_puz_object, attr) )
def testRebus(self): p = puz.read('testfiles/nyt_rebus_with_notes_and_shape.puz') self.assertTrue(p.has_rebus()) r = p.rebus() self.assertTrue(r.has_rebus()) self.assertEqual(3, len(r.get_rebus_squares())) self.assertTrue(all(r.is_rebus_square(i) for i in r.get_rebus_squares())) self.assertTrue(all('STAR' == r.get_rebus_solution(i) for i in r.get_rebus_squares())) self.assertTrue(None == r.get_rebus_solution(100)) # trigger save p.tostring()
def clues2pandas(fname): p = puz.read(fname) puzNumber = os.path.splitext(os.path.basename(fname))[0] across = p.clue_numbering().across down = p.clue_numbering().down ret = [] date = title2date(p.title) try: year = date.year month = date.month day = date.day day_name = date.strftime('%A') except: year = month = day = day_name = 0 for clue in across: row = {'puzzle_number': puzNumber, 'puzzle_date': date, 'puzzle_year': year, 'puzzle_month': month, 'puzzle_day': day, 'puzzle_day_name': day_name, 'clue_number': clue['num'], 'clue_is_across': True, 'is_culture_clue': is_culture_clue(clue['clue']), 'is_pun_clue': is_pun_clue(clue['clue']), 'clue_text': clue['clue'], 'clue_text_clean': clean_text(clue['clue']), 'answer_length': clue['len'], } ret.append(row) for clue in down: row = {'puzzle_number': puzNumber, 'puzzle_date': date, 'puzzle_year': year, 'puzzle_month': month, 'puzzle_day': day, 'puzzle_day_name': day_name, 'clue_number': clue['num'], 'clue_is_across': False, 'is_culture_clue': is_culture_clue(clue['clue']), 'is_pun_clue': is_pun_clue(clue['clue']), 'clue_text': clue['clue'], 'clue_text_clean': clean_text(clue['clue']), 'answer_length': clue['len'], } ret.append(row) return(pd.DataFrame.from_dict(ret))
def add_clues_down(clues, date): path_name = "puzs/" + date + ".puz" if not os.path.isfile(path_name): save_puzzle(date) p = puz.read(path_name) numbering = p.clue_numbering() for clue in numbering.down: answer = ''.join(p.solution[clue['cell'] + i] for i in range(clue['len'])) clues.append(Clue(clue['num'], Clue.DOWN, clue['clue'], answer)) return clues
def runTest(self): try: orig = file(self.filename, 'rb').read() p = puz.read(self.filename) if (p.puzzletype == puz.PuzzleType.Normal): clues = p.clue_numbering() # smoke test the clue numbering while we're at it self.assertEqual(len(p.clues), len(clues.across) + len(clues.down), 'failed in %s' % self.filename) # this is the roundtrip new = p.tostring() self.assertEqual(orig, new, '%s did not round-trip' % self.filename) except puz.PuzzleFormatError: self.assertTrue(False, '%s threw PuzzleFormatError: %s' % (self.filename, sys.exc_info()[1].message))
def test_read_puz_to_crossword(self): puz_object = puz.read('fixtures/puz/chronicle_20140815.puz') puzzle = crossword.from_puz(puz_object) self.assertEqual( puzzle.meta.title, 'Que Pasa? - August 15, 2014' ) self.assertEqual( puzzle.meta.creator, 'by Ian Livengood / Edited by Brad Wilber ' ) self.assertEqual(puzzle.block, '.') self.assertEqual(puzzle.clues.across[67], 'Jupiter, but not Zeus') self.assertEqual(puzzle.clues.down[60], 'Cadenza automaker')
def test_rebus(self): p = puz.read('testfiles/nyt_rebus_with_notes_and_shape.puz') self.assertTrue(p.has_rebus()) r = p.rebus() self.assertTrue(r.has_rebus()) self.assertEqual(3, len(r.get_rebus_squares())) self.assertTrue( all(r.is_rebus_square(i) for i in r.get_rebus_squares())) self.assertTrue( all('STAR' == r.get_rebus_solution(i) for i in r.get_rebus_squares())) self.assertEqual(None, r.get_rebus_solution(100)) # trigger save p.tobytes()
def load(self, puz_file): puzzle = puz.read(puz_file) clues = puzzle.clue_numbering() solution = puzzle.solution self.rows = [] while len(solution) >= puzzle.width: row = solution[:puzzle.width] self.rows.append(tokenize_row(row)) solution = solution[puzzle.width:] self.clues_across = [[d['num'], d['clue']] for d in clues.across] self.clues_down = [[d['num'], d['clue']] for d in clues.down] self.author = puzzle.author self.width = puzzle.width self.height = puzzle.height
def runTest(self): try: with open(self.filename, 'rb') as fp_filename: orig = fp_filename.read() p = puz.read(self.filename) if (p.puzzletype == puz.PuzzleType.Normal): clues = p.clue_numbering() # smoke test the clue numbering while we're at it self.assertEqual(len(p.clues), len(clues.across) + len(clues.down), 'failed in %s' % self.filename) # this is the roundtrip new = p.tobytes() self.assertEqual(orig, new, '%s did not round-trip' % self.filename) except puz.PuzzleFormatError: args = (self.filename, sys.exc_info()[1].message) self.assertTrue(False, '%s threw PuzzleFormatError: %s' % args)
def test_save_small_puzzle(self): ''' an example of creating a small 3x3 puzzle from scratch and writing to a file ''' p = puz.Puzzle() with tempfile.NamedTemporaryFile(suffix='.puz') as tmp: p.title = 'Test Puzzle' p.author = 'Alex' p.height = 3 p.width = 3 p.solution = 'A' * 9 p.clues = ['clue'] * 6 p.fill = '-' * 9 p.save(tmp.name) p2 = puz.read(tmp.name) self.assertEqual(p.title, p2.title) self.assertEqual(p.author, p2.author) self.assertEqual(p.solution, p2.solution) self.assertEqual(p.clues, p2.clues) self.assertEqual(p.fill, p2.fill)
def from_puz(cls, filename: str) -> Crossword: """Creates a Crossword object from a .puz file. Args: filename (str): The path of the input .puz file. Returns: Crossword: A Crossword object. """ puz_obj = puz.read(filename) grid = np.reshape( list(puz_obj.solution), (puz_obj.height, puz_obj.width), ) xw = cls(grid=grid) for cn in puz_obj.clue_numbering().across: xw[ACROSS, cn["num"]].clue = cn["clue"] for cn in puz_obj.clue_numbering().down: xw[DOWN, cn["num"]].clue = cn["clue"] return xw
def downs(puzzle=pzzle): p = puz.read(puzzle) n = p.clue_numbering() d = defaultdict(int) #this next chunk gets an ordering for the clues #in p.clues, they go 1a, 1d, 2d, 3d, 4d, 5a, 5d, etc. for clue in n.across: d[clue["num"]] += 1 for clue in n.down: d[clue["num"]] += 1 last_clue = n.across[-1]["num"] #this chunk is to identify all of the across clues so they can be replaced #1a is always first, hence the initial conditions for clue_num clue_num = {1: 0} for i in range(2, last_clue + 1): clue_num[i] = clue_num[i - 1] + d[i - 1] #this does the replacing. clue_num takes the number of the clue and #returns the position of the clue in the overall list (p.clues) for clue in n.across: j = clue["num"] p.clues[clue_num[j]] = "-" p.save("downss.puz")
def load_puzzle(self, puzzle): """Load a puzzle to the window.""" self.puzzle = puz.read(puzzle) self.puzzle.fill = list(self.puzzle.fill) self.puzzle.numbering = self.puzzle.clue_numbering() self.title.config(text=self.puzzle.title.lstrip("NY Times, ")) self.author.config(text=self.puzzle.author) self.game_board.config(width=config["board"]["cell-size"]*self.puzzle.width + CANVAS_SPARE, height=config["board"]["cell-size"]*self.puzzle.height + CANVAS_SPARE) self.game_board.create_rectangle( CANVAS_OFFSET, CANVAS_OFFSET, config["board"]["cell-size"]*self.puzzle.width + CANVAS_OFFSET, config["board"]["cell-size"]*self.puzzle.height + CANVAS_OFFSET) for clue in self.puzzle.numbering.across: clue.update({"dir": ACROSS}) for clue in self.puzzle.numbering.down: clue.update({"dir": DOWN}) self.board = CrosswordBoard(self.puzzle) numbers = {w["cell"]: w["num"] for w in self.puzzle.numbering.across} numbers.update({w["cell"]: w["num"] for w in self.puzzle.numbering.down}) for y in range(self.puzzle.height): for x in range(self.puzzle.width): cell = CrosswordCell( self.game_board, self.puzzle.fill[position_to_index(x, y, self.puzzle.width)], "black", config["board"]["deselected-fill"], CANVAS_OFFSET + x*config["board"]["cell-size"], CANVAS_OFFSET + y*config["board"]["cell-size"], number=numbers.get(y*self.puzzle.height + x, "")) self.board[x, y] = cell cell.draw() self.board.generate_words() logging.log(DEBUG, "%s populated old cells", repr(self)) logging.log(DEBUG, "%s drew old puzzle", repr(self)) logging.log(DEBUG, "%s loaded puzzle", repr(self)) self.epoch = 0 logging.log(DEBUG, "%s reset epoch", repr(self)) self.pause()
def __init__(self, path): self.path = path self.puzfile = puz.read(path) self.title = self.puzfile.title.strip() self.author = self.puzfile.author.strip() self.fill = self.puzfile.fill filled = [char for char in self.fill if char.isalpha()] total = [char for char in self.fill if char != '.'] self.progress = len(filled) / len(total) if b'LTIM' in self.puzfile.extensions: tb = self.puzfile.extensions[b'LTIM'] self.timer = int(tb.decode().split(',')[0]) else: self.timer = None try: self.line_width = os.get_terminal_size().columns except: self.line_width = 80
#!/usr/bin/env python from __future__ import print_function import puz import json import sys p = puz.read(sys.argv[1]) r = p.rebus() def get_sol(i, j): sq = i * p.width + j if r.has_rebus() and r.is_rebus_square(sq): return r.get_rebus_solution(sq) else: return p.solution[sq] def get_circles(): circles = [] if p.has_markup(): m = p.markup() for square in m.get_markup_squares(): if m.markup[square] == puz.GridMarkup.Circled: circles.append(square) return circles grid = [[get_sol(i, j) for j in range(p.width)] for i in range(p.height)] circles = get_circles()
'de': 'german', 'is': 'icelandic', 'id': 'indonesian', 'it': 'italian', 'ms': 'malay', 'no': 'norwegian', 'pt': 'portuguese', 'es': 'spanish', 'sw': 'swahili', 'sv': 'swedish' } # READING PUZ FILE filename = sys.argv[1] p = puz.read(filename + ".puz") old_clues = p.clues new_clues = [] # TRANSLATING THAT BAD BOY from multiprocessing.dummy import Pool as ThreadPool import time pool = ThreadPool(20) # Threads def request(text): lang = "fr" t = google_translator(timeout=5) # TRANSLATES TO RANDOM LANGUAGES FOUR TIMES
# Insert the puzzle into the square image r_start = (dim - sh[0]) // 2 r_stop = r_start + sh[0] c_start = (dim - sh[1]) // 2 c_stop = c_start + sh[1] sq[r_start:r_stop, c_start:c_stop] = p return sq if __name__ == "__main__": FILE_PATH = sys.argv[1] PUZ_FILE = "puz_files/other-puzzles/{}.puz".format(FILE_PATH) IMAGE_FILE = "puzzle_images/{}.png".format(FILE_PATH) PUZZLE = puz.read(PUZ_FILE) CIRCLED_SQUARES = PUZZLE.markup().get_markup_squares() # Assign sizes based on the puz file SIZES["ROWS"] = PUZZLE.height SIZES["COLS"] = PUZZLE.width SIZES["PUZZLE_HEIGHT"] = ((SIZES["BORDER"] * 2) + (SIZES["CELL_SIZE"] * SIZES["ROWS"]) + ((SIZES["ROWS"] - 1) * SIZES["GRID_LINE"])) SIZES["PUZZLE_WIDTH"] = ((SIZES["BORDER"] * 2) + (SIZES["CELL_SIZE"] * SIZES["COLS"]) + ((SIZES["COLS"] - 1) * SIZES["GRID_LINE"])) # Compute and save the image p = read_puzzle() raw = draw_puzzle(p)
def read_puzzle(self): """ Reads the puzzle file and returns a puzzle object """ puzzledata = puz.read(self.puzzle.path) return puzzledata
def test_extensions(self): p = puz.read('testfiles/nyt_rebus_with_notes_and_shape.puz') # We don't use assertIn for compatibility with Python 2.6 self.assertTrue(puz.Extensions.Rebus in p.extensions) self.assertTrue(puz.Extensions.RebusSolutions in p.extensions) self.assertTrue(puz.Extensions.Markup in p.extensions)
def testClueNumbering(self): p = puz.read('testfiles/washpost.puz') clues = p.clue_numbering() self.assertEqual(len(p.clues), len(clues.across) + len(clues.down))
def testLockedBit(self): self.assertFalse(puz.read('testfiles/washpost.puz').is_solution_locked()) self.assertTrue(puz.read('testfiles/nyt_locked.puz').is_solution_locked())
def testPuzzleType(self): self.assertFalse(puz.read('testfiles/washpost.puz').puzzletype == puz.PuzzleType.Diagramless) self.assertFalse(puz.read('testfiles/nyt_locked.puz').puzzletype == puz.PuzzleType.Diagramless) self.assertTrue(puz.read('testfiles/nyt_diagramless.puz').puzzletype == puz.PuzzleType.Diagramless)
#! /usr/bin/env python import sys, os sys.path.append(os.path.abspath(os.path.join(os.getcwd(), os.path.pardir))) import puz print "unlocking %s" % sys.argv[1] p = puz.read(sys.argv[1]) if p.locksum == 0: print "puzzle already unlocked" sys.exit(0) locked = [] for i in range(p.width): for j in range(p.height): pos = p.width * j + i char = p.answers[pos:pos+1] if not char == '.': locked.append(char) locked_str = ''.join(locked) counter = 0 key = 1637 while counter < 10000: keystr = "%04d" % key digits = [int(keystr[0:1]),int(keystr[1:2]),int(keystr[2:3]),int(keystr[3:4])] unl = puz.unscramble(locked_str, digits) if puz.data_cksum(unl) == p.locksum and counter > 430: print "counter: %d" % counter break key += 163
def testExtensions(self): p = puz.read('testfiles/nyt_rebus_with_notes_and_shape.puz') self.assertTrue(puz.Extensions.Rebus in p.extensions) self.assertTrue(puz.Extensions.RebusSolutions in p.extensions) self.assertTrue(puz.Extensions.Markup in p.extensions)