Pygame四子棋开发:回合切换函数无法交替执行问题求助
解决Pygame四子棋无法交替玩家回合的问题
看起来你遇到的核心问题是回合切换逻辑没有正确生效,我帮你拆解下问题根源,然后给出修复方案:
问题根源分析
- 全局变量未正确引用:你在
playerOne函数里设置playerOneOver = True,但这个变量在函数内是局部变量,不会修改全局的playerOneOver。因此全局的playerOneOver永远是False,程序会一直重复执行playerOne()。 - 缺少玩家二回合结束的切换逻辑:就算
playerOneOver能成功变为True,playerTwo函数执行完后没有把playerOneOver改回False,导致之后会一直执行playerTwo(),无法切回玩家一。 - 事件处理分散:两个玩家函数里都调用
pg.event.get(),会导致事件被其中一个函数“吃掉”,另一个函数无法响应输入,这也会影响回合切换的流畅性。
修复后的代码方案
我针对上述问题对代码做了修改,同时优化了部分逻辑让代码更简洁:
import pygame as pg # 初始化Pygame(之前遗漏了这关键一步) pg.init() # 窗口、颜色等基础设置 display = pg.display.set_mode((500, 500)) white = (255, 255 , 255) black = (0, 0, 0) red = (255, 0, 0) blue = (0, 0, 255) display.fill(white) # 用简易绘制的棋盘代替图片,避免找不到文件报错(可替换回你的board.png) pg.draw.rect(display, blue, (100, 100, 280, 240), 2) for i in range(7): for j in range(6): pg.draw.circle(display, white, (120 + i*40, 120 + j*40), 15) playerOneOver = False # 初始为玩家一回合 # 优化棋盘数据结构:用二维列表代替6个单独的行变量,更易维护 board = [['b' for _ in range(7)] for _ in range(6)] # 预定义列选择区域,避免循环内重复创建 columns = [pg.Rect(105 + i*45, 70, 30, 30) for i in range(7)] def playerOne(): global playerOneOver # 声明要修改全局变量 chip_color = red # 显示当前轮到玩家一 pg.draw.rect(display, chip_color, (230, 5, 20, 20)) mouse_pressed = pg.mouse.get_pressed() mouse_pos = pg.mouse.get_pos() # 遍历所有列,检查是否被点击 for col_idx, col_rect in enumerate(columns): if col_rect.collidepoint(mouse_pos) and mouse_pressed[0]: # 从最下方行往上找空位置落子 for row_idx in range(5, -1, -1): if board[row_idx][col_idx] == 'b': board[row_idx][col_idx] = 'r' pg.draw.circle(display, chip_color, (120 + col_idx*40, 120 + row_idx*40), 15) playerOneOver = True # 玩家一回合结束 break break def playerTwo(): global playerOneOver # 声明要修改全局变量 chip_color = black # 显示当前轮到玩家二 pg.draw.rect(display, chip_color, (230, 5, 20, 20)) mouse_pressed = pg.mouse.get_pressed() mouse_pos = pg.mouse.get_pos() # 遍历所有列,检查是否被点击 for col_idx, col_rect in enumerate(columns): if col_rect.collidepoint(mouse_pos) and mouse_pressed[0]: # 从最下方行往上找空位置落子 for row_idx in range(5, -1, -1): if board[row_idx][col_idx] == 'b': board[row_idx][col_idx] = 'B' pg.draw.circle(display, chip_color, (120 + col_idx*40, 120 + row_idx*40), 15) playerOneOver = False # 玩家二回合结束,切回玩家一 break break # 游戏主循环 while True: # 统一处理事件,避免事件被单个函数独占 for event in pg.event.get(): if event.type == pg.QUIT: pg.quit() exit() # 重绘列选择区域(清除旧的绘制痕迹) display.fill(white, (100, 60, 300, 40)) for col_rect in columns: pg.draw.rect(display, blue, col_rect) # 回合切换逻辑 if not playerOneOver: playerOne() else: playerTwo() pg.display.flip() # 更新画面 # 打印棋盘状态(调试用,可注释) for row in reversed(board): print(row) print("---")
关键修改点说明
- 全局变量引用:在两个玩家函数中添加
global playerOneOver,确保函数内的赋值能真正修改全局变量,实现回合切换。 - 闭环回合切换:
playerTwo函数执行完后将playerOneOver设为False,让下一轮循环切回玩家一。 - 统一事件处理:把
pg.event.get()移到主循环中,避免事件被单个函数消费,确保所有输入都能被正确响应。 - 优化数据结构:用二维列表
board替代6个单独的行变量,简化落子逻辑的同时让代码更易维护。 - 简化落子判断:通过循环从下往上查找空行,避免重复编写大量
elif判断,减少冗余代码。
这样修改后,就能实现玩家一和玩家二的交替落子了,你可以测试下效果~
内容的提问来源于stack exchange,提问作者Andrew Ely
相关产品推荐
相关产品推荐

