How to restrict image movement to only the frame they're in?

82 Views Asked by At

I have a program that allows you to move an image if you click on the image than click on the square you want it to go. I have two frames, both with the same images but I want to restrict image movement to only the frames that they are currently in.

I have tried to do things like if self.squares[0, dict_rank_pieces or self.white_images] in self.squares[1, pos] but that doesn't work

class Board(tk.Frame):

    def __init__(self, parent, length, width):  # self=Frame, parent=root

        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.length = length
        self.width = width
        self.config(height=100 * self.length, width=100 * self.width)
        self.frame1 = tk.Frame(self)
        self.frame2 = tk.Frame(self)
        self.pack()

        self.square_color = None
        self.squares = {}
        self.ranks = string.ascii_lowercase
        self.white_images = {}  # stores images of pieces
        self.black_images = {}
        self.white_pieces = ["image1", "image2", "image3", "image4", "image5"]
        self.black_pieces = ["image1", "image2", "image3", "image4", "image5"]
        self.buttons_pressed = 0
        self.turns = 0
        self.sq1 = None  # first square clicked
        self.sq2 = None
        self.sq1_button = None  # button associated with the square clicked
        self.sq2_button = None
        self.piece_color = None
        self.set_squares()

    def select_piece(self, button):
        if self.buttons_pressed == 0:
            self.sq1 = list(self.squares.keys())[list(self.squares.values()).index(button)]
            self.sq1_button = button
            self.buttons_pressed += 1

        elif self.buttons_pressed == 1:  # stores square and button of second square selected
            self.sq2 = list(self.squares.keys())[list(self.squares.values()).index(button)]
            self.sq2_button = button
            if self.sq2 == self.sq1:
                self.buttons_pressed = 0
                return
            if True:
                self.squares[self.sq2].config(image=self.sq1_button["image"])
                self.squares[self.sq2].image = self.sq1_button["image"]
                self.squares[self.sq1].config(image=self.white_images["blank.png"])  # clears sq1
                self.squares[self.sq1].image = self.white_images["blank.png"]
                self.buttons_pressed = 0
                return

    def set_squares(self):  # fills frame with buttons representing squares

        for x in range(5):
            for y in range(5):
                for i, frame in enumerate((self.frame1, self.frame2)):
                    pos = self.ranks[x] + str(y + 1)
                    b = tk.Button(frame, bg=self.square_color, activebackground="lawn green")
                    b.grid(row=x, column=y, sticky="nsew")
                    b.config(command=lambda key=b: self.select_piece(key))
                    self.squares[i, pos] = b
    

    def import_pieces(self):  # opens and stores images of pieces and prepares the pieces for the game for both sides
        path = os.path.join(os.path.dirname(__file__), "white")  # stores white pieces images into dicts
        w_dirs = os.listdir(path)
        for file in w_dirs:
            img = Image.open(path + "/" + file)
            img = img.resize((80, 80), Image.Resampling.LANCZOS)
            img = ImageTk.PhotoImage(image=img)
            self.white_images.setdefault(file, img)

    def set_pieces(self):  # places pieces in starting positions
        dict_rank_pieces = {"a": "dirt.png", "b": "fire.png", "c": "metal.png", "d": "water.png", "e": "wood.png"}
        blank_piece = "blank.png"
        for rank in range(1, 6):  # fill rest with blank pieces
            for file in range(5):
                starting_piece = dict_rank_pieces[self.ranks[file]]
                pos = self.ranks[file] + str(rank)
                self.squares[0, pos].config(image=self.white_images[starting_piece if rank == 1 else blank_piece])
                self.squares[1, pos].config(image=self.white_images[starting_piece if rank == 5 else blank_piece])

        self.frame1.pack(side='left')
        self.frame2.pack(side='right')


root = tk.Tk()
root.geometry("800x800")
board = Board(root, 5, 5)
board.import_pieces()
board.set_pieces()
board.mainloop()
1

There are 1 best solutions below

2
acw1668 On BEST ANSWER

As said in my comment of your other question, you can use the key of self.squares, i.e. the values of self.sq1 and self.sq2 which are of the format in (frame_index, position), to determine whether the selected squares are in the same frame:

def select_piece(self, button):
    if self.buttons_pressed == 0:
        ...
    elif self.buttons_pressed == 1:
        ...
        # do nothing if same square is selected
        # or they are not in same frame
        if (self.sq2 == self.sq1) or (self.sq2[0] != self.sq1[0]):
            self.button_pressed = 0
            return
        ...