Skip to main content
 首页 » 编程设计

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

2024年11月01日3luoye11

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

游戏的 Gui 看起来像这样:

代码:

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