def __init__(self, sourcefile): self.game = Game(sourcefile) self.archive = {} # initialize first "last move" last_move = [None, 0] # put first possible moves in queue self.queue = [[move] for move in self.game.find_moves(last_move)]
def get_goal_layout(self, goal_moves): """ Creates new game to set moves for the goal layout. """ game = Game(self.sourcefile) for choice in tuple(goal_moves): game.move(choice) game.board.create_layout() return game.board.layout
class BFHybrid(BreadthFirst): """ Creates Breadth First algorithm where first moves are set and goal is a given layout. """ def __init__(self, sourcefile, goal, starting_moves, max_moves): self.game = Game(sourcefile) self.archive = {} self.goal = goal self.max_moves = max_moves # run starting moves for choice in starting_moves: self.game.move(choice) self.game.board.create_layout() self.game.board.draw_board() # put first possible moves in queue if starting_moves: last_move = starting_moves[-1] else: last_move = [None, 0] self.queue = [[move] for move in self.game.find_moves(last_move)] # if no moves possible find moves without last move if not self.queue: last_move = [None, 0] self.queue = [[move] for move in self.game.find_moves(last_move)] def won_game(self): """ Game is won if layout is equal to goal layout. """ if self.game.win(): return 1 elif self.game.board.layout.tobytes() == self.goal.tobytes(): return 2 elif len(self.queue[0]) > self.max_moves: return 3 return False
def __init__(self, sourcefile, goal, starting_moves, max_moves): self.game = Game(sourcefile) self.archive = {} self.goal = goal self.max_moves = max_moves # run starting moves for choice in starting_moves: self.game.move(choice) self.game.board.create_layout() self.game.board.draw_board() # put first possible moves in queue if starting_moves: last_move = starting_moves[-1] else: last_move = [None, 0] self.queue = [[move] for move in self.game.find_moves(last_move)] # if no moves possible find moves without last move if not self.queue: last_move = [None, 0] self.queue = [[move] for move in self.game.find_moves(last_move)]
def find_double_layouts(self): """ Creates all layouts for a moves set and finds duplicates. """ # create a new game, dict for layouts and key pairs list game = Game(self.sourcefile) layout_dict = {} key_pairs = [] # save layout per move for i in range(len(self.moves_set)): game.move(self.moves_set[i]) game.board.create_layout() layout = game.board.layout # if layout is already in dict, save keys as key pair for key in layout_dict: if layout.tobytes() == layout_dict[key].tobytes(): key_pairs.append([key, i]) layout_dict[i] = layout return key_pairs
def __init__(self, sourcefile, outputfile): # initialize variables self.fig = plt.figure() self.ims = [] self.outputfile = outputfile # read outputfile with open(outputfile, "r") as reader: datafile = csv.reader(reader) next(datafile) self.moves_set = [] for row in datafile: self.moves_set.append([row[0], int(row[1])]) # create new game self.game = Game(sourcefile) # removes axes in images plt.xticks([]) plt.yticks([]) # create color map self.colormap()
def new_game(self): """ Creates a new Game object. """ return Game(self.sourcefile)
else: b = moveList[:] b.append(str(move[0].name) +"," + str(move[1])) solve(gameCopy, amountOfMoves, b) if __name__ == '__main__': # initialize best moves list best_moves = [None] * 100000 # play game untill interrupted with ctrl-c try: # while True: # create new game game = Game('data/Rushhour6x6_1.csv') # draw first board game.board.draw_board() # keep track of time t0 = time.perf_counter() solve(game, 0, []) # # make random moves until win # while not game.win() and len(game.moves) <= len(best_moves): # # # find possible moves # valid_moves = game.find_moves()
class BreadthFirst(): """ Creates Breadth First algorithm to solve a Rush Hour board. """ def __init__(self, sourcefile): self.game = Game(sourcefile) self.archive = {} # initialize first "last move" last_move = [None, 0] # put first possible moves in queue self.queue = [[move] for move in self.game.find_moves(last_move)] def get_moves_set(self): """ Returns first item in queue. """ return self.queue.pop(0) def try_moves(self, moves_set): """ Moves cars according to set of moves and creates new layout. """ for choice in tuple(moves_set): self.game.move(choice) self.game.board.create_layout() def won_game(self): if self.game.win(): self.game.board.draw_board() return True return False def not_in_archive(self): """ Checks if layout is already in archive. If not, adds layout to archive. """ if self.game.board.layout.tobytes() not in self.archive: self.archive[self.game.board.layout.tobytes()] = self.game.board.layout.tobytes() return True return False def add_to_queue(self, moves_set): """ Finds new moves and adds to queue. """ new_moves = self.game.find_moves(moves_set[-1]) for new_move in tuple(new_moves): self.queue.append(moves_set + [new_move]) def reverse_moves(self, moves_set): """ Reverses moves that are made to get back to beginning board. """ moves_set.reverse() for choice in tuple(moves_set): self.game.move([choice[0], -choice[1]]) def run(self): """ Runs the Breadth First algorithm untill win or empty queue. Gets moves set from queue, moves those cars, checks for win, checks with archive and adds moves sets to queue. """ # keep track of counter counter = 0 while self.queue: # print depth of tree every 10000 steps if counter % 10000 == 0: print(len(self.queue[0])) # get first moves set from queue moves_set = self.get_moves_set() # move all moves from set self.try_moves(moves_set) # continue branch (add to queue) if layout is not in archive if self.not_in_archive(): self.add_to_queue(moves_set) # check for win if self.won_game(): # return winning set of moves return moves_set # reverse moves to original layout self.reverse_moves(moves_set) # add to counter counter += 1
from code.helpers.show_results import show_results import gameboards if __name__ == "__main__": # initialize first game and board input_board = input( "Please enter the name of the board you want to run (ex: 'gameboards/Rushhour6x6_1.csv'): \n" ) print(input_board) if input_board != 'gameboards/Rushhour6x6_1.csv': # or "'gameboards/Rushhour6x6_2.csv'"or "'gameboards/Rushhour6x6_3.csv'" or "'gameboards/Rushhour9x9_4.csv'" or "'gameboards/Rushhour9x9_5.csv'" or "'gameboards/Rushhour9x9_6.csv'" or "'gameboards/Rushhour12x12_7.csv'": print("You entered an invalid name") sys.exit() lvl1 = Game(input_board) size = lvl1.size gameboard_file = lvl1.gameboard_file board = Board(size, gameboard_file) cars = board.cars # gives user the decision to run an algorithm algorithm = input( "which algorithm would you like to run? \n 1) press 1 for randomize \n 2) press 2 for the cut algorithm \n 3) press 3 for best first search \n 4) press 4 for random BFS \n" ) if algorithm == '1': # line 28-29 run the random algorithm random_run = randomize(board) show_results(random_run[0], random_run[1], random_run[2], random_run[3])
class Visualize: """ Algorithm to create a visualisation for a Rush Hour solution. """ def __init__(self, sourcefile, outputfile): # initialize variables self.fig = plt.figure() self.ims = [] self.outputfile = outputfile # read outputfile with open(outputfile, "r") as reader: datafile = csv.reader(reader) next(datafile) self.moves_set = [] for row in datafile: self.moves_set.append([row[0], int(row[1])]) # create new game self.game = Game(sourcefile) # removes axes in images plt.xticks([]) plt.yticks([]) # create color map self.colormap() def colormap(self): """ Makes the color map based on number of cars in game. """ # colors for vehicles possible_colors = [ "darkorange", "darkgreen", "gold", "navy", "indigo", "steelblue" ] # colors for blank spaces and target car colors = ["white", "red"] # look for the highest ascii value from the cars last_car = max([ ord(car.name[-1]) - ASCII for car in list(self.game.board.cars.values())[:-1] ]) # add color to colormap for all the cars for i in range(last_car - 1): colors.append(possible_colors[i % len(possible_colors)]) self.cmap = ListedColormap(colors) def matrix_to_numbers(self): """ Changes the layout to a matrix of ascii numbers to match the colormap. """ # loop over layout to change to numbers matrix = np.array([[ord(letter) - ASCII for letter in row] for row in self.game.board.layout]) indices = np.where(matrix == VALUE__) xx = np.where(matrix == VALUE_X) matrix[indices] = 0 matrix[xx] = 1 return matrix def create_image(self, matrix): """ Creates images of matrices in matplotlib. """ im = plt.imshow(matrix, animated=True, cmap=self.cmap) self.ims.append([im]) def run(self): """ Runs algorithm to create a gif of a Rush Hour game. """ # create first layout matrix = self.matrix_to_numbers() self.create_image(matrix) # create image per move in game for move in self.moves_set: self.game.move(move) self.game.board.create_layout() matrix = self.matrix_to_numbers() self.create_image(matrix) # create animation and add it to outputmap ani = animation.ArtistAnimation(self.fig, self.ims, interval=400, blit=True, repeat_delay=10000) ani.save(f'{self.outputfile}.gif')