Tkinter:在可伸缩井字游戏中无法进行胜利检查

问题描述 投票:-1回答:1

我正在用Tkinter制作可缩放的井字游戏(这意味着板子的大小可以是2x2,直到适合屏幕的大小)。我正在使用cget("image")查找按钮具有的标记。由于某些原因,胜利检查会显示非常随机的内容。我已经尝试了许多半随机的方法来修复它,但是修复失败。这是代码:

from tkinter import *

class XOGame:
    def main_game(self):
        self.__game_window = Tk()
        self.__grid_size = 3 # User inputted in a different part of the code
        self.__game_window.title("Tic Tac Toe (" + str(self.__grid_size) + "x"
                                     + str(self.__grid_size) + ")")

        # this is user inputted in a different part of the program.
        self.__players = ["p1", "p2"]
        self.__player1 = self.__players[0]
        self.__player2 = self.__players[1]

        self.build_board(self.__game_window)

        self.__game_window.mainloop()


    def build_board(self, window):
        self.__size = self.__grid_size ** 2
        self.__turn_nr = 1
        self.__win = False

        self.__empty_square = PhotoImage(master=window,
                                         file="rsz_empty.gif")
        self.__x = PhotoImage(master=window,
                              file="rsz_cross.gif")
        self.__o = PhotoImage(master=window,
                              file="rsz_nought.gif")

        self.__squares = [None] * self.__size
        self.create_win_check_lists()

        # Building the buttons and gridding them
        for i in range(self.__size):
            self.__squares[i] = (Button(window, image=self.__empty_square))
        row = 0
        column = 0
        number = 1
        for j in self.__squares:

            j.grid(row=row, column=column)
            j.config(command=lambda index=self.__squares.index(j):
                     self.change_mark(index))
            column += 1
            if number % 3 == 0:
                row += 1
                column = 0
            number += 1

# This is the part where the picture changing happens.
    def change_mark(self, i):
        """
            Function changes mark of empty button to either X or O depending on the
            player in turn. It also checks if the change in mark results in a win.
            :param i: The button number, whose mark is being changed
            :return: None
        """
        if self.__turn_nr % 2 == 1:
            self.__player_in_turn = self.__player1

        else:
            self.__player_in_turn = self.__player2

        if self.__player_in_turn == self.__player1:
            self.__mark = self.__x
        else:
            self.__mark = self.__o

        self.__squares[i].configure(image=self.__mark, state=DISABLED)

        self.__turn_nr += 1

        self.check_win(i)

        if self.__win is True:
            print("this is thought to be a win")
        else:
            print("the game thinks this is not a win")

        # Checking if the game tied.
        if self.__turn_nr == self.__size + 1 and not self.__win:
            print("the game thinks it tied.")

    def check_win(self, i):
        """
        Checks if mark placement leads to a win.
        :param i: i is the button location.
        :return: None
        """

                # checks row
        if self.__win == False:
            for row in self.__rows:
                if i + 1 in row:
                    self.__win = self.checksameimage(row)
                    if self.__win == True:
                        break

        # checks column
        if self.__win == False:
            for column in self.__columns:
                if i + 1 in column:
                    self.__win = self.checksameimage(column)
                    if self.__win == True:
                        break

        # if i is in a diagonal, checks one/both diagonals
        if self.__win == False:
            for diag in self.__diagonals:
                if i + 1 in diag:
                    self.__win = self.checksameimage(diag)
                    if self.__win == True:
                        break

        return self.__win

    # checking if all the images are same
    # This is likely where the issue is. Either this part or checkEqual.
    def checksameimage(self, lst):
        images = []
        for nr in lst:
            try:
                images.append(self.__squares[nr].cget("image"))
            except IndexError:
                pass

        return self.checkEqual(images)

    def checkEqual(self, lst):
        """
        Function checks if all elements in a list are equal. Used for checking
        if the dice throws are the same.
        :param lst: The list the check is performed on
        :return: True/False, True if all elements are equal.
        """
        if all(x == lst[0] for x in lst):
            return True
        else:
            return False

    def create_win_check_lists(self):
        """
        Creates lists whose elements are lists of the locations of each spot
        of the game board that belongs to a row/column/diagonal
        :return:
        """

        self.__rows = [[] for _ in range(self.__grid_size)]

        for i in range(self.__grid_size):
            self.__rows[i].append(i + 1)
            for k in range(1, self.__grid_size):
                self.__rows[i].append(i + 1 + self.__grid_size * k)

        self.__columns = [[] for _ in range(self.__grid_size)]

        for i in range(self.__grid_size):
            for j in range(1, self.__grid_size + 1):
                self.__columns[i].append(i * self.__grid_size + j)

        self.getDiagonals(self.__columns)

    def getDiagonals(self, lst):

        self.__diagonals = [[], []]
        self.__diagonals[0] = [lst[i][i] for i in range(len(lst))]
        self.__diagonals[1] = [lst[i][len(lst) - i - 1] for i in
                               range(len(lst))]

    def start(self):
        # Function starts the first window of the game.
        self.main_game()


def main():
    ui = XOGame()
    ui.start()


main()

代码中使用的图像为125x125。这是一个适用于24小时的链接:https://picresize.com/b5df006025f0d8

python tkinter tic-tac-toe
1个回答
0
投票

毫无疑问,您的问题与索引有关。通过将图像更改为对应于索引的文本,我们可以看到每个正方形对应的索引:

尝试更改build_board中的此循环:

    for i in range(self.__size):
        self.__squares[i] = (Button(window, image=self.__empty_square))

改为显示它对应的索引:

    for i in range(self.__size):
        self.__squares[i] = (Button(window, text=str(i)))

然后将lst打印输出传递给checksameimage,您会看到所检查的索引都比预期的高一。

© www.soinside.com 2019 - 2024. All rights reserved.