예제 #1
0
    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)]
예제 #2
0
    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
예제 #3
0
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
예제 #4
0
    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)]
예제 #5
0
    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()
예제 #7
0
 def new_game(self):
     """
     Creates a new Game object.
     """
     return Game(self.sourcefile)
예제 #8
0
                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()
예제 #9
0
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
예제 #10
0
파일: main.py 프로젝트: Karim-1/RushHour
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')