【问题标题】:How do I get the score to change in the game in Pygame?如何在 Pygame 中更改游戏中的分数?
【发布时间】:2021-02-18 02:34:13
【问题描述】:

我正在尝试在 PyGame 中制作井字游戏,但是当玩家连续获得三个“x”时,我无法改变分数。每当我运行代码时,游戏开始,我可以放置'x's 和'o's,我可以清除棋盘并关闭窗口,但即使有赢家,分数也不会改变。我希望每个“连续三个”都算作一个点。我想要计算分数,当一名球员得到五分时,他们赢得了整场比赛。我尝试将比分打印到终端,但是在一场胜利之后这些数字就搞砸了,但如果你在两轮之间清除棋盘,那应该不是问题。我也没有收到任何错误,所以我不知道从哪里开始。我用谷歌搜索了如何解决这个问题,但没有任何意义或适合这种情况。

我没有任何东西可以检查 'o's 是否赢了,但我将复制/粘贴带有 'x's 的部分并更改一些内容,以便它也适用于 'o's。

我不知道出了什么问题,所以这是我所有的代码:

import pygame
import os
import sys
from pygame.locals import *
pygame.init()

WIDTH, HEIGHT = 500, 500
P_WIDTH, P_HEIGHT = 79, 80
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Tic-Tac-Toe")

main_font = pygame.font.SysFont("Comic sans", 40)
X_WINS = 0
O_WINS = 0
TIES = 0

BG = pygame.transform.scale(pygame.image.load(os.path.join("Board3.jpg")).convert_alpha(), (WIDTH, HEIGHT))
title_label1 = main_font.render("Tic-Tac-Toe", True, (0, 0, 0))
Player_1 = pygame.transform.scale(pygame.image.load(os.path.join("X.png")).convert_alpha(), (P_WIDTH, P_HEIGHT))
Player_2 = pygame.transform.scale(pygame.image.load(os.path.join("O.png")).convert_alpha(), (P_WIDTH, P_HEIGHT))
X_WINS_LABEL = main_font.render(f"X = {X_WINS}", True, (0, 0, 0))
O_WINS_LABEL = main_font.render(f"O = {O_WINS}", True, (0, 0, 0))
TIES_LABEL = main_font.render(f"Ties = {TIES}", True, (0, 0, 0))
X_WON_LABEL = main_font.render("WINNER: X", True, (0, 0, 0))
O_WON_LABEL = main_font.render("WINNER: O", True, (0, 0, 0))

board_state = [[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
                [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None], ]


def redraw_window():
    global Player_1
    global board_state
    global TIES
    global X_WINS
    global X_WINS_LABEL
    global O_WINS_LABEL
    global TIES_LABEL

    WIN.blit(BG, (0, 0))
    WIN.blit(title_label1, (175, 20))
    WIN.blit(X_WINS_LABEL, (100, 450))
    WIN.blit(O_WINS_LABEL, (350, 450))
    WIN.blit(TIES_LABEL, (205, 450))

    y_cursor = 0
    for row in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30):
        x_cursor = 0
        for col in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30):
            if board_state[row][col] == 'x':
                WIN.blit(Player_1, (x_cursor, y_cursor))
            elif board_state[row][col] == 'o':
                WIN.blit(Player_2, (x_cursor, y_cursor))
            x_cursor += WIDTH // 31  # move the cursor across
        y_cursor += HEIGHT // 31  # move the cursor down

    pygame.display.update()


