【发布时间】:2021-05-08 06:53:43
【问题描述】:
我一直在开发基于文本的冒险游戏,正在为游戏构建系统制作骨架。我最初是通过键入 NESW 来使机芯工作的,但在删除调试代码后,它被破坏了一天多。以为我会寻求帮助...
这里是主要问题: 一个网格是自动生成的,坐标对象包含一个字典值,它“canGo”对应于单个字母键和一个布尔值,默认为 False。初始化网格后,我将要激活的坐标列表传递给执行以下功能的网格:(1)它激活传递的列表中的所有网格; (2)它运行一个生成活动方块列表的函数; (3) 它将该列表传递给一个函数,该函数检查每个活动坐标的一个方格并查看它是否处于活动状态,如果是,则将该方向 bool 标记为 True(例如 canGo["N"] = True.
问题:(下面的调试)初始化时正确设置属性,完成后键返回错误但似乎没有再次设置为我的代码中的其他内容。此外,它将所有键设置为同一事物(在这种情况下,所有坐标中的所有键都是 ["S"] = True)
-SD--------
SETTING DIRECTIONG debug
(1, 1) >> N
-SD--------
(1, 1) directions = N
(1, 1){'N': True, 'S': False, 'E': False, 'W': False}
-------------------
-SD--------
SETTING DIRECTIONG debug
(1, 2) >> S
-SD--------
(1, 2) directions = S
(1, 2){'N': False, 'S': True, 'E': False, 'W': False}
-------------------
(1,1): {'N': False, 'S': True, 'E': False, 'W': False}
Which direction would you like to move? <NESW>:
到目前为止的调试:我在里面有调试代码,显示它正确识别激活的网格,正确地将它们传递给列表,并且列表正确设置了 ["canGo"] 坐标属性。在初始化和处理激活的坐标之后,在它询问你想要去哪个方向之前,不会执行任何其他代码。
代码如下...
主要
from coordinates import Coordinates as Coords
from grid import Grid
from player import Player
def main():
gridSizeX = 5
gridSizeY = 5
game = Grid(gridSizeX,gridSizeY, Player("John Doe", 1, 1))
#game.setActiveGridSquares([(1,1),(1,2),(1,3)])
game.grid[1][1].active = True
game.grid[1][2].active = True
game.grid[1][1].setDirections("N")
game.grid[1][2].setDirections("S")
while(True):
x,y = game.player.getLocation()
print("({x},{y}): {canGo}".format(x=x,y=y,canGo=game.grid[x][y].canGo))
move = input("Which direction would you like to move? <NESW>: ")
if(move.upper() == "EXIT"):
break
game.movePlayer(move.upper())
if __name__ == "__main__":
main()
网格
在这里,我传递了一个不可变的元组 (x,y) 列表,然后迭代并分解。错误中方向的主要处理发生在directionsProcessing()中的Grid类下
from coordinates import Coordinates as Coords
from player import Player
class Grid:
"""Builds Grid and takes Player Object to move along grid"""
playerLocation = None
def __init__(self, gridSizeX, gridSizeY, player):
self.grid = self.buildGrid(gridSizeX,gridSizeY)
self.player = player
def buildGrid(self, gridSizeX, gridSizeY):
"""Builds and returns a grid object as a dictionary of [x][y]
Starts at 1 and ends at gridSize(X/Y)
gridSize(X/Y) will be the (x/y) max. -> 5 would be 1 to 5
"""
Grid = {}
for x in range(1, gridSizeX+1):
Grid[x] = {}
for y in range(1, gridSizeY+1):
Grid[x][y] = Coords(x, y)
return Grid
def copyGrid(self):
"""Returns a copy of grid dictionary"""
return self.grid
def setPlayer(self, playerToSet):
"""Sets player object into grid class to allow for player tracking"""
self.player = playerToSet
def setActiveGridSquares(self, squares):
"""Sets a list of grid squares to active"""
for t in squares:
x,y = t
self.grid[x][y].isActive = True
self.solveGridDirections(self.getAllActiveSquares())
def getAllActiveSquares(self):
"""Returns list of all active grid squares"""
activeGridSquares = []
for x in self.grid:
for y in self.grid[x]:
if(self.grid[x][y].isActive):
activeGridSquares.append((self.grid[x][y].x,self.grid[x][y].y))
return activeGridSquares
def solveGridDirections(self, activeSquares):
"""Resolves all active grid squares direction components to
allow movement into nearby active squares"""
for t in activeSquares:
adjoiningDirections = []
x,y = t
#print("Evaluating ActiveSquare: ("+str(x)+","+str(y)+")")
if((x,y+1) in activeSquares):
adjoiningDirections.append("N")
if((x,y-1) in activeSquares):
adjoiningDirections.append("S")
if((x+1,y) in activeSquares):
adjoiningDirections.append("E")
if((x-1,y) in activeSquares):
adjoiningDirections.append("W")
self.grid[x][y].setDirections("".join(adjoiningDirections)) #Sets allowed move directions inside grid
def movePlayer(self, direction):
"""Moves player in direction, preforms coordinate check if player can move"""
if(len(direction) > 1):
print("Lenght must be 1 character ONLY <NESW>")
return
x,y = self.player.getLocation()
print("-MP-------------") #####
print("({x},{y})Can I move in {direction} direction? {tf}".format(x=str(x),y=str(y),direction=direction,tf=str(self.grid[x][y].canGo[direction])))
print("-MP-------------") #####
if(self.grid[x][y].canGo[direction]):
self.player.movePlayer(direction)
else:
print("Player cannot move in that direciton on this grid square.")
坐标
class Coordinates:
"""Set coordinates of path squards in the world"""
actionOnEnter = None
choices = {"a":None,"b":None,"c":None}
canGo = {"N": False,"S": False,"E": False,"W": False}
isActive = False
def __init__(self, x, y):
self.x = x #set x coords
self.y = y #set y coords
def directionsProcessing(self, directions):
"""Directions are processed into a specific order and canGo is amended"""
listOfDirections = ["N", "S", "E", "W"]
verifiedDirections = []
coordsDir = str(self.getCoords())
print(coordsDir+" directions = "+directions) #####
for m in listOfDirections:
if(directions.find(m) != -1):
self.canGo[m] = True
verifiedDirections.append(m)
else:
self.canGo[m] = False
print(coordsDir+str(self.canGo)) #####
print("-------------------") #####
def setDirections(self, direcitons):
"""Sets directions a player can move, updates from initialization"""
print("-SD--------")#####
coordsDir = str(self.getCoords())#####
print("SETTING DIRECTIONG debug")#####
print(coordsDir+" >> "+direcitons)#####
print("-SD--------")#####
self.directionsProcessing(direcitons)
def getCoords(self):
"""Return x,y coordinate duple"""
return self.x,self.y
玩家(不那么重要,但仍然在运动中滚动)
class Player:
"""Player class used to hold player data.
X and Y coords are player's starting coordinates
Control inventory, keys, etc.
"""
inventory = {"sword": False}
keys = {"rectangle": False, "half moon": False}
def __init__(self, name, x, y):
self.name = name
self.x = x
self.y = y
def movePlayer(self, direction):
"""Moves player toards certain coordinates, <NESW>"""
if (len(direction) != 1):
raise Exception("Only 1 letter may be used.")
updown = {"N": 1, "S": -1, "W": -1, "E": 1}
validDirections = ["N","S","E","W"]
if(direction.upper() in validDirections):
if (direction in ["N","S"]):
self.y += updown[direction]
if (direction in ["W","E"]):
self.x += updown[direction]
else:
Exception("Direction is invalid")
def getLocation(self):
"""Returns tuple of player location x,y"""
return self.x,self.y
def setLocation(self, locationTuple):
"""Sets location based on input tuple
Syntax -> Player.setLocation((x,y))
"""
x,y = locationTuple
self.x = x
self.y = y
def toString(self):
"""Converts player data into string"""
return "Player: {name} Location: {x},{y}".format(name=self.name, x=self.x, y=self.y)
【问题讨论】:
-
对我来说代码太多了;您是否将可变值(列表、集合或字典)作为参数传递,所以网格都指的是单个可变值,并且对可变值的任何更改当然在所有网格位置都可见?
-
我正在传递一个不可变的元组 (x,y) 列表,然后它会遍历并分解。主要处理发生在 GRID 下的方向Processing()
-
这是您的代码在执行此操作:在我看来,您正在混淆类和实例属性。您希望
canGo成为实例属性,因此将其初始化从Coord中的位置(这使其成为类属性,即它只有一个值)移动到__init__()方法中作为self.canGo=…检查您拥有的其他类属性,看看它们是否需要类似的处理,以便它们成为实例属性。 -
我没有尝试过这个,但我认为正在发生的事情是如果
canGo是不可变的,例如然后将字符串/整数/元组分配给实例.canGo将创建具有该值的实例属性。然而,由于Coords.canGo是可变的,写入它的实例会更新类属性,因此所有实例都会看到相同的值。