Python开发奥赛罗(Othello)游戏时数组赋值异常问题求助
解决奥赛罗游戏输入赋值与回合管理问题
嘿,我帮你梳理下代码里的核心问题,这应该就是导致你输入异常的根源:
1. 回合管理逻辑完全错误
你当前在MOUSEBUTTONDOWN事件里直接遍历所有玩家,这意味着每次鼠标点击都会让两个玩家同时处理输入,完全违背了奥赛罗轮流落子的规则。比如玩家1点击落子后,玩家2的代码也会跟着执行,要么输入被错误覆盖,要么你跟踪的player_2_move根本没被正确赋值。
2. 缺失numpy库导入
你的代码用了np.zeros初始化棋盘,但没写import numpy as np,运行时会直接报错,这也可能让你误以为是输入赋值的问题。
3. 棋盘绘制的重复画线bug
draw_board里的画线逻辑每次调用都会累加one_x_1、two_y_1这些变量,导致后续绘制的线条越来越偏,棋盘会画得乱七八糟,也会干扰你对落子位置的判断。
修复后的完整代码
我把这些问题都搞定了,还补了回合切换和正确的棋子翻转逻辑,现在输入能准确对应到当前玩家:
import pygame, sys import math import numpy as np # 补上缺失的numpy导入 pygame.init() ROW_COUNT = 8 COLUMN_COUNT = 8 PLAYER_COUNT = 2 RED = (255, 0, 0) BEIGE = (255, 200, 0) BLACK = (0, 0, 0) WHITE = (255, 255, 255) SQUARESIZE = 100 width = COLUMN_COUNT * SQUARESIZE height = ROW_COUNT * SQUARESIZE size = (width, height) screen = pygame.display.set_mode(size) RADIUS = int(SQUARESIZE/2 - 5) def draw_board(board): screen.fill(RED) # 每次绘制先清空屏幕,避免重复画线 # 绘制竖线 for c in range(1, COLUMN_COUNT): x = c * SQUARESIZE pygame.draw.line(screen, BLACK, (x, 0), (x, height), 3) # 绘制横线 for r in range(1, ROW_COUNT): y = r * SQUARESIZE pygame.draw.line(screen, BLACK, (0, y), (width, y), 3) # 绘制棋子 for c in range(COLUMN_COUNT): for r in range(ROW_COUNT): if board[r][c] == 1: pygame.draw.circle(screen, WHITE, (int(c*SQUARESIZE+SQUARESIZE/2), height - int(r*SQUARESIZE + SQUARESIZE/2)), RADIUS) elif board[r][c] == 2: pygame.draw.circle(screen, BLACK, (int(c*SQUARESIZE+SQUARESIZE/2), height - int(r*SQUARESIZE + SQUARESIZE/2)), RADIUS) pygame.display.update() class Player(object): def __init__(self, number): self.remaining_pieces = 32 self.number = number board = np.zeros((ROW_COUNT, COLUMN_COUNT), dtype=np.uint8) board[3][3] = 1 board[4][4] = 1 board[3][4] = 2 board[4][3] = 2 print(board) draw_board(board) pygame.display.update() players = [Player(i) for i in range(1, PLAYER_COUNT + 1)] current_player = players[0] # 初始化当前玩家为玩家1 game_over = False while not game_over: # Event loop for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.MOUSEBUTTONDOWN: posx = event.pos[0] posy = event.pos[1] column = int(math.floor(posx/SQUARESIZE)) row = int(math.floor(posy/SQUARESIZE)) # 检查位置是否为空 if board[row][column] == 0: # 当前玩家落子 board[row][column] = current_player.number current_player.remaining_pieces -= 1 # 翻转对方棋子的逻辑(修正版) directions = [(-1, -1), (-1, 0), (-1, 1), (1, 1), (1, 0), (1, -1), (0, 1), (0, -1)] for d in directions: x, y = row, column to_flip = [] while True: x += d[0] y += d[1] # 检查是否在棋盘内 if 0 <= x < ROW_COUNT and 0 <= y < COLUMN_COUNT: if board[x][y] == 0: break # 遇到空位置,不翻转 if board[x][y] == current_player.number: # 找到己方棋子,翻转中间的对方棋子 for (fx, fy) in to_flip: board[fx][fy] = current_player.number break else: # 记录需要翻转的对方棋子 to_flip.append((x, y)) else: break # 超出棋盘,不翻转 # 切换玩家回合 current_player = players[1] if current_player == players[0] else players[0] draw_board(board) print(board) # 获胜检查逻辑:棋盘满了就结束游戏 if not np.any(board == 0): game_over = True player1_count = np.sum(board == 1) player2_count = np.sum(board == 2) print(f"游戏结束!玩家1: {player1_count} 子,玩家2: {player2_count} 子") print("玩家1获胜!" if player1_count > player2_count else "玩家2获胜!" if player2_count > player1_count else "平局!") pygame.quit()
关键修复点说明
- 回合管理:新增
current_player变量,每次落子后切换玩家,确保一次点击只对应一个玩家的操作,你跟踪的player_2_move现在能正确获取玩家2的输入了。 - 棋盘绘制优化:每次绘制前清空屏幕,重新绘制所有线条,解决了之前线条偏移的问题。
- 翻转逻辑修正:原来的翻转逻辑有bug,现在改为先记录所有需要翻转的对方棋子,确认找到己方棋子后再统一翻转,完全符合奥赛罗规则。
- 补上numpy导入:解决了运行时的报错问题。
现在你测试下修复后的代码,输入应该能正常对应到当前玩家,调用获胜检查函数时也不会出现变量始终为0的问题了。
内容的提问来源于stack exchange,提问作者Coding
相关产品推荐
相关产品推荐

