def __init__(self):
        """
        Initializes all systems, prepares the game data.
        :return:
        """
        self.picked_items = []
        self.entities = []
        self.settings = Settings()
        self.itemManager = ItemManager("../Databases/items.db")
        self.sortingManager = SortingManager(self.settings)
        self.settingsPanel = SettingsPanel(self)
        self.soundmanager = SoundManager()
        self.gameScreen = FloatLayout(size_hint = (GAME_SCREEN_WIDTH/SCREEN_WIDTH, 1.00))
        self.map = Map(self,"../Databases/map.txt")
        self.pathfinding = Pathfinding(self.map.create_collision_map())

        self.robot = Robot(0.5+self.map.nodesize_x/2.0,0.5+self.map.nodesize_y/2.0)
        self.robot.addToLayout(self.gameScreen)
        self.running = False
        self.time = 0
        Window.size = (SCREEN_WIDTH, SCREEN_HEIGHT)
Exemple #2
0
from collections import deque
from sortingmanager import SortingManager

toSort = deque([deque(),
               deque([4]),
               deque([10]),
               deque([1]),
               deque([8]),
               deque([5]),
               deque([2]),
               deque([9]),
               deque([3]),
               deque([6]),
               deque([7])])
sm = SortingManager(toSort)

print("enter\n1 for option 1\n2 for option 2\n8 for undo\n9 for redo")
while sm.progress[0] != 0:
    print(' ')
    print(sm.sorting_state)
    print((100*sm.progress[0]/sm.progress[1]))
    print(sm.options)
    user_input = input(">")
    if user_input == '1':
        sm.select(0)
    if user_input == '2':
        sm.select(1)
    if user_input == '8':
        sm.undo()
    if user_input == '9':
        sm.redo()
    def __init__(self, parent):

        # Initialise frame
        tkinter.ttk.Frame.__init__(self, parent)
        self.grid(column=0, row=0, sticky="nsew")
        self.parent = parent
        self.parent.columnconfigure(0, weight=1)
        self.parent.rowconfigure(0, weight=1)
        self.parent.title("Sortamajig")
        self.configure(height=400, width=600, cursor='heart')
        self.grid_propagate(False)

        self.leftImageFrame = tkinter.ttk.Frame(self)
        self.leftImageFrame.grid_propagate(False)
        self.leftImageFrame.grid(row=0, column=0, sticky="nwse")

        self.rightImageFrame = tkinter.ttk.Frame(self)
        self.rightImageFrame.grid_propagate(False)
        self.rightImageFrame.grid(row=0, column=1, sticky="nwse")

        self.controlFrame = tkinter.ttk.Frame(self)
        self.controlFrame.grid_propagate(False)
        self.controlFrame.configure(height=180)
        self.controlFrame.grid(row=1, column=0, sticky="nwse", columnspan=2)

        self.columnconfigure(0, pad=0, weight=1)
        self.columnconfigure(1, pad=0, weight=1)
        self.rowconfigure(0, weight=1)

        self.randomButton = tkinter.ttk.Button(self.controlFrame)
        self.randomButton.grid_propagate(False)
        self.randomButton.configure(text="¯\_(ツ)_/¯  Meh!  Either or.", command=self.random_selection)
        self.randomButton.grid(row=0, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.statusLabel = tkinter.ttk.Label(self.controlFrame)
        self.statusLabel.grid_propagate(False)
        self.statusLabel.configure(text="Progress", anchor="center")
        self.statusLabel.grid(row=1, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.saveButton = tkinter.ttk.Button(self.controlFrame)
        self.saveButton.grid_propagate(False)
        self.saveButton.configure(text="Save sorting state", command=self.save)
        self.saveButton.grid(row=2, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.undoButton = tkinter.ttk.Button(self.controlFrame)
        self.undoButton.grid_propagate(False)
        self.undoButton.configure(text="Undo", command=self.undo)
        self.undoButton.grid(row=3, column=0, pady=3, padx=3, sticky="nsew")

        self.redoButton = tkinter.ttk.Button(self.controlFrame)
        self.redoButton.grid_propagate(False)
        self.redoButton.configure(text="Redo", command=self.redo)
        self.redoButton.grid(row=3, column=1, pady=3, padx=3, sticky="nsew")

        self.generateMontageButton = tkinter.ttk.Button(self.controlFrame)
        self.generateMontageButton.grid_propagate(False)
        self.generateMontageButton.configure(text="Generate Output", state=tkinter.DISABLED, command=self.montage)
        self.generateMontageButton.grid(row=4, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.controlFrame.columnconfigure(0, pad=0, weight=1)
        self.controlFrame.columnconfigure(1, pad=0, weight=1)
        self.controlFrame.rowconfigure(0, weight=1)
        self.controlFrame.rowconfigure(1, weight=1)
        self.controlFrame.rowconfigure(2, weight=1)
        self.controlFrame.rowconfigure(3, weight=1)
        self.controlFrame.rowconfigure(4, weight=1)

        self.label1 = TkLabelImage(self.leftImageFrame)
        self.label1.image_behaviour('dynamic', True, 500)
        self.label1.grid_propagate(False)
        self.label1.grid(row=0, column=0, sticky="nwse")
        self.leftImageFrame.columnconfigure(0, pad=0, weight=1)
        self.leftImageFrame.rowconfigure(0, pad=0, weight=1)
        self.label1.configure(text="Frame1", anchor="center")

        self.label2 = TkLabelImage(self.rightImageFrame)
        self.label2.image_behaviour('dynamic', True, 500)
        self.label2.grid_propagate(False)
        self.label2.grid(row=0, column=0, sticky="nwse")
        self.rightImageFrame.columnconfigure(0, pad=0, weight=1)
        self.rightImageFrame.rowconfigure(0, pad=0, weight=1)
        self.label2.configure(text="Frame2", anchor="center")

        self.commandList = []
        self.parent.bind("<Configure>", self.resize)
        self.label1.bind("<Button-1>", self.label1click)
        self.label2.bind("<Button-1>", self.label2click)

        self.sortableDeque = pickle.load(open("sortable.srt", "rb"))
        self.sm = SortingManager(self.sortableDeque)
        self.load_images()

        self.directoryName = "images/"
class MainApplication(tkinter.ttk.Frame):
    def __init__(self, parent):

        # Initialise frame
        tkinter.ttk.Frame.__init__(self, parent)
        self.grid(column=0, row=0, sticky="nsew")
        self.parent = parent
        self.parent.columnconfigure(0, weight=1)
        self.parent.rowconfigure(0, weight=1)
        self.parent.title("Sortamajig")
        self.configure(height=400, width=600, cursor='heart')
        self.grid_propagate(False)

        self.leftImageFrame = tkinter.ttk.Frame(self)
        self.leftImageFrame.grid_propagate(False)
        self.leftImageFrame.grid(row=0, column=0, sticky="nwse")

        self.rightImageFrame = tkinter.ttk.Frame(self)
        self.rightImageFrame.grid_propagate(False)
        self.rightImageFrame.grid(row=0, column=1, sticky="nwse")

        self.controlFrame = tkinter.ttk.Frame(self)
        self.controlFrame.grid_propagate(False)
        self.controlFrame.configure(height=180)
        self.controlFrame.grid(row=1, column=0, sticky="nwse", columnspan=2)

        self.columnconfigure(0, pad=0, weight=1)
        self.columnconfigure(1, pad=0, weight=1)
        self.rowconfigure(0, weight=1)

        self.randomButton = tkinter.ttk.Button(self.controlFrame)
        self.randomButton.grid_propagate(False)
        self.randomButton.configure(text="¯\_(ツ)_/¯  Meh!  Either or.", command=self.random_selection)
        self.randomButton.grid(row=0, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.statusLabel = tkinter.ttk.Label(self.controlFrame)
        self.statusLabel.grid_propagate(False)
        self.statusLabel.configure(text="Progress", anchor="center")
        self.statusLabel.grid(row=1, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.saveButton = tkinter.ttk.Button(self.controlFrame)
        self.saveButton.grid_propagate(False)
        self.saveButton.configure(text="Save sorting state", command=self.save)
        self.saveButton.grid(row=2, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.undoButton = tkinter.ttk.Button(self.controlFrame)
        self.undoButton.grid_propagate(False)
        self.undoButton.configure(text="Undo", command=self.undo)
        self.undoButton.grid(row=3, column=0, pady=3, padx=3, sticky="nsew")

        self.redoButton = tkinter.ttk.Button(self.controlFrame)
        self.redoButton.grid_propagate(False)
        self.redoButton.configure(text="Redo", command=self.redo)
        self.redoButton.grid(row=3, column=1, pady=3, padx=3, sticky="nsew")

        self.generateMontageButton = tkinter.ttk.Button(self.controlFrame)
        self.generateMontageButton.grid_propagate(False)
        self.generateMontageButton.configure(text="Generate Output", state=tkinter.DISABLED, command=self.montage)
        self.generateMontageButton.grid(row=4, column=0, pady=3, padx=3, sticky="nsew", columnspan=2)

        self.controlFrame.columnconfigure(0, pad=0, weight=1)
        self.controlFrame.columnconfigure(1, pad=0, weight=1)
        self.controlFrame.rowconfigure(0, weight=1)
        self.controlFrame.rowconfigure(1, weight=1)
        self.controlFrame.rowconfigure(2, weight=1)
        self.controlFrame.rowconfigure(3, weight=1)
        self.controlFrame.rowconfigure(4, weight=1)

        self.label1 = TkLabelImage(self.leftImageFrame)
        self.label1.image_behaviour('dynamic', True, 500)
        self.label1.grid_propagate(False)
        self.label1.grid(row=0, column=0, sticky="nwse")
        self.leftImageFrame.columnconfigure(0, pad=0, weight=1)
        self.leftImageFrame.rowconfigure(0, pad=0, weight=1)
        self.label1.configure(text="Frame1", anchor="center")

        self.label2 = TkLabelImage(self.rightImageFrame)
        self.label2.image_behaviour('dynamic', True, 500)
        self.label2.grid_propagate(False)
        self.label2.grid(row=0, column=0, sticky="nwse")
        self.rightImageFrame.columnconfigure(0, pad=0, weight=1)
        self.rightImageFrame.rowconfigure(0, pad=0, weight=1)
        self.label2.configure(text="Frame2", anchor="center")

        self.commandList = []
        self.parent.bind("<Configure>", self.resize)
        self.label1.bind("<Button-1>", self.label1click)
        self.label2.bind("<Button-1>", self.label2click)

        self.sortableDeque = pickle.load(open("sortable.srt", "rb"))
        self.sm = SortingManager(self.sortableDeque)
        self.load_images()

        self.directoryName = "images/"

    def random_selection(self):
        true_or_false = random.choice([True, False])
        if true_or_false is True:
            self.label1click(None)
        else:
            self.label2click(None)

    def label1click(self, event):
        self.sm.select(0)
        self.load_images()

    def label2click(self, event):
        self.sm.select(1)
        self.load_images()

    def load_images(self):
        images = self.sm.options
        if images is None:
            images = ["sorted.png", "sorted.png"]

        self.label1.load(images[0])
        self.label2.load(images[1])
        progress = self.sm.progress
        progress_string = ''.join(['Sorting Progress: ', str(progress[1] - progress[0]), ' out of ', str(progress[1])])
        self.statusLabel.configure(text=''.join([progress_string]))
        if self.sm.is_sorted():
            self.generateMontageButton.configure(state=tkinter.NORMAL)
        else:
            self.generateMontageButton.configure(state=tkinter.DISABLED)

    def undo(self):
        self.sm.undo()
        self.load_images()

    def redo(self):
        self.sm.redo()
        self.load_images()

    def save(self):
        pickle.dump(self.sortableDeque, open("sortable.srt", "wb"))
        print("saved")

    def resize(self, event):
        self.label1.fill()
        self.label2.fill()
        pass

    def determine_layout(self, dimensions, padding, width, maximum_height):
        return_value = []
        number_of_images = len(dimensions)
        start = 0
        aspect_ratio_sum = 0
        number_of_images_in_row = 0

        for imm in range(0, number_of_images):
            aspect = dimensions[imm][0] / dimensions[imm][1]
            aspect_ratio_sum += aspect
            number_of_images_in_row += 1
            height = (width - padding * (number_of_images_in_row + 1)) / aspect_ratio_sum
            if height < maximum_height:
                return_value.append([start, imm, height])
                start = imm + 1
                aspect_ratio_sum = 0
                number_of_images_in_row = 0
        if number_of_images_in_row is not 0:
            return_value.append([start, number_of_images - 1, maximum_height])
        return return_value

    def montage(self):
        padding = 30
        canvas_size = [1920, 1080]
        canvas = Image.new("RGB", (1920, 1080), "white")
        dimensions = []

        image_file_names = self.sm.sorting_state[1]

        with open('results.txt', 'w') as result_file:
            for image_file in image_file_names:
                result_file.write(''.join([image_file, '\n']))

        for image_file in image_file_names:
            with Image.open(image_file) as im:
                dimensions.append(im.size)

        total_height = 0
        row_height = 0
        while total_height < canvas_size[1]:
            row_height += 1
            layout = self.determine_layout(dimensions, padding, canvas_size[0], row_height)

            total_height = padding
            for row in layout:
                height = int(row[2])
                if height is 0:
                    height = 1
                total_height += padding + height

        final_row_height = (row_height-1)

        layout = self.determine_layout(dimensions, padding, canvas_size[0], final_row_height)

        vertical_position = padding
        for row in layout:
            horizontal_position = padding
            height = int(row[2])
            if height is 0:
                height = 1

            for image_index in range(row[0], row[1]+1):
                width = int(height * dimensions[image_index][0] / dimensions[image_index][1])
                if width is 0:
                    width = 1
                print(image_file_names[image_index])
                print(width, height)
                image = Image.open(image_file_names[image_index])
                image = image.resize((width, height), Image.ANTIALIAS)
                canvas.paste(image, (horizontal_position, vertical_position))

                horizontal_position += width + padding

            vertical_position += height + padding
        canvas.save("test.png")
class Game:
    def __init__(self):
        """
        Initializes all systems, prepares the game data.
        :return:
        """
        self.picked_items = []
        self.entities = []
        self.settings = Settings()
        self.itemManager = ItemManager("../Databases/items.db")
        self.sortingManager = SortingManager(self.settings)
        self.settingsPanel = SettingsPanel(self)
        self.soundmanager = SoundManager()
        self.gameScreen = FloatLayout(size_hint = (GAME_SCREEN_WIDTH/SCREEN_WIDTH, 1.00))
        self.map = Map(self,"../Databases/map.txt")
        self.pathfinding = Pathfinding(self.map.create_collision_map())

        self.robot = Robot(0.5+self.map.nodesize_x/2.0,0.5+self.map.nodesize_y/2.0)
        self.robot.addToLayout(self.gameScreen)
        self.running = False
        self.time = 0
        Window.size = (SCREEN_WIDTH, SCREEN_HEIGHT)

    def start(self):
        """
        This gets called after user clicks "START" in Settings panel
        Initializes and sets all variables needed for the main game loop
        :return:
        """
        self.running = True
        self.picked_items = []
        self.time = 0
        #remove all previous items (if the game was ran before)
        for item in self.map.items:
            self.map.remove_item(item)

        self.add_items()
        self.closest_item = None
        self.path = self.build_path()
        self.node_id = 0

    def update(self, dt):
        """
        Main game loop, this is where game logic sits
        :param dt: delta time (duration of the frame in seconds)
        :return:
        """
        if(self.running == True):
            self.settings.time
            self.time += dt

            # if time has run out
            if self.time >=  self.settings.time:
                self.end()

            # if all the items are picked
            if len(self.map.items) == 0:
                self.end()

            if(self.robot.moving == False):

                # if robot traveled through the path
                if(len(self.path) == 0):
                    self.end()
                else:
                    # if not, more robot to the next pathfinding node, and increment the node_id varialbe
                    node = self.path[self.node_id]
                    self.robot.moveTo((self.path[self.node_id].x/self.map.gridsize_x)+self.map.nodesize_x/2.0,
                                      (self.path[self.node_id].y/self.map.gridsize_y)+self.map.nodesize_y/2.0)
                    self.node_id += 1

            self.robot.update(dt)
            self.update_pick_item()

    def end(self):
        # called when game should be stopped
        self.running = False
        self.picked_items = self.sortingManager.sort(self.picked_items)
        self.settingsPanel.show_results()

    def update_pick_item(self):
        """
            checks whether robot is colliding with any of the items in the map, if so,
            append it to list of picked items and remove it from map
        """
        for item in self.map.items:
            item_point = Rectangle(item.bounds.position.x,item.bounds.position.y,0.01,0.01)
            if(self.robot.bounds.overlaps(item_point)):
                self.picked_items.append(item)
                self.map.remove_item(item)


    def build_path(self):
        """
            builds a path for the robot to get ALL the items contained in the map
            :return built path
        """
        totalPath = []
        start = Node(int(self.robot.bounds.position.x*self.map.gridsize_x),
                     int(self.robot.bounds.position.y*self.map.gridsize_y))
        for item in self.map.items:
            x = int(item.bounds.position.x*self.map.gridsize_x)
            y = int(item.bounds.position.y*self.map.gridsize_y)
            destination = Node(x,y)
            path = self.pathfinding.astar(start,destination)
            start = Node(x,y)

            for n in path:
                totalPath.append(n)

        return totalPath

    def add_items(self):
        """
            Adds items selected in the Settings Panel to the game map
        :return:
        """
        items = self.settingsPanel.getSelectedItems()
        itemsleft = len(items)
        collision_map = self.map.create_collision_map()
        while(itemsleft > 0):
            randx = int((self.map.gridsize_x)*random())
            randy = int((self.map.gridsize_y)*random())

            if(collision_map[randx][randy] == 0):
                item = items.pop()
                itemsleft = len(items)
                self.map.add_item(randx,randy,item)

    def find_closest_item(self):
        """
            Finds closest item from to the robot
        :return:
        """
        closest = self.map.items[0]
        for item in self.map.items:
            distance = item.bounds.position.distance(self.robot.bounds.position)
            closestDistance = closest.bounds.position.distance(self.robot.bounds.position)
            if(distance < closestDistance):
                closest = item

        return closest

    def collidesWithEntities(self, entity):
        """
            checkes wheter entity collides with any other entity in the map
        :param item:
        :return:
        """
        for e in self.entities:
            if(e.bounds.intersects(entity.bounds)):
                return True
        return False

    def addEntity(self, entity):
        """
            adds entity to the screen
        """
        self.entities.append(entity)
        entity.addToLayout(self.gameScreen)