def main():

    while True:
        global X_WINS
        global O_WINS
        global TIES

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit(0)
            elif event.type == pygame.locals.KEYDOWN:

                # Place an "X"
                if event.key == K_1:
                    board_state[7][7] = 'x'
                if event.key == K_2:
                    board_state[7][13] = 'x'
                if event.key == K_3:
                    board_state[7][19] = 'x'
                if event.key == K_4:
                    board_state[13][7] = 'x'
                if event.key == K_5:
                    board_state[13][13] = 'x'
                if event.key == K_6:
                    board_state[13][19] = 'x'
                if event.key == K_7:
                    board_state[19][7] = 'x'
                if event.key == K_8:
                    board_state[19][13] = 'x'
                if event.key == K_9:
                    board_state[19][19] = 'x'

                # Place an "O"
                if event.key == K_q:
                    board_state[7][7] = 'o'
                if event.key == K_w:
                    board_state[7][13] = 'o'
                if event.key == K_e:
                    board_state[7][19] = 'o'
                if event.key == K_a:
                    board_state[13][7] = 'o'
                if event.key == K_s:
                    board_state[13][13] = 'o'
                if event.key == K_d:
                    board_state[13][19] = 'o'
                if event.key == K_z:
                    board_state[19][7] = 'o'
                if event.key == K_x:
                    board_state[19][13] = 'o'
                if event.key == K_c:
                    board_state[19][19] = 'o'

                # Check for wins
                if board_state[7][7] == 'x' and board_state[7][13] == 'x' and board_state[7][19] == 'x':
                    X_WINS += 1
                if board_state[13][7] == 'x' and board_state[13][13] == 'x' and board_state[13][19] == 'x':
                    X_WINS += 1
                if board_state[19][7] == 'x' and board_state[19][13] == 'x' and board_state[19][19] == 'x':
                    X_WINS += 1
                if board_state[7][7] == 'x' and board_state[13][7] == 'x' and board_state[19][7] == 'x':
                    X_WINS += 1
                if board_state[7][13] == 'x' and board_state[13][13] == 'x' and board_state[19][13] == 'x':
                    X_WINS += 1
                if board_state[7][19] == 'x' and board_state[13][19] == 'x' and board_state[19][19] == 'x':
                    X_WINS += 1
                if board_state[7][7] == 'x' and board_state[13][13] == 'x' and board_state[19][19] == 'x':
                    X_WINS += 1
                if board_state[19][7] == 'x' and board_state[13][13] == 'x' and board_state[7][19] == 'x':
                    X_WINS += 1

                # Winning the game
                if X_WINS >= 5:
                    WIN.blit(X_WON_LABEL, (190, 175))
                if O_WINS >= 5:
                    WIN.blit(O_WON_LABEL, (190, 175))

                # Clear the board
                if event.key == K_BACKSPACE:
                    board_state[7][7], board_state[7][13], board_state[7][19], board_state[13][7], board_state[13][13], board_state[13][19], board_state[19][7], board_state[19][13], board_state[19][19] = 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none', 'none'

                # Clear the score
                if event.key == K_DELETE:
                    X_WINS, O_WINS, TIES = 0, 0, 0
        redraw_window()


main()

【问题讨论】:

  • 您创建了一个名为X_WINS_LABEL 的表面一次,而且只有一次,其内容永远不会改变。 X_WINSX_WINS_LABEL 之间没有神奇的关系。当X_WINS 更新时,没有任何合同约束X_WINS_LABEL 进行更新。每次分数变化时,您都需要创建并显示另一个表面。
  • 仅供参考,您可以只用一行创建一个相同的board_state,使用列表理解:board_state = [[None for a in range(31)] for b in range(31)]。通常,如果您在代码中看到大量重复,在大多数情况下您可能可以使用循环来避免它。

标签: python pygame


【解决方案1】:

当X_WINS的值发生变化时,你需要更新X_WINS_LABEL,例如

X_WINS += 1
X_WINS_LABEL = main_font.render(f"X = {X_WINS}", True, (0, 0, 0))

事实上,X_WINS_LABEL 被初始化为一个值但从未改变,更新X_WINS 不会导致X_WINS_LABEL 自行更新。

您还可以通过在重绘时生成消息来一起摆脱X_WINS_LABEL var:

WIN.blit(main_font.render(f"X = {X_WINS}", True, (0, 0, 0)), (100, 450))

这会更简洁一些,因为您不必单独管理获胜次数和标签,但您会更频繁地致电main_font.render。根据呈现消息的成本,这可能是一个值得权衡的选择,也可能不值得。

【讨论】:

  • 我把 "X_WINS_LABEL = main_font.render(f"X = {X_WINS}", True, (0, 0, 0)) " 在所有带有 X_WINS += 1 的 if 语句中,它都算在内赢的次数,但是当我试图清除棋盘时,它也会给刚刚得分的人加分。你知道什么可以解决这个问题吗?
  • 看起来您正在检查每个输入的获胜条件,而不仅仅是玩家移动的输入,因此清除棋盘(或进行另一移动)玩家获胜后)也会增加分数。处理此问题的一种方法是跟踪是否有任何玩家赢得了回合,仅检查没有玩家获胜的胜利条件,并将跟踪回合胜利的变量在清除棋盘时设置为 false,当玩家获胜时设置为 true。跨度>
猜你喜欢
  • 2014-01-24
  • 2014-04-16
  • 2018-06-24
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多