python - 如何使用 guizero 知道谁是 python 井字游戏的赢家

标签 python python-3.x tkinter tic-tac-toe guizero

我创建了一个名为 Tic Tac Toe 的游戏。有 2 位玩家,其中一位是 Xs,其中一位是 Os,您所要做的就是在没有其他人阻挡您的情况下连续获得您的符号 3。

游戏的 Gui 看起来像这样:

enter image description here

代码:

from guizero import App, TextBox, PushButton, Text, info

empty = '   '
player = "X"
def clicked(z):
    button = buttonlist[int(z)] # Finds out which button was pressed
    global empty, player
    if button.text != empty:
        pass # If button already pushed do nothing
    else:
        # Marks button with user's go
        button.text = player
        # Switches players
        if player == "X":
            player = "O"
        else:
            player = "X"
    return

def instructions():
    info("Instructions","There are 2 players one of them are Xs one of them are Os. All you have to do is you have to try getting your symbol 3 times in a row without the other player blocking you")
def quit_game():
    app.destroy()
    
app = App(title="Tic Tac Toe", layout="grid", width=200, height=250)
buttonlist = [] # Empty list to contain a list of Buttons

Player1_label = Text(app, text="Player 1",  align="top", grid=[0, 0, 2 , 1])
Player1 = TextBox(app, text=empty, align="top", grid=[2, 0, 3, 1])# Player 1 enters the username

Player2_label = Text(app, text="Player 2",  align="top", grid=[0, 1, 2 , 1])
Player2 = TextBox(app, text=empty, align="top", grid=[2, 1, 3, 1])# Player 2 enters the username

Instructions = PushButton(app, command=instructions, text="Instructions", grid=[0, 5, 3, 1])# Display the instructions
                          
Quit = PushButton(app, command=quit_game ,text="Quit",grid=[10, 0, 3, 2])

# Create Buttons for game, in 3 rows of 3
z=0
for x in range(3):
    for y in range(2, 5):
        buttonlist.append(PushButton(app, text=empty, args=str(z), grid=[x, y], command=clicked))
        z+=1

app.display()

我的问题是显示谁是赢家。我知道如何让一个窗口出现以显示获胜者,执行此操作的行是:

app.info("Tic Tac Toe Winner","获胜者是"+ Player1.value)

但我遇到的问题是在比赛结束时知道谁是赢家,并显示他们是赢家我也觉得找出赢家与 有关buttonlist 我制作的列表,但我不知道该怎么做,所以如果有人能帮助我,我会很感激。

谢谢

最佳答案

不错的游戏。要使用游戏板,我建议创建一个内部数据表示,而不是根据惯例一直使用 gui 元素。

原因是,如果你在任何地方都使用 gui 元素,它可能会更慢,因为它不是理想的数据表示。您无法使用 pickle 等保存数据,并且还对您使用的 gui 框架添加了强烈的依赖性​​。 例如。如果您以后打算将其转换为 Web 应用程序等,您将很难过。

所以我只是创建了一个简单的数据表示,我将字段存储在二维数组中。

# check_win checks if there are three markings
# in one row/column or diagonally
def check_win():
    # the checks array is just a trick to
    # reduce the amount of code,
    # you could avoid it by just adding
    # one nested loop where the outer iterates 
    # over y and the inner over x
    # one with the outer on x and the inner on y
    # and then two others with just one loop
    # for the diagonals
    # the body of the inner loops would
    # esentially look the same as for the while
    # loop below
    checks= [(0, 0, 1, 1), (0, 2, 1, -1)]
    for i in range(3):
        checks.append((i, 0, 0, 1))
        checks.append((0, i, 1, 0))
    won= None
    for y, x, incr_y, incr_x in checks:
        player= field[y][x]
        found= player is not None
        while found and x < 3 and y < 3:
            found= (player == field[y][x])
            y+= incr_y
            x+= incr_x
        if found:
            won= player
            break
    return won

# I also changed your clicked method a bit, so
# it calles the check_win method
# and also changed the signature, so
# it gets the y and x coordinate of the
# button which makes maintaining the
# field array inside the clicked method
# a bit simpler and also seems more natural
# to me
def clicked(y, x):
    button = buttonlist[y][x] # Finds out which button was pressed
    global empty, player
    if button.text != empty:
        pass # If button already pushed do nothing
    else:
        # Marks button with user's go
        button.text = player
        field[y][x] = player
        # Switches players
        if player == "X":
            player = "O"
        else:
            player = "X"
    won= check_win()
    if won is not None:
        print(f'Player {won} has won the game')
    return

# now I initialize the field array
# it will contain None for an untouched
# cell and X/O if taken by the corresponding
# user
field= [[None] * 3 for i in range(3)]
buttonlist= list()

# to get the buttons to call the 
# clicked function with the new
# signature and also maintain the
# buttons in a two dimensional array
# I changed the order of your loops
# and the args argument
for y in range(0, 3):
    rowlist= list()
    buttonlist.append(rowlist)
    for x in range(3):
        rowlist.append(PushButton(app, text=empty, args=(y, x), grid=[x, y+2], command=clicked))
        z+=1

app.display()


# a plain vanilla version of check_win would look something like:

def check_win():
    for start in range(3):
        x= start
        mark= field[0][x]
        for y in range(1, 3):
            if field[y][x] != mark:
                # the sequence is not complete
                mark= None
        if mark is not None:
            # player who set the mark won
            return mark
        y= start
        mark= field[y][0]
        for x in range(1, 3):
            if field[y][x] != mark:
                # the sequence is not complete
                mark= None
        if mark is not None:
            # player who set the mark won
            return mark
    mark= field[0][0]
    for x in range(1, 3):
        if field[y][x] != mark:
            # the sequence is not complete
            mark= None
    if mark is not None:
        # player who set the mark won
        return mark
    mark= field[0][3]
    for x in range(1, 3):
        if field[y][2-x] != mark:
            # the sequence is not complete
            mark= None
    if mark is not None:
        # player who set the mark won
        return mark
    return None        

关于python - 如何使用 guizero 知道谁是 python 井字游戏的赢家,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57744832/

相关文章:

python - TypeError : initial_value must be str or none, 不是 python 3 中的字节?

Python 3.1 NameError 令人头痛

python - 如何组织具有多个窗口和函数的 Tkinter 代码

python - tkinter 照片图像构造函数

python - 为什么 Tkinter 可以是程序化的,而 PyQt 只能与 OO 范式一起使用?

python - 如何在 Mac OS X 上的 Python 交互式 shell 中输入英镑字符 (£)?

python - 操作系统错误 : [Errno 22] Invalid argument in subprocess

python - 想在python中输入一个变量方程来编程

python - 如何在 Python 中装饰控制台记录器消息?

python - 使用 SQLAlchemy、to_sql 使用 pandas 写入 MySQL 数据库