Candy Crush类OOP项目:Player类legal_length方法实现求助
问题:如何在Player类中获取Board实例属性以实现合法坐标验证?
我正在开发一个仿Candy Crush的OOP项目,包含三个核心类:
- Board类:生成由黄色(Y)、蓝色(B)、粉色(P)水果组成的m*n矩阵棋盘
- main入口:让用户创建棋盘,输入新旧坐标来移动水果(功能未完成)
- Player类:需要实现
legal_length方法,验证用户输入的old_x、old_y、new_x、new_y是否在棋盘范围内,但目前不知道如何在不重复创建Board实例的前提下获取其属性,请求帮助完成该方法。
现有代码
Board类代码
import numpy as np from Player import * class Board: def __init__(self, x=None, y=None): if x is None: x = int(input("Enter the width of the board: ")) if y is None: y = int(input("Enter the height of the board: ")) self.x = x self.y = y self.board_flaeche = np.zeros((x, y), dtype=str) fruits_liste = ["Y", "B", "P"] for i in range(x): for j in range(y): self.board_flaeche[i][j] = np.random.choice(fruits_liste) print(self.board_flaeche) # do I need it?? self.player = Player(0, 0, 0, 0) def move(self): old_x = self.player.getOldX() old_y = self.player.getOldY() new_x = self.player.getNewX() new_y = self.player.getNewY() # Update position of the player instance # self.player.setPosition(new_x, new_y)
Player类代码
# from numpy import np import main from Board import * # from x, y to newX, newY class Player: def __init__(self, old_x, old_y, new_x, new_y): self.old_x = old_x self.old_y = old_y self.new_x = new_x self.new_y = new_y def getOldX(self): return self.old_x def getOldY(self): return self.old_y def getNewX(self): return self.new_x def getNewY(self): return self.new_y # switching positions - not finished yet # def move(self): # Board.board_flaeche[x][y] = Board.board_flaeche[newX][newY] # ToDo: # Task: Write a method legal_length where old_x, old_y, new_x, new_y # must be checked if they are within the self.board_area[i][j] range def legal_length(self): # ToDo Problem: # how do I get the attributes from another class in Python without creating an instance each time pass def setPosition(self, new_x, new_y): pass
Main入口代码
from Board import * from Player import * if __name__ == "__main__": b = Board() while True: old_x_input = int(input("x: ")) old_y_input = int(input("y: ")) new_x_input = int(input("move to newX: ")) new_y_input = int(input("move to newY: ")) p = Player(old_x_input - 1, old_y_input - 1, new_x_input - 1, new_y_input - 1) print(b.board_flaeche) print(b.move())
解决方案
核心思路:让Player持有Board实例引用
不需要重复创建Board实例,而是让Player类在初始化时接收一个Board实例作为参数,通过这个引用直接获取棋盘的尺寸属性,同时解决原代码中的循环导入问题。
修改后的代码示例
1. 重构Player类
class Player: def __init__(self, board, old_x, old_y, new_x, new_y): # 持有Board实例引用,用于获取棋盘尺寸 self.board = board self.old_x = old_x self.old_y = old_y self.new_x = new_x self.new_y = new_y # 保留原有的get方法 def getOldX(self): return self.old_x def getOldY(self): return self.old_y def getNewX(self): return self.new_x def getNewY(self): return self.new_y def legal_length(self): # 通过board实例获取棋盘的宽高 max_x = self.board.x max_y = self.board.y # 验证所有坐标是否在合法范围内(0 <= 坐标 < 棋盘尺寸) old_valid = 0 <= self.old_x < max_x and 0 <= self.old_y < max_y new_valid = 0 <= self.new_x < max_x and 0 <= self.new_y < max_y return old_valid and new_valid def setPosition(self, new_x, new_y): self.old_x = self.new_x self.old_y = self.new_y self.new_x = new_x self.new_y = new_y
2. 重构Board类
移除默认创建的Player实例,改为在move方法中接收Player参数,避免循环依赖:
import numpy as np class Board: def __init__(self, x=None, y=None): if x is None: x = int(input("Enter the width of the board: ")) if y is None: y = int(input("Enter the height of the board: ")) self.x = x self.y = y self.board_flaeche = np.zeros((x, y), dtype=str) fruits_liste = ["Y", "B", "P"] for i in range(x): for j in range(y): self.board_flaeche[i][j] = np.random.choice(fruits_liste) print(self.board_flaeche) def move(self, player): # 先验证坐标合法性 if not player.legal_length(): print("Invalid coordinates!") return # 执行水果交换逻辑 old_x, old_y = player.getOldX(), player.getOldY() new_x, new_y = player.getNewX(), player.getNewY() self.board_flaeche[old_x][old_y], self.board_flaeche[new_x][new_y] = \ self.board_flaeche[new_x][new_y], self.board_flaeche[old_x][old_y] print(self.board_flaeche)
3. 重构Main入口
创建Player时传入Board实例,并调用Board的move方法:
from Board import Board from Player import Player if __name__ == "__main__": b = Board() while True: try: old_x_input = int(input("x: ")) old_y_input = int(input("y: ")) new_x_input = int(input("move to newX: ")) new_y_input = int(input("move to newY: ")) # 创建Player时传入Board实例 p = Player(b, old_x_input - 1, old_y_input - 1, new_x_input - 1, new_y_input - 1) # 调用Board的move方法执行交换 b.move(p) except ValueError: print("Please enter valid integers!")
额外说明
- 解决循环导入:原代码中Board和Player互相import导致循环依赖,修改后Player通过参数接收Board实例,无需提前import Board类。
- 坐标合法性验证:
legal_length方法确保所有坐标都在棋盘的索引范围内,避免数组越界错误。 - OOP设计优化:通过依赖注入的方式传递Board实例,让Player与Board的关系更清晰,代码更易维护和扩展。
内容的提问来源于stack exchange,提问作者CGD 16
相关产品推荐
相关产品推荐

