def __init__( self, t): Puzzle.__init__(self) self._shape = t self._start_position = (0,0) self._finish_position = (t[0]-1, t[1]-1) self._grid = Grid( t) self._allowed_moves = MazePuzzle._DEFAULT_MOVES
def start(self): log.info("Worker started on processor %d %s" % (rank, name)) # First we send all the required partitions to the neighbors and then # receive all the segments and reconstruct a local matrix where the # function will be evaluated. puzzle = Puzzle(self.partition) for lbl, enum in zip(LABELS, ORDERED): self.comm.send(getattr(self.conns, lbl), enum) for lbl, enum in zip(RLABELS, REVERSED): m = self.comm.receive(getattr(self.conns, lbl), enum) if m: puzzle.add_piece(m, enum) start = time.time() puzzle.apply(self.offsets, function) log.info("Worker %d: %.10f seconds to compute the partition" % \ (rank - 1, time.time() - start)) log.info("Sending back the computed sub-partition from %d" % rank) start = time.time() comm.gather(self.partition.matrix, root=0) log.info("Worker %d: %.10f seconds to send back the partition" % \ (rank - 1, time.time() - start)) comm.Barrier()
def getPuzzle(puzList): #Split on each row of input to get rid white spaces and tabs #Append the 3 rows of inputs into a list #forming a nxn matrix puzzle = Puzzle(puzList) puzzle.printPuzzle() return puzzle
def load(self): # init data before loading self.puzzles = [] # Load puzzles puzzles_data = self.data_mgr.get_puzzles_data() for puzzle_data in puzzles_data: puzzle = Puzzle(self.data_mgr) puzzle.load(puzzle_data) self.puzzles.append(puzzle)
def sample(request): ''' This was split off from the below function to bypass the csrf token check on ajax calls, but leave it in place for all other requests. This returns a sample puzzle for development, and for solving once anyway ;) ''' dimension = Dimension([9, 9]) context_dict = {} puzzle = Puzzle(dimension, 'sample', None) context_dict['board'] = puzzle.draw_board() context_dict['fields'] = puzzle.get_input_fields() return render_to_response('main.html', context_dict, context_instance=RequestContext(request))
class PuzzleTestDownloadPluginArchive(unittest.TestCase): def setUp(self): self.p = Puzzle(plugins_dir=join(getcwd(), PATH)) def test_download_archive(self): self.p.load_plugins() url = 'file:///path_to_test_plugin_archive.zip' self.p.download_puzzle_part(url) self.assertEqual(self.p.table.size(), 3) def test_plugins_instalation(self): for id,(key, plugin) in enumerate(self.p.table_items()): self.assertTrue(issubclass(plugin, Plugin))
def main(request, action=None): ''' Process the requests for updating values in the puzzle, and generating new puzzles (coming soon). I hardcoded 9x9, but all code in this program is flexible for any dimension, providing it is a square. So we should be able to handle different puzzle square type games just by writing a new solver. ''' dimension = Dimension([9, 9]) context_dict = {} values = request.POST if is_post(request) else None puzzle = Puzzle(dimension, values, action) context_dict['board'] = puzzle.draw_board() context_dict['fields'] = puzzle.get_input_fields() return render_to_response('main.html', context_dict, context_instance=RequestContext(request))
class PuzzleTestBasic(unittest.TestCase): def setUp(self): self.p = Puzzle(plugins_dir=join(getcwd(), PATH)) def test_creation_puzzle(self): self.assertIsNotNone("Creating instance of Puzzle.", self.p) def test_table_load(self): self.assertIsNotNone("Creating instance of Puzzle.", self.p.table) def test_observer_load(self): self.assertIsNotNone("Creating instance of Puzzle.", self.p.observable) def test_loading_plugins(self): self.p.load_plugins() self.assertEqual(self.p.table.size(), 2) def test_plugins_instalation(self): for id,(key, plugin) in enumerate(self.p.table_items()): self.assertTrue(issubclass(plugin, Plugin))
def __init__ (self, game, event_handler, ID = None, defn = None): self.game = game # add event handlers event_handler.add_event_handlers({ pygame.MOUSEBUTTONDOWN: self._click, pygame.MOUSEBUTTONUP: self._unclick, pygame.MOUSEMOTION: lambda e: setattr(self, 'mouse_moved', True) }) pzl_args = ( eh.MODE_ONDOWN_REPEAT, max(int(conf.MOVE_INITIAL_DELAY * conf.FPS), 1), max(int(conf.MOVE_REPEAT_DELAY * conf.FPS), 1) ) menu_args = ( eh.MODE_ONDOWN_REPEAT, max(int(conf.MENU_INITIAL_DELAY * conf.FPS), 1), max(int(conf.MENU_REPEAT_DELAY * conf.FPS), 1) ) od = eh.MODE_ONDOWN held = eh.MODE_HELD l = conf.KB_LAYOUT event_handler.add_key_handlers([ (conf.KEYS_MOVE_LEFT[l], [(self._move, (0,))]) + pzl_args, (conf.KEYS_MOVE_UP[l], [(self._move, (1,))]) + pzl_args, (conf.KEYS_MOVE_RIGHT[l], [(self._move, (2,))]) + pzl_args, (conf.KEYS_MOVE_DOWN[l], [(self._move, (3,))]) + pzl_args, (conf.KEYS_BACK, self.menu, od), (conf.KEYS_TAB, self.switch_puzzle, od), (conf.KEYS_INSERT, self._insert_cb, od), (conf.KEYS_DEL, self.delete, od), (conf.KEYS_UNDO, self.undo) + menu_args, (conf.KEYS_REDO, self.redo) + menu_args, (conf.KEYS_RESET, self.reset, od) ]) self.event_handler = event_handler # create block/surface selection grid blocks = xrange(conf.MAX_ID + 1) surfaces = xrange(-1, conf.MIN_ID - 1, -1) self._selector_defn = '3 {0}\n{1}\n\n{2}\n{3}'.format( max(len(blocks), len(surfaces)), '\n'.join('{0} 0 {1}'.format(b, i) for i, b in enumerate(blocks)), '\n'.join('{0} 1 {1}'.format(b, i) for i, b in enumerate(blocks)), '\n'.join('{0} 2 {1}'.format(s, i) for i, s in enumerate(surfaces)) ) self.selector = Puzzle(game, self._selector_defn) self.FRAME = conf.FRAME self.load(ID, defn)
def load (self, ID = None, definition = None): """Load a level. Takes ID and definition arguments as in the constructor. """ self.ID = None if ID is None or ID[0] else ID[1] if ID is not None: # get data from file path = conf.LEVEL_DIR_CUSTOM if ID[0] else conf.LEVEL_DIR_MAIN with open(path + ID[1]) as f: definition = f.read() self.puzzle = Puzzle(self.game, definition, True, self.sound) self.players = [b for b in self.puzzle.blocks if b.type == conf.B_PLAYER] # store message and solutions lines = definition.split('\n') msgs = [] solns = [] for line in lines: line = line.strip() for char, val in (('@', msgs), (':', solns)): if line.startswith(char): # add lines (stripped) starting with the character val.append(line[1:].strip()) # won't start with the other one if it starts with this one continue self.msg = msgs[0] if msgs and conf.SHOW_MSG else None self.solutions = solns self._moved = [] self._stored_moves = [] self._winning = False self.won = False self.solving = False self.solving_index = None self._ff = False self.recording = False self.frozen = False self.start_time = time()
def load (self, ID = None, defn = None): """Load a level. load([ID][, defn]) ID: custom level ID. defn: if ID is not given, load a level from this definition; if this is not given, load a blank level. """ if ID is None: if defn is None: # blank grid defn = conf.BLANK_LEVEL self.ID = None else: # get data from file d = conf.LEVEL_DIR_DRAFT if ID[0] == 2 else conf.LEVEL_DIR_CUSTOM with open(d + ID[1]) as f: defn = f.read() self.ID = ID[1] if hasattr(self, 'editor'): self.editor.load(defn) else: self.editor = Puzzle(self.game, defn) self.editor_rect = None self.editor.deselect() self.editor.select((0, 0)) self.selector.deselect() self.selector.select((0, 0), True) self.puzzle = self.editor self.editing = True self.dirty = True self.changes = [] self.state = 0 self.mouse_moved = False self.resizing = False
def getUserPuzzleInput(): #Infinite while loop to keep polling for user input #while input values aren't correct while True: #default puzzle user_input = raw_input("Type \"1\" to use a default puzzle, or \"2\" to enter your own puzzle.\n") if user_input == '1': print "You have chosen the default puzzle.\n" puzzle = Puzzle() puzzle.printPuzzle() return puzzle #user-generated puzzle elif user_input == '2': print "Enter your puzzle, use a zero to represent the blank" #Split on each row of input to get rid white spaces and tabs puzzle_row_1 = raw_input("Enter the first row, use a space or tabs between numbers ") puzzle_row_1 = puzzle_row_1.split() puzzle_row_2 = raw_input("Enter the second row, use a space or tabs between numbers ") puzzle_row_2 = puzzle_row_2.split() puzzle_row_3 = raw_input("Enter the third row, use a space or tabs between numbers ") puzzle_row_3 = puzzle_row_3.split() #Append the 3 rows of inputs into a list #forming a nxn matrix puzzle_list = [] puzzle_list.append(puzzle_row_1) puzzle_list.append(puzzle_row_2) puzzle_list.append(puzzle_row_3) puzzle = Puzzle(puzzle_list) puzzle.printPuzzle() return puzzle else: print "Incorrect input, please try again.\n"
import sys sys.path.insert(0, 'src') from puzzle import Puzzle from pprint import pprint setup_1 = [0, 2, 3, 1, 4, 6, 2, 5] setup_2 = [1, 2, 3, 0, 4, 6, 2, 5] setup_3 = [1, 2, 3, 4, 0, 6, 2, 5] setup_4 = [1, 2, 3, 4, 5, 6, 2, 0] setup_5 = [1, 2, 3, 4, 5, 6, 7, 0, 9, 10, 11, 8] puzzle = Puzzle(2, setup_1) print('\n') print(puzzle) print(puzzle.possible_moves()) puzzle = Puzzle(2, setup_2) print('\n') print(puzzle) print(puzzle.possible_moves()) puzzle = Puzzle(2, setup_3) print('\n') print(puzzle) print(puzzle.possible_moves()) puzzle = Puzzle(2, setup_4) print('\n') print(puzzle) print(puzzle.possible_moves())
class Level (object): """A simple Puzzle wrapper to handle input and winning. CONSTRUCTOR Level([event_handler][, ID][, definition][, win_cb], sound = True) event_handler: evthandler.EventHandler instance to use for keybindings. If not given, the level cannot be controlled by the keyboard. ID: level ID to load in the form (is_custom, level_ID). definition: a level definition to use; see the puzzle module for details. win_cb: function to call when the player wins, or (function, *args) to pass some arguments to the function. sound: whether to play sounds. One of ID and definition is required. METHODS load move reset solve set_frozen stop_solving start_recording stop_recording update ATTRIBUTES game: None. ID: level ID; None if this is a custom level or a definition was given instead. puzzle: puzzle.Puzzle instance. players: player blocks in the puzzle. msg: puzzle message. won: whether the level has been won. solving: whether the puzzle is currently being solved. solving_index: the current step in the solution being used to solve the puzzle. solutions: a list of solutions to the level. recording: whether input is currently being recorded. frozen: whether the solution being played back is paused. start_time: time the level started; this is altered when unpaused to give the proper amount of time the level has been running, not its actual start time. win_cb: as given. sound: as given. """ def __init__ (self, event_handler = None, ID = None, definition = None, win_cb = None, sound = True): if not hasattr(self, 'game'): self.game = None if event_handler is not None: # add gameplay key handlers args = ( eh.MODE_ONDOWN_REPEAT, max(int(conf.MOVE_INITIAL_DELAY * conf.FPS), 1), max(int(conf.MOVE_REPEAT_DELAY * conf.FPS), 1) ) move = lambda *ds: [(self._move, ds)] freeze = lambda k, e, m: self.set_frozen() l = conf.KB_LAYOUT event_handler.add_key_handlers([ (conf.KEYS_MOVE_LEFT[l], move(0)) + args, (conf.KEYS_MOVE_UP[l], move(1)) + args, (conf.KEYS_MOVE_RIGHT[l], move(2)) + args, (conf.KEYS_MOVE_DOWN[l], move(3)) + args, (conf.KEYS_MOVE_UPLEFT[l], move(0, 1)) + args, (conf.KEYS_MOVE_UPRIGHT[l], move(1, 2)) + args, (conf.KEYS_MOVE_DOWNRIGHT[l], move(2, 3)) + args, (conf.KEYS_MOVE_DOWNLEFT[l], move(3, 0)) + args, (conf.KEYS_SOLN_NEXT, self._step_solution) + args, (conf.KEYS_RESET, self.reset, eh.MODE_ONDOWN), (conf.KEYS_TAB, self._fast_forward, eh.MODE_HELD), (conf.KEYS_NEXT, freeze, eh.MODE_ONDOWN), (conf.KEYS_RIGHT, self._step_solution) + args ]) self.sound = sound self.load(ID, definition) if hasattr(win_cb, '__call__'): self.win_cb = (win_cb,) else: self.win_cb = win_cb def load (self, ID = None, definition = None): """Load a level. Takes ID and definition arguments as in the constructor. """ self.ID = None if ID is None or ID[0] else ID[1] if ID is not None: # get data from file path = conf.LEVEL_DIR_CUSTOM if ID[0] else conf.LEVEL_DIR_MAIN with open(path + ID[1]) as f: definition = f.read() self.puzzle = Puzzle(self.game, definition, True, self.sound) self.players = [b for b in self.puzzle.blocks if b.type == conf.B_PLAYER] # store message and solutions lines = definition.split('\n') msgs = [] solns = [] for line in lines: line = line.strip() for char, val in (('@', msgs), (':', solns)): if line.startswith(char): # add lines (stripped) starting with the character val.append(line[1:].strip()) # won't start with the other one if it starts with this one continue self.msg = msgs[0] if msgs and conf.SHOW_MSG else None self.solutions = solns self._moved = [] self._stored_moves = [] self._winning = False self.won = False self.solving = False self.solving_index = None self._ff = False self.recording = False self.frozen = False self.start_time = time() def move (self, multi, *directions): """Apply force to all player blocks in the given directions.""" if len(directions) == 1 and multi: if self._stored_moves is True: pass elif self._stored_moves: directions += (self._stored_moves[0],) self._stored_moves = True else: self._stored_moves.append(directions[0]) return # only make the move if haven't done already this frame directions = [d for d in directions if d not in self._moved] if not directions: return self._moved += directions if self.recording: self._record(directions) for d in set(directions): for player in self.players: player.add_force(d, conf.FORCE_MOVE) player.set_direction(d) def _move (self, key, event, mods, *directions): """Key callback to move player.""" if not self.solving: for d in directions: self.move(mods & conf.KEYS_MULTI, d) def reset (self, *args): """Reset the level to its state after the last call to Level.load.""" if not self.solving: self.puzzle.reset() self.players = [b for b in self.puzzle.blocks if b.type == conf.B_PLAYER] # restart recording if want to if self.recording and self._blank_on_reset: self.start_recording() self._winning = False self.won = False def _fast_forward (self, key, event, mods): """Key callback to fast-forward solving this frame.""" if self.solving: # if holding ctrl, go even faster if pygame.KMOD_CTRL & mods: self._ff = 2 else: self._ff = 1 def _parse_soln (self, ID, speed = conf.SOLVE_SPEED): """Parse a solution string and return the result.""" soln = self.solutions[ID] parsed = [] for i, s in enumerate(soln.split(',')): s = s.strip() if i % 2: # directions s = [conf.SOLN_DIRS.index(c) for c in s] else: # time delay if s.startswith('['): # got keys to hold for this waiting period end = s.find(']') hold = [conf.SOLN_DIRS.index(c) for c in s[1:end]] s = s[end + 1:].strip() else: hold = () ops = ('>', '<') if any(op in s for op in ops): # minimum and maximum values allowed_range = [None, None] while s: # check for < and > being first for op in ops: if s.startswith(op): s = s[1:].strip() eq = s.startswith('=') if eq: # remove = if found s = s[1:].strip() else: # op is not the first operator continue # the number is everything up to the next operator next_op = len(s) for o in ops: j = s.find(o) # or the end of the string if j == -1: j = len(s) next_op = min(j, next_op) val = int(s[:next_op]) val = int(val) # add/subtract one if >/< val += (-1 if op == '<' else 1) * (1 - eq) allowed_range[ops.index(op)] = val s = s[next_op:].strip() # constrain by given conditions gt, lt = allowed_range s = speed if gt is not None: s = max(s, gt) if lt is not None: s = min(s, lt) else: s = int(s) if s else speed s = (hold, s) parsed.append(s) return parsed def solve (self, solution = 0, stop_on_finish = True): """Solve the puzzle. Takes the solution number to use (its index in the list of solutions ordered as in the puzzle definition). This defaults to 0 (the 'primary' solution). Returns a list of the directions moved. This function is also called to move to the next step of an ongoing solution, in which case it requires no argument. In fact, if a solution is ongoing, it cannot be called as detailed above (any argument is ignored). This makes it a bad idea to call this function while solving. """ i = self.solving_index if i is None: # starting self.reset() self.solving = True self.solving_index = 0 self._solution = self._parse_soln(solution) self._solution_ff = self._parse_soln(solution, 0) self._solve_time = self._solution[0][1] self._solve_time_ff = self._solution_ff[0][1] self._finished_solving = False # store solve method if self.ID is not None: levels = conf.get('completed_levels', []) if self.ID not in levels: solved = conf.get('solve_methods', []) solved.append(False) conf.set(solve_methods = solved) # call this function again to act on the first instruction move = self.solve() elif i == len(self._solution): # finished: just wait until the level ends self._finished_solving = True if stop_on_finish: self.stop_solving() move = [] else: # continuing if i % 2: # make a move move = self._solution[i] self.move(False, *move) i += 1 if i < len(self._solution): self._solve_time = self._solution[i][1] self._solve_time_ff = self._solution_ff[i][1] self.solving_index = i else: # wait # if fast-forwarding, use the quicker solution fast = self._ff or self.frozen t = self._solve_time_ff if fast else self._solve_time if t <= 0: self.solving_index += 1 # do next step now move = self.solve() else: self._solve_time -= 1 self._solve_time_ff -= 1 held = self._solution[self.solving_index][0] if held: # want to send some input every frame for this delay self.move(False, *held) move = held else: move = [] self._ff = False return move def set_frozen (self, frozen = None): """Set paused state of solution, or toggle without an argument.""" if self.solving: self.frozen = not self.frozen if frozen is None else frozen def _step_solution (self, key, event, mods): """If paused, step the solution forwards once.""" if self.solving and self.frozen: self._next_step = True def stop_solving (self): """Stop solving the puzzle.""" if self.solving: self.solving = False self.solving_index = None self.frozen = False del self._solution, self._solution_ff, self._solve_time, \ self._solve_time_ff, self._next_step, self._finished_solving def _record (self, directions): """Add input to the current recording.""" directions = set(directions) recorded = self._recorded frame = self._recording_frame while len(recorded) < frame: # haven't added anything for some previous frames recorded.append(None) if len(recorded) == frame: # haven't added anything for this frame recorded.append(directions) else: # add more to this frame recorded[frame] |= directions self._recorded = recorded def start_recording (self, blank_on_reset = True): """Start recording input to the puzzle (moves). Takes one boolean argument indicating whether to start recording again if the puzzle is reset. If already recording, calling this will delete the current recording. """ self.recording = True self._blank_on_reset = blank_on_reset self._recorded = [] self._recording_frame = 0 def stop_recording (self): """Stop recording input and return the recorded input. The return value is in the standard solution format. If not recording, this function returns None. """ result = '' t = 0 for frame in self._recorded: if frame is None: # wait for a frame with input t += 1 else: # add total wait time result += str(t) + ',' t = 0 # add input result += ''.join(conf.SOLN_DIRS[d] for d in frame) + ',' self.recording = False del self._blank_on_reset, self._recorded, self._recording_frame return result[:-1] def update (self): """Update puzzle and check win conditions. Returns whether anything changed. """ if not self.frozen or self._next_step: # fast-forward by increasing FPS if self.solving and self._ff == 2: if not hasattr(self, '_FRAME'): self._FRAME = self.FRAME self.FRAME /= conf.FF_SPEEDUP elif hasattr(self, '_FRAME'): self.FRAME = self._FRAME del self._FRAME # continue solving if self.solving: self.solve() # continue recording if self.recording: self._recording_frame += 1 # step puzzle forwards rtn = self.puzzle.step() self._next_step = False # reset list of moves made this frame self._moved = [] self._stored_moves = [] else: rtn = False # check for surfaces with their corresponding Block types on them win = True for col in self.puzzle.grid: for s, b, sel in col: # goal surfaces have IDs starting at 0 if s >= 0 and (not isinstance(b, Block) or s != b.type): win = False break # need to stay winning for one frame - that is, blocks must have # stopped on the goals, not just be moving past them if win: if not self._winning: self._winning = True # else if this is the first frame since we've won, elif not self.won: # stop solving if self.solving: if self._finished_solving: self.stop_solving() win = self._winning else: win = False if win: # save to disk if not self.solving and self.ID is not None: levels = conf.get('completed_levels', []) if self.ID not in levels: levels.append(self.ID) conf.set(completed_levels = levels) self.game.set_backend_attrs(menu.MainMenu, 're_init', True) # store solve method solved = conf.get('solve_methods', []) solved.append(True) conf.set(solve_methods = solved) # call win callback if self.win_cb is not None: self.win_cb[0](*self.win_cb[1:]) # play victory sound if self.sound: self.game.play_snd('win') self.won = True else: self._winning = False return rtn
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ import sys from puzzle import Puzzle if __name__ == "__main__": if len(sys.argv) > 1: f = open(sys.argv[1], "r") ans = [] for l in f.readlines(): if l[0] != "#": ans.append(l.rstrip().split(" ")) pz = Puzzle(ans) pz.printout() pz.initial_update() while (pz.eliminate_singles() or pz.eliminate_doubles()) and (not pz.finished()): pass print print pz.printout()
def setUp(self): self.p = Puzzle(plugins_dir=join(getcwd(), PATH))
def __init__(self, initial_state): initial_state = initial_state.split(",") initial_state = [int(i) for i in initial_state] self.START_PUZZLE = Puzzle(initial_state, 0)
#! /usr/bin/python from puzzle import Puzzle from a_star import Astar import time ##Set Goal goal = ["1", "2", "3", "4", "5", "6", "7", "8", "_"] test = Puzzle() test.random_start(5) print "-----------Puzzle----------" test.print_board() print "---------------------------" solve = Astar() start_time = time.time() solve.simulated_annealing(test,goal) print("--- search took %.2f seconds ---" % (time.time() - start_time)) # print solve.solution # test.print_board() print "Total move is %d" % (len(solve.solution)) for direction in solve.solution: print "next move is %s" % (direction) raw_input("Press Enter to continue...") test.move(direction) test.print_board()
def read_xpf(filename, warnings=True): results = [] try: doc = etree.parse(filename) except etree.XMLSyntaxError: raise XPFParserError(u"No valid XML syntax.") puzzles = doc.getroot() if puzzles.tag != "Puzzles": raise XPFParserError(u"No root element called Puzzles found.") version = puzzles.get("Version") if version is None: raise XPFParserError(u"No version specified for this XPF file. Possible older than v1.0?") try: version = float(version) except ValueError: raise XPFParserError("uXPF version is not a valid number") if version < 1.0: raise XPFParserError("uXPF versions older than 1.0 are not supported.") for puzzle in puzzles: if puzzle.tag != "Puzzle": if warnings: print "Warning: skipping a child of Puzzles that is not a Puzzle." continue r_meta = {} r_width = None r_height = None r_grid = None r_notepad = "" r_styles = {} r_gstyles = {} r_number_mode = constants.NUMBERING_AUTO for child in puzzle: if child.tag in XPF_META_ELEMS: r_meta[XPF_META_ELEMS[child.tag]] = child.text elif child.tag == "Size": for d in child: try: if d.tag == "Rows": r_height = int(d.text) elif d.tag == "Cols": r_width = int(d.text) except ValueError: raise XPFParserError(u"Invalid grid dimensions were specified.") elif child.tag == "Grid": if r_width is None: raise XPFParserError(u"The number of columns was not specified.") if r_height is None: raise XPFParserError(u"The number of rows was not specified.") assert r_width >= 0 assert r_height >= 0 r_grid = Grid(r_width, r_height) y = 0 for row in child: if row.tag != "Row": if warnings: print "Warning: skipping a child of Grid that is not a Row." continue if not row.text:# or len(row.text) < r_width: if warnings: print "Warning: skipping a row with missing content." continue for x, c in enumerate(row.text): if c == '.': r_grid.data[y][x]["block"] = True elif c == '~': r_grid.data[y][x]["void"] = True else: r_grid.data[y][x]["char"] = c if c != ' ' else '' y += 1 elif child.tag == "Circles": for circle in child: if circle.tag != "Circle": if warnings: print "Warning: skipping a child of Circles that is not a Circle." continue a_row = circle.get("Row") a_col = circle.get("Col") if not (a_row and a_col): if warnings: print "Warning: skipping a child of Circles with missing content." continue try: x = int(a_col) - 1 y = int(a_row) - 1 except ValueError: if warnings: print "Warning: skipping child of Circles with invalid coordinates." continue if (x, y) not in r_styles: r_styles[x, y] = CellStyle() r_styles[x, y]["circle"] = True elif child.tag == "RebusEntries": for rebus in child: if rebus.tag != "Rebus": if warnings: print "Warning: skipping a child of RebusEntries that is not a Rebus." continue a_row = rebus.get("Row") a_col = rebus.get("Col") a_short = rebus.get("Short") content = rebus.text if not (a_row and a_row and a_short and content): if warnings: print "Warning: skipping a child of RebusEntries with missing content." continue try: x = int(a_col) - 1 y = int(a_row) - 1 except ValueError: if warnings: print "Warning: skipping child of RebusEntries with invalid coordinates." continue r_grid.set_rebus(x, y, a_short, content) elif child.tag == "Shades": for shade in child: if shade.tag != "Shade": if warnings: print "Warning: skipping a child of Shades that is not a Shade." continue a_row = shade.get("Row") a_col = shade.get("Col") if not (a_row and a_col and shade.text): if warnings: print "Warning: skipping a child of Shades with missing content." continue try: x = int(a_col) - 1 y = int(a_row) - 1 except ValueError: if warnings: print "Warning: skipping a child of Shades with invalid coordinates." continue if (x, y) not in r_styles: r_styles[x, y] = CellStyle() if shade.text == "gray": rgb = (32767, 32767, 32767) elif shade.text[0] == '#': rgb = hex_to_color(shade.text) r_styles[x, y]["cell", "color"] = rgb elif child.tag == "Clues": for clue in child: if clue.tag != "Clue": if warnings: print "Warning: skipping a child of Clues that is not a Clue." continue a_row = clue.get("Row") a_col = clue.get("Col") a_num = clue.get("Num") a_dir = clue.get("Dir") a_ans = clue.get("Ans") if not (a_row and a_col and a_dir): if warnings: print "Warning: skipping a child of Clues with missing content." continue try: x = int(a_col) - 1 y = int(a_row) - 1 except ValueError: if warnings: print "Warning: skipping a child of Clues with invalid coordinates." continue dirs = {"Across": "across", "Down": "down"} if a_dir not in dirs: if warnings: print "Warning: skipping a clue with a direction that is not across or down." continue if not clue.text: if warnings: print "Warning: skipping clue without text." continue r_grid.store_clue(x, y, dirs[a_dir], "text", clue.text) elif child.tag == "Notepad": r_notepad = child.text elif child.tag == "Palabra": version = child.get("Version") if version > constants.VERSION: # for now, don't try if warnings: print "Warning: Palabra-specific puzzle content was not loaded as it was made in a newer version of Palabra." continue for c in child: if c.tag == "Explanation": a_row = c.get("Row") a_col = c.get("Col") a_dir = c.get("Dir") if not (a_row and a_col and a_dir): if warnings: print "Warning: skipping Explanation with missing content" continue try: x = int(a_col) - 1 y = int(a_row) - 1 except ValueError: if warnings: print "Warning: skipping Explanation with invalid coordinates." continue dirs = {"Across": "across", "Down": "down"} if a_dir not in dirs: if warnings: print "Warning: skipping Explanation with a direction that is not across or down." continue if not c.text: if warnings: print "Warning: skipping explanation without text." continue r_grid.store_clue(x, y, dirs[a_dir], "explanation", c.text) elif c.tag == "Style": for s in c: if s.tag == "Bar": width = s.get("Width") if width is not None: r_gstyles["bar", "width"] = int(width) elif s.tag == "Border": width = s.get("Width") if width is not None: r_gstyles["border", "width"] = int(width) color = s.get("Color") if color is not None: r_gstyles["border", "color"] = hex_to_color(color) elif s.tag == "Cell": size = s.get("Size") if size is not None: r_gstyles["cell", "size"] = int(size) color = s.get("Color") if color is not None: r_gstyles["cell", "color"] = hex_to_color(color) elif s.tag == "Line": width = s.get("Width") if width is not None: r_gstyles["line", "width"] = int(width) color = s.get("Color") if color is not None: r_gstyles["line", "color"] = hex_to_color(color) elif s.tag == "Block": color = s.get("Color") if color is not None: r_gstyles["block", "color"] = hex_to_color(color) margin = s.get("Margin") if margin is not None: r_gstyles["block", "margin"] = int(margin) elif s.tag == "Char": color = s.get("Color") if color is not None: r_gstyles["char", "color"] = hex_to_color(color) size = s.get("Size") if size is not None: s_s = int(size) s_k = ("cell", "size") s_d = {s_k: (r_gstyles[s_k] if s_k in r_gstyles else DEFAULTS[s_k])} s_r = _relative_to(s_k, s_s / 100.0, d=s_d) r_gstyles["char", "size"] = (s_s, s_r) elif s.tag == "Number": color = s.get("Color") if color is not None: r_gstyles["number", "color"] = hex_to_color(color) size = s.get("Size") if size is not None: s_s = int(size) s_k = ("cell", "size") s_d = {s_k: (r_gstyles[s_k] if s_k in r_gstyles else DEFAULTS[s_k])} s_r = _relative_to(s_k, s_s / 100.0, d=s_d) r_gstyles["number", "size"] = (s_s, s_r) if r_number_mode == constants.NUMBERING_AUTO: r_grid.assign_numbers() p = Puzzle(r_grid, r_styles, r_gstyles) p.metadata = r_meta p.type = constants.PUZZLE_XPF p.filename = filename p.notepad = r_notepad results.append(p) return results
#! /usr/bin/python from copy import deepcopy from puzzle import Puzzle import sys,time # define question array p = Puzzle([ ["1","2","3"], ["4","5","6"], ["7","8"," "], ]) # define goal array goal = Puzzle(deepcopy(p.Array)) # define where there is a space space_index = [2,2] def check_answer(): """ Check the answer is correct """ if p.Array == goal.Array: print "Clear!!" return True else: return False def print_problem(puzzle): """ print problem statement """ print "\nProblem %d" % (i) puzzle.print_puzzle()
from puzzle import Puzzle #just some tests to show how the class works #testPuzzle.printBoard() #print(testPuzzle.getTile(0,2)) #stringVer = testPuzzle.printBoardString() #print(stringVer) testPuzzle = Puzzle([[1, 2, 3], [4, 5, 0], [6, 7, 8]]) wrongPuzzle = Puzzle([[4, 2, 1], [3, 7, 8], [6, 5, 0]]) testPuzzle2 = Puzzle([[1, 2, 3], [4, 5, 0], [6, 7, 8]]) print("\nCorrect board") testPuzzle.printBoard() print("\n") print("Incorrect board\n") wrongPuzzle.printBoard() #print("Attempting to find neighbors") #possibilities = testPuzzle.getNeighbors() #print(possibilities) #print(testPuzzle.isGoal()) #print(testPuzzle.getHamming()) #print(wrongPuzzle.isGoal()) #print(wrongPuzzle.getHamming()) #print(testPuzzle.boardsEqual(wrongPuzzle.getBoard())) #print(testPuzzle.boardsEqual(testPuzzle2.getBoard())) print("WrongPuzzle's current state: \n")
if file.endswith(image_type) ] for image_name in image_files: image_gray = cv2.imread(images_path + image_name, 0) if image_gray is None: continue puzzle_state, puzzle_image = extract_puzzle( image_gray, puzzle_extractor_display_time) new_visualizer = Visualizer(puzzle_state, puzzle_image, window_name='Recursive Solver') input = np.reshape( np.asarray([int(num) for num in puzzle_state.strip()]), (9, 9)) # new_puzzle = Puzzle(input, visualizer=new_visualizer, display_updates=show_standard).solve() Puzzle(visualizer=new_visualizer).solve_recursive( input, display_updates=show_recursive) filepath = './puzzles/sudoku.csv' with open(filepath, newline='') as pz: reader = csv.reader(pz, ) next(reader, None) # Skip the header line recursive_sum = 0 standard_sum = 0 perf = 0 ct = 0 try: for input, solution in reader: ct += 1
def load(self, puzzle_index, solve_set) -> (Puzzle, Puzzle): puzzle = Puzzle(self.__puzzle_strings[puzzle_index], solve_set) solution = Puzzle(self.__solution_strings[puzzle_index]) return puzzle, solution
class Editor (object): """A puzzle editor (Game backend). Takes arguments to pass to Editor.load. METHODS load change resize insert delete set_block undo redo click_tile switch_puzzle reset menu ATTRIBUTES game: as given. event_handler: as given. ID: as given. selector: puzzle used to select blocks/surfaces to add. editor: the puzzle being edited. editor_rect: the rect the editor puzzle is drawn in, or None if unknown. puzzle: the current visible puzzle (editor or selector). editing: whether the current puzzle is editor. changes: a list of changes that have been made to the puzzle. state: the current position in the changes list. """ def __init__ (self, game, event_handler, ID = None, defn = None): self.game = game # add event handlers event_handler.add_event_handlers({ pygame.MOUSEBUTTONDOWN: self._click, pygame.MOUSEBUTTONUP: self._unclick, pygame.MOUSEMOTION: lambda e: setattr(self, 'mouse_moved', True) }) pzl_args = ( eh.MODE_ONDOWN_REPEAT, max(int(conf.MOVE_INITIAL_DELAY * conf.FPS), 1), max(int(conf.MOVE_REPEAT_DELAY * conf.FPS), 1) ) menu_args = ( eh.MODE_ONDOWN_REPEAT, max(int(conf.MENU_INITIAL_DELAY * conf.FPS), 1), max(int(conf.MENU_REPEAT_DELAY * conf.FPS), 1) ) od = eh.MODE_ONDOWN held = eh.MODE_HELD l = conf.KB_LAYOUT event_handler.add_key_handlers([ (conf.KEYS_MOVE_LEFT[l], [(self._move, (0,))]) + pzl_args, (conf.KEYS_MOVE_UP[l], [(self._move, (1,))]) + pzl_args, (conf.KEYS_MOVE_RIGHT[l], [(self._move, (2,))]) + pzl_args, (conf.KEYS_MOVE_DOWN[l], [(self._move, (3,))]) + pzl_args, (conf.KEYS_BACK, self.menu, od), (conf.KEYS_TAB, self.switch_puzzle, od), (conf.KEYS_INSERT, self._insert_cb, od), (conf.KEYS_DEL, self.delete, od), (conf.KEYS_UNDO, self.undo) + menu_args, (conf.KEYS_REDO, self.redo) + menu_args, (conf.KEYS_RESET, self.reset, od) ]) self.event_handler = event_handler # create block/surface selection grid blocks = xrange(conf.MAX_ID + 1) surfaces = xrange(-1, conf.MIN_ID - 1, -1) self._selector_defn = '3 {0}\n{1}\n\n{2}\n{3}'.format( max(len(blocks), len(surfaces)), '\n'.join('{0} 0 {1}'.format(b, i) for i, b in enumerate(blocks)), '\n'.join('{0} 1 {1}'.format(b, i) for i, b in enumerate(blocks)), '\n'.join('{0} 2 {1}'.format(s, i) for i, s in enumerate(surfaces)) ) self.selector = Puzzle(game, self._selector_defn) self.FRAME = conf.FRAME self.load(ID, defn) def load (self, ID = None, defn = None): """Load a level. load([ID][, defn]) ID: custom level ID. defn: if ID is not given, load a level from this definition; if this is not given, load a blank level. """ if ID is None: if defn is None: # blank grid defn = conf.BLANK_LEVEL self.ID = None else: # get data from file d = conf.LEVEL_DIR_DRAFT if ID[0] == 2 else conf.LEVEL_DIR_CUSTOM with open(d + ID[1]) as f: defn = f.read() self.ID = ID[1] if hasattr(self, 'editor'): self.editor.load(defn) else: self.editor = Puzzle(self.game, defn) self.editor_rect = None self.editor.deselect() self.editor.select((0, 0)) self.selector.deselect() self.selector.select((0, 0), True) self.puzzle = self.editor self.editing = True self.dirty = True self.changes = [] self.state = 0 self.mouse_moved = False self.resizing = False def change (self, *data): """Make a change to the puzzle; takes data to store in self.changes.""" cs = self.changes # purge 'future' states cs = cs[:self.state] cs.append(data) # purge oldest state if need to (don't need to increment state, then) if len(cs) > conf.UNDO_LEVELS > 0: cs.pop(0) else: self.state += 1 self.changes = cs def resize (self, amount, dirn): """Like Editor.editor.resize, but do some wrapper stuff.""" lost = self.editor.resize(amount, dirn) # might not have changed if lost is not False: self.dirty = True self.change('resize', amount, dirn, lost) def _move (self, key, event, mods, direction): """Callback for arrow keys.""" resize = False mods = (mods & pygame.KMOD_SHIFT, mods & pygame.KMOD_ALT) shrink = bool(mods[direction <= 1]) grow = bool(mods[direction > 1]) resize = shrink ^ grow if resize: # things could get messy if we're already mouse-resizing if not self.resizing: self.resize(1 if grow else -1, direction) else: # move selection self.puzzle.move_selected(direction) def insert (self): """Insert a block or surface at the current position.""" if not self.editing: return # get type and ID of selected tile in selector puzzle col, row = self.selector.selected.keys()[0] x, y = self.editor.selected.keys()[0] is_block = col == 0 and row <= conf.MAX_ID if is_block: ID = row # will be here for col = 0 if past end of blocks elif col == 0 or col == 1: ID = row if ID > conf.MAX_ID: ID = conf.DEFAULT_SURFACE else: ID = -row - 1 if ID >= 0: ID = conf.DEFAULT_SURFACE # make changes to selected tile in editor puzzle if necessary current = self.editor.grid[x][y] if is_block: if current[1] is None or current[1].type != ID: old_b = current[1] b = self.editor.add_block((BoringBlock, ID), x, y) self.game.play_snd('place_block') self.change('set_block', old_b, b, x, y) else: if current[0] != ID: old_ID = current[0] self.editor.set_surface(x, y, ID) self.game.play_snd('place_surface') self.change('set_surface', old_ID, ID, x, y) def _insert_cb (self, *args): """Callback for conf.KEYS_INSERT.""" if self.editing: self.insert() else: self.switch_puzzle() def delete (self, *args): """Delete a block or surface in the currently selected tile.""" if self.editing: x, y = self.editor.selected.keys()[0] data = self.editor.grid[x][y] snd = True # delete block, if any if data[1] is not None: b = self.editor.rm_block(None, x, y) self.change('set_block', b, None, x, y) # set surface to blank if not already elif data[0] != conf.S_BLANK: s = self.editor.set_surface(x, y, conf.S_BLANK) self.change('set_surface', s, conf.S_BLANK, x, y) else: snd = False if snd: self.game.play_snd('delete') def set_block (self, b, x, y): """Add or remove a block to or from the puzzle. set_block(b, x, y) b: BoringBlock instance, or None to remove. x, y: tile position. """ if b is None: self.editor.rm_block(None, x, y) else: self.editor.add_block(b, x, y) def undo (self, *args): """Undo changes to the puzzle.""" if self.state > 0: self.state -= 1 # get change data data = self.changes[self.state] c, data = data[0], data[1:] # make the change to the puzzle if c == 'set_block': old_b, new_b, x, y = data self.set_block(old_b, x, y) elif c == 'set_surface': old, new, x, y = data self.editor.set_surface(x, y, old) elif c == 'resize': amount, direction, lost = data self.editor.resize(-amount, (direction - 2) % 4) # restore stuff that was lost in the resize for obj, x, y in lost: if isinstance(obj, int): self.editor.set_surface(x, y, obj) else: self.set_block(obj, x, y) self.dirty = True def redo (self, *args): """Redo undone changes.""" if self.state < len(self.changes): # get change data data = self.changes[self.state] c, data = data[0], data[1:] self.state += 1 # make the change to the puzzle if c == 'set_block': old_b, new_b, x, y = data self.set_block(new_b, x, y) elif c == 'set_surface': old, new, x, y = data self.editor.set_surface(x, y, new) elif c == 'resize': amount, direction, lost = data self.editor.resize(amount, direction) self.dirty = True def click_tile (self, insert, pos): """Insert or delete a block or surface at the given position. click_tile(insert, pos) insert: whether to insert the current block or surface (else delete). pos: on-screen position to try to perform the action at. """ # get clicked tile p = self.editor.point_tile(pos) if p: # clicked a tile in self.editor: switch to and select if not self.editing: self.switch_puzzle() self.editor.deselect() self.editor.select(p) (self.insert if insert else self.delete)() else: p = self.selector.point_tile(pos) if p: # clicked a tile in self.selector: switch to selector, then # select the tile if self.editing: self.switch_puzzle() self.selector.deselect() self.selector.select(p) def _click (self, evt): """Handle mouse clicks.""" button = evt.button pos = evt.pos if button in (1, 3): # left-click to insert, right-click to delete self.click_tile(button == 1, pos) elif button == 2: rel_pos = self.editor.point_pos(pos) # make sure we're clicking in the grid if rel_pos is None: return self._resize_sides = [] # exclude a zone in the middle b = conf.RESIZE_DEAD_ZONE_BOUNDARY for i in (0, 1): if b < rel_pos[i] < 1 - b: self._resize_sides.append(None) else: # the axes we can resize on depends on where we start from self._resize_sides.append(1 if rel_pos[i] > .5 else -1) if self._resize_sides == [None, None]: return self.resizing = list(pos) def _unclick (self, evt): """Handle mouse click release.""" if evt.button == 2 and self.resizing: self.resizing = False del self._resize_sides def switch_puzzle (self, *args): """Switch selected puzzle between editor and block selector.""" self.editing = not self.editing pzls = (self.editor, self.selector) if self.editing: new, old = pzls else: old, new = pzls # deselect old and select new for colour, pzl in enumerate((new, old)): pos = pzl.selected.keys()[0] pzl.deselect() pzl.select(pos, colour) self.puzzle = new def reset (self, *args): """Confirm resetting the puzzle.""" if self.state > 0: self.game.start_backend(Menu, 1, self) # else nothing to reset def menu (self, *args): """Show the editor menu.""" self.game.start_backend(Menu, 0, self) def _do_reset (self): """Actually reset the puzzle.""" # just reset to original state - to whatever was loaded, if anything while self.state > 0: self.undo() def update (self): """Handle mouse movement.""" if self.mouse_moved: pos = pygame.mouse.get_pos() if self.resizing: # change puzzle size if middle-click-dragging old_pos = self.resizing for i in (0, 1): side = self._resize_sides[i] if side is None: # can't resize on this axis continue diff = pos[i] - old_pos[i] threshold = min(conf.RESIZE_LENGTH * conf.RES[0], self.editor.tile_size(i)) while abs(diff) >= threshold: # resize sign = 1 if diff > 0 else -1 self.resize(sign * side, i + 2 * (sign == 1)) # prepare for resizing again old_pos[i] += sign * threshold diff -= sign * threshold else: # change selection based on mouse position # get tile under mouse tile = self.editor.point_tile(pos) if tile: # editor: select tile under mouse if not self.editing: self.switch_puzzle() self.editor.deselect() self.editor.select(tile) else: # selector: just make sure it's the current puzzle tile = self.selector.point_tile(pos) if tile: if self.editing: self.switch_puzzle() self.mouse_moved = False def draw (self, screen): """Draw the puzzles.""" w, h = screen.get_size() w1 = int(conf.EDITOR_WIDTH * w) w2 = w - w1 pad = int(conf.EDITOR_ARROW_PADDING * w) if self.dirty: screen.fill(conf.BG[conf.THEME]) # get puzzle sizes e = self.editor.tiler s = self.selector.tiler if w1 != s.offset[0]: # screen size changed: need to change puzzle positions e.offset = (pad, pad) s.offset = (w1, 0) s.reset() # draw puzzles drawn1 = self.editor.draw(screen, self.dirty, (w1 - 2 * pad, h - 2 * pad)) drawn2 = self.selector.draw(screen, self.dirty, (w2, h)) # and return the sum list of rects to draw in drawn = [] for d in (drawn1, drawn2): if d: drawn += d # draw arrows if self.dirty: self.editor_rect = drawn1 # TODO to_draw = range(8) special = [] drawn = True else: # TODO to_draw = [] special = [] drawn += [] if to_draw: # get draw area position and size l, t, w, h = self.editor_rect[0] tl = (l - pad, t - pad) br = (l + w, t + h) sz = (w + 2 * pad, h + 2 * pad) # generate required arrow images fn = conf.IMG_DIR + conf.THEME + os.sep + '{0}.png' imgs = [] for ID in ('arrow', 'arrow-special'): imgs.append(self.game.img(fn.format(ID), (pad / 2, None))) for i in xrange(1, 4): imgs.append(None) img_s = [img for img in imgs if img is not None][0].get_size() # draw for i in to_draw: p = [0, 0] axis = (i / 2) % 2 p[axis] = (br if i > 3 else tl)[axis] + img_s[0] * (i % 2) p[not axis] = tl[not axis] + (sz[not axis] - img_s[1]) / 2 img = (axis + 2 * (i % 2)) % 4 if i in special: img += 4 if imgs[img] is None: source = imgs[4 * (i in special)] imgs[img] = pygame.transform.rotate(source, -90 * img) screen.blit(imgs[img], p) self.dirty = False return drawn
from puzzle import Puzzle ''' Information for the {@param: data_group}: "Days" : [ "June 10", "June 11", "June 12", "June 13" ], "Departures" : [ "uttonwillow", "Coulterville", "Farley", "Leland" ], "Names" : [ "Allen", "Chris", "Julio", "Luke" ] ''' data_group = {"Days" : [ "10", "11", "12", "13" ], "Departures" : [ "buttonwillow", "coulterville", "farley", "leland" ], "Names" : [ "allen", "chris", "julio", "luke"] } puzzle = Puzzle(data_group) # puzzle.process_hint('The/at person/nn departing/vbg from/in Buttonwillow/np will/md leave/vb 2/cd days/nn after/cs Julio/np.') # puzzle.process_hint('Luke/np is/bez scheduled/vbd to/in leave/vb on/in June/np 11/cd.') # puzzle.process_hint('The/at person/nn working/vbg on/in June/np 11/cd is/is either/cc the/at person/nn departing/vbg from/in Coulterville/np or/in Allen/np.') puzzle.process_hint('The/at conductor/nn departing/vbg from/in Leland/np will/md leave/vb 1/cd day/nn after/cs Chris/np') print(puzzle.kb_rule_list) # print(puzzle.process_hint('The/at conductor/nn departing/vbg from/in Leland/np will/md leave/vb 1/cd day/nn after/cs Chris/np')) # hint1 = Hint('The person departing from Buttonwillow will leave 2 days after Julio.') def test_process_hint_puzzle_one(puzzle, num_tests = 4): print(puzzle.process_hint('The/at person/nn departing/vbg from/in Buttonwillow/np will/md leave/vb 2/cd days/nn after/in Julio/np.')) print(puzzle.process_hint('Luke/np is/bez scheduled/vbd to/in leave/vb on/in June/np 11/cd.')) print(puzzle.process_hint('The/at conductor/nn departing/vbg from/in Leland/np will/md leave/vb 1/cd day/nn after/cs Chris/np'))
def testHowManyMovesIsCurrentStateFromGoal(self): p = Puzzle("021345678") self.assertEqual(p.distanceToGoal(), 2)
def choose_map(self, continent): name = continent.replace(" ", "-") img = pg.transform.smoothscale(prepare.GFX[name], (640, 480)) self.persist["puzzle"] = Puzzle(img) self.next_state = "IDLE" self.done = True
def read_ipuz(filename, warnings=True): results = [] content = None with open(filename, 'r') as f: content = f.read() content = content.strip('\n') if content is not None: data = json.loads(content[5:-1]) keys = data.keys() if "version" not in keys: raise IPUZParserError(u"Mandatory version element missing in ipuz file.") if "kind" not in keys: raise IPUZParserError(u"Mandatory kind element missing in ipuz file.") n_kinds = len(data["kind"]) if n_kinds == 0: raise IPUZParserError(u"Mandatory kind element has no content.") if n_kinds > 1: raise IPUZParserError(u"Mandatory kind element has more than one puzzle kind.") kind = data["kind"][0] if kind != "http://ipuz.org/crossword#1": raise IPUZParserError(u"This type of puzzle (" + kind + ") is not supported.") r_meta = {} r_width = None r_height = None r_grid = None r_notepad = "" r_styles = {} r_gstyles = {} r_number_mode = constants.NUMBERING_AUTO for m in IPUZ_MY_META_ELEMS: if m in data: r_meta[IPUZ_MY_META_ELEMS[m]] = data[m] for m in IPUZ_META_ELEMS: if m in data: r_meta[m] = data[m] c_block = IPUZ_BLOCK_CHAR c_empty = IPUZ_EMPTY_CHAR for t in IPUZ_TECH_ELEMS: if t in data: if t == "block": r_meta[t] = c_block = data[t] elif t == "empty": r_meta[t] = c_empty = data[t] else: pass # TODO for e in IPUZ_CROSS_ELEMS: if e in data: if e == "dimensions": r_width = data[e]["width"] r_height = data[e]["height"] elif e == "puzzle": assert r_width >= 0 assert r_height >= 0 r_grid = Grid(r_width, r_height) x, y = 0, 0 for row in data[e]: for x, c in enumerate(row): if isinstance(c, dict): if "style" in c: style = c["style"] if "shapebg" in style: if style["shapebg"] == "circle": if (x, y) not in r_styles: r_styles[x, y] = CellStyle() r_styles[x, y]["circle"] = True if "color" in style: if (x, y) not in r_styles: r_styles[x, y] = CellStyle() rgb = hex_to_color('#' + style["color"]) r_styles[x, y]["cell", "color"] = rgb if "colortext" in style: if (x, y) not in r_styles: r_styles[x, y] = CellStyle() rgb = hex_to_color(style["colortext"]) r_styles[x, y]["char", "color"] = rgb if "cell" in c: c = c["cell"] # fall-through if c == None: r_grid.set_void(x, y, True) elif c == c_block: r_grid.set_block(x, y, True) elif c == c_empty: pass y += 1 elif e == "solution": assert r_grid is not None x, y = 0, 0 for row in data[e]: for x, c in enumerate(row): if isinstance(c, list) or isinstance(c, dict): print "TODO" elif c is not None and c != c_block and c != c_empty: r_grid.set_char(x, y, c) y += 1 elif e == "clues": assert r_grid is not None clues = {} for md, d in [("across", "Across"), ("down", "Down")]: if d in data[e]: for n, clue in data[e][d]: clues[n, md] = clue if r_number_mode == constants.NUMBERING_AUTO: r_grid.assign_numbers() for d in ["across", "down"]: for n, x, y in r_grid.words_by_direction(d): if (n, d) in clues: r_grid.store_clue(x, y, d, "text", clues[n, d]) p = Puzzle(r_grid, r_styles, r_gstyles) p.metadata = r_meta p.type = constants.PUZZLE_IPUZ p.filename = filename p.notepad = r_notepad results.append(p) return results
if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("size", type=int, help="Size of the puzzle's side. Must be >3.") args = parser.parse_args() cmd = "python puzzle_generator.py " + str(args.size) proc = subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True) (out, err) = proc.communicate() print out out = out.strip() data = out.split('\n') puzzle = Puzzle(data) print '' print 'Comment:', puzzle.comment print '' print 'Puzzle:', puzzle.list print '' print 'Solution:', puzzle.solution start = BlockPuzzle(puzzle.size, puzzle.list) end = BlockPuzzle(puzzle.size, puzzle.solution) x = solve(start, end, distance_h) i = 0 for puzzle in x[2]:
rect2 = pygame.Rect(0, 300, 600, 300) font = pygame.font.Font(None, 30) pygame.display.set_icon(pygame.image.load('objects/tile.bmp')) while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = 0 outer_loop = 0 if event.type == pygame.MOUSEBUTTONUP: pos = pygame.mouse.get_pos() if rect1.collidepoint(pos): puzzle = Puzzle(screen) outer_loop = puzzle.play() running = 0 break elif rect2.collidepoint(pos): puzzle = Puzzle(screen) outer_loop = puzzle.user_create_puzzle() running = 0 break #draw rectangles pygame.draw.rect(screen, (0, 0, 0), rect1, 1) pygame.draw.rect(screen, (0, 0, 0), rect2, 1) #render text text1 = font.render("Solve a puzzle", True, (0, 0, 0))
#!/usr/bin/env python3 import argparse from puzzle import Puzzle parser = argparse.ArgumentParser(description='A very simple soduku solver') parser.add_argument("file", type=str, default=None, help="File to process.") parser.add_argument("-d", "--details", default=None, action="store_true", help="Output steps in details") args = parser.parse_args() p = Puzzle(args.file) p.output_details = args.details p.solve().format()
fin = ([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0],15) nants = raw_input("Numero de hormigas: ") base_attractiveness = raw_input("Atractividad base: ") initial_tau = raw_input("Feromona inicial: ") ratio_de_evaporacion = raw_input("Ratio de evaporacion: ") cota = raw_input("Cota: ") alfa = raw_input("Alfa: ") beta = raw_input("Beta: ") convergencia_minima = raw_input("Convergencia minima: ") i = 0 start = time.time() p1 = Puzzle(inicio, fin, float(alfa), float(beta), int(nants), float(ratio_de_evaporacion), float(cota), float(base_attractiveness), float(initial_tau)) solution = p1.run(int(convergencia_minima)) end = time.time() if solution == None: print("Run again") else: mostrar_solucion = "" for s in solution: mostrar_solucion += str(s[0])+"," print("Solution found in "+ str(end-start) + " seconds") print("View solution in:") print("http://ratslap.com/hormigas/") print("Paste this:") print(str(mostrar_solucion)[0:-1])
def general_search(problem, queueing_function): num_expanded = 0 #Counts number of nodes expanded (excluding root) max_nodes_in_queue = 0 #Counts maximum number of nodes in queue PQueue = [] #List to be transformed into a priority queue visited = {} #Dictionary to keep track of visited nodes (Allows for O(1) searching) heapq.heapify(PQueue) #Heapify the list we made earlier puzzle = copy.deepcopy(problem) #Make a deep copy just in case so stuff doesn't break #Check for solvability in O(1) time if not checkSolvability(puzzle): print "\nPuzzle is not Solvable!\n" return -1 #If puzzle is solvable, then calculate initial h(n) if queueing_function == "UniformCostSearch": puzzle.heuristicCost = 0 elif queueing_function == "A_star_misplaced": puzzle.heuristicCost = calcMisplacedTilesDistance(puzzle) elif queueing_function == "A_star_manhattan": puzzle.heuristicCost = calcManhattanDistance(puzzle) #Push initial node onto priority queue heapq.heappush(PQueue,puzzle) #While queue is not empty #Values still exist in the queue which means search has not #been exhausted(backup in case solvability check fails) while len(PQueue) != 0: #Pop the node with lowest total cost from queue #(Overloaded <= operator in puzzle class) prevPuzzle = heapq.heappop(PQueue) #Check if the puzzle's state is equivalent to the goal state if prevPuzzle.checkIfFinished(): #If true print out completion and the trace #for nodes expanded and maximum nodes in queue print "\nGoal!!" prevPuzzle.printPuzzle() print "\nTo solve this problem the search algorithm expanded a total of", num_expanded, "nodes." print "The maximum number of nodes in the queue at any one time was", max_nodes_in_queue,"." print "The depth of the goal node was", prevPuzzle.depth , "." return #Otherwise, print out trace for next best node to expand print "\nThe best state to expand with a g(n) =",prevPuzzle.depth\ ,"and h(n) =",prevPuzzle.heuristicCost,"is..." #Print out the node that we are expanding prevPuzzle.printPuzzle() print "\nExpanding this node..." #Generate all possible moves(children) for that node puzzle_tree = prevPuzzle.GenerateMoves() #For all the children of the current node popped for puzzle in puzzle_tree: #Generate a list and then convert it into a string #based off the puzzle's state #This will be our key in our dictionary for hashing puzzle_list = [] for list in puzzle.startPuzzle: puzzle_list += list puzzle_key = "" for elem in puzzle_list: puzzle_key += str(elem) #If the key does not exist in our dictionary if puzzle_key not in visited: #Hash in the new node with its respective key #Must convert to tuple since lists are not hashable visited[puzzle_key] = tuple(puzzle_list) #Create the new puzzle to be pushed onto queue #and calculate its respective h(n) value nextPuzzle = Puzzle(puzzle.startPuzzle) if queueing_function == "UniformCostSearch": nextPuzzle.heuristicCost = 0 elif queueing_function == "A_star_misplaced": nextPuzzle.heuristicCost = calcMisplacedTilesDistance(nextPuzzle) elif queueing_function == "A_star_manhattan": nextPuzzle.heuristicCost = calcManhattanDistance(nextPuzzle) #Increment depth counter for children nextPuzzle.depth = prevPuzzle.depth+1 #Push child onto priority queue heapq.heappush(PQueue,nextPuzzle) #Increment number of nodes expanded num_expanded += 1 #If the current number of nodes in queue exceeds #current maximum counter, update maximum if len(PQueue) > max_nodes_in_queue: max_nodes_in_queue = len(PQueue) #Return failure if 2nd check trips #(Should not happen because solvability check should handle) print "This puzzle is not solvable! \n" return -1
def _find_locations(self,puzzle): locations = [None]*16 for i in enumerate(Puzzle.to_list(puzzle)): locations[i[1]] = i[0] return locations
class PuzzleTestLifecycle(unittest.TestCase): def setUp(self): self.p = Puzzle(plugins_dir=join(getcwd(), PATH)) def test_creation_puzzle(self): self.assertIsNotNone("Creating instance of Puzzle.", self.p) def test_loading_plugins(self): self.p.load_plugins() self.assertEqual(self.p.table.size(), 2) def test_resolve_state(self): self.p.load_plugins() self.p.table.resolve_all() for key, plugin in self.p.table_items(): self.assertIsInstance(plugin.state, statemachine.Resolved) def test_active_state(self): self.p.load_plugins() self.p.table.resolve_all() self.p.table.activate_all() for key, plugin in self.p.table_items(): self.assertIsInstance(plugin.state, statemachine.Active) def test_stop_plugin(self): self.p.load_plugins() self.p.table.resolve_all() self.p.table.activate_all() self.p.table.stop_plugin(0) plugin = self.p.table.get_plugin(0) self.assertIsInstance(plugin.state, statemachine.Stopped) def test_restart_plugin(self): self.p.load_plugins() self.p.table.resolve_all() self.p.table.activate_all() self.p.table.stop_plugin(0) self.p.table.restart_plugin(0) plugin = self.p.table.get_plugin(0) self.assertIsInstance(plugin.state, statemachine.Resolved) def test_unregister_no_plugin_refresh(self): self.p.load_plugins() self.p.table.resolve_all() self.p.table.activate_all() self.p.table.stop_plugin(0) self.p.table.unregister_plugin(0, False) self.assertEqual(self.p.table.size(), 1) def test_unregister_plugin_refresh(self): self.p.load_plugins() self.p.table.resolve_all() self.p.table.activate_all() self.p.table.stop_plugin(0) self.p.table.unregister_plugin(0, True) self.assertEqual(self.p.table.size(), 2) def test_resolve_plugin_after_refresh(self): self.p.load_plugins() self.p.table.resolve_all() self.p.table.activate_all() self.p.table.stop_plugin(0) self.p.table.unregister_plugin(0, True) self.p.table.resolve(0) plugin = self.p.table.get_plugin(0) self.assertIsInstance(plugin.state, statemachine.Resolved)
def start( self): if( not self.is_active()): Puzzle.start( self) self._current_position = self._start_position
path - путь для сохранения файлов Выход - файлы с решениями пазла размерностью sizeH на sizeV """ import keras.utils.io_utils as HDF5Matrix import numpy as np from puzzle import Puzzle sizeH = 4 sizeV = 4 file_name = [] number_solution = 0 count = 1000 max_turn = 100 path = 'C:\\Python34\\Puzzle15\\utils\\Solutions\\3x3\\Solution' while number_solution <= count: puzz = Puzzle(sizeH, sizeV) start = puzz.generate_puzzle() print('Start puzzle', start) solution = np.array(puzz.searchSolution()) l = len(solution)-1 # поправка на начальное состоние print(' Have solution in -', l, ' step!') if (l > 0) and (l < max_turn): file_name = path + str(number_solution) + '-' + str(len(solution)) HDF5Matrix.save_array(solution, file_name) number_solution += 1 print('Saving in ', file_name)