这段代码有严重的问题。让我们从头开始设计。这将有望成为如何设计和构建类和数据结构的一个很好的教训。
首先,您应该围绕一个Map
类组织您的代码,然后将您的房间表示为一个网格。您不应该考虑“房间 1”、“房间 2”等(在地图上很难跟踪),而应该根据坐标来考虑房间。
现在,我们在开始时会忽略一些可能的特征,包括玩家只看到他去过的房间、玩家留在地图的中心以及对角线路径。如果您想要它们,您可以稍后在基本功能正常工作后将它们放入。现在,我们的目标是看起来有点像这样:
[ ]-[u] [ ] [ ]
|
[ ]-[ ]-[ ] [ ]
|
[ ]-[ ]-[ ] [ ]
|
[ ]-[ ]-[ ]-[ ]
也就是说,我们将其表示为一个网格,其中一些房间相连,而另一些房间则没有。让我们让每个房间都有一个坐标对,有点像这样:
0 1 2 3
0 [ ]-[u] [ ] [ ]
|
1 [ ]-[ ]-[ ] [ ]
|
2 [ ]-[ ]-[ ] [ ]
|
3 [ ]-[ ]-[ ]-[ ]
让 x 沿着顶部,y 沿着侧面。左上角是 (0, 0),[u]
里面是 (0, 1)。
现在,我们Map
类的组件是什么?
地图高度:整数
地图宽度:整数)
player_x, player_y:玩家坐标
可能的路径:我们可以在它们之间移动的成对房间列表。上面的地图将表示为:
[((0, 0), (1, 0)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((1, 1), (2, 1)),
((1, 0), (1, 2)), ((0, 2), (1, 2)), ((1, 2), (2, 2)), ((0, 2), (0, 3)),
((0, 3), (1, 3)), ((1, 3), (2, 3)), ((2, 3), (3, 3))]
请注意,我订购了每一对,以便较大的元组在前(这在以后很重要)。
所以现在我们有了我们的设计,让我们编写那个Map
类!
我可以想到我们想要的四种方法:print_map
、move
和初始化程序。初始化很简单:只需设置我们上面列出的四个属性:
class Map:
def __init__(self, height, width, player_x, player_y, paths):
self.height = height
self.width = width
self.x = player_x
self.y = player_y
self.paths = paths
现在,move
很简单。给定一个方向 n/e/s/w:
def move(self, direction):
if direction == "n":
if ((self.x, self.y - 1), (self.x, self.y)) not in self.paths:
print "Cannot go north"
else:
self.y -= 1
“北”的move
功能只是检查是否有通往我们所在房间上方的路径。
现在最有趣的部分是:打印地图。为此,您可以循环遍历行(0 到self.height
)和列(0 到self.width
)。(注意:您不能print
在这种情况下使用,因为它会自动在字符串后放置换行符或空格。相反,我们使用sys.stdout.write。
def print_map(self):
for y in range(0, self.height):
# print the yth row of rooms
for x in range(0, self.width):
if self.x == x and self.y == y:
sys.stdout.write("[u]") # this is the player's room
else:
sys.stdout.write("[ ]") # empty room
# now see whether there's a path to the next room
if ((x, y), (x + 1, y)) in self.paths:
sys.stdout.write("-")
else:
sys.stdout.write(" ")
# now that we've written the rooms, draw paths to next row
print # newline
for x in range(0, self.width):
sys.stdout.write(" ") # spaces for above room
if ((x, y), (x, y + 1)) in self.paths:
sys.stdout.write("| ")
else:
sys.stdout.write(" ")
print
现在,让我们将它们放在一起并尝试一下。这是代码:
import sys
class Map:
def __init__(self, height, width, player_x, player_y, paths):
self.height = height
self.width = width
self.x = player_x
self.y = player_y
self.paths = paths
def move(self, direction):
if direction == "n":
if ((self.x, self.y - 1), (self.x, self.y)) not in self.paths:
print "Cannot go north"
else:
self.y -= 1
if direction == "s":
if ((self.x, self.y), (self.x, self.y + 1)) not in self.paths:
print "Cannot go south"
else:
self.y += 1
if direction == "e":
if ((self.x, self.y), (self.x + 1, self.y)) not in self.paths:
print "Cannot go east"
else:
self.x += 1
if direction == "w":
if ((self.x - 1, self.y), (self.x, self.y)) not in self.paths:
print "Cannot go west"
else:
self.x -= 1
def print_map(self):
for y in range(0, self.height):
# print the yth row of rooms
for x in range(0, self.width):
if self.x == x and self.y == y:
sys.stdout.write("[u]") # this is the player's room
else:
sys.stdout.write("[ ]") # empty room
# now see whether there's a path to the next room
if ((x, y), (x + 1, y)) in self.paths:
sys.stdout.write("-")
else:
sys.stdout.write(" ")
# now that we've written the rooms, draw paths to next row
print # newline
for x in range(0, self.width):
sys.stdout.write(" ") # spaces for above room
if ((x, y), (x, y + 1)) in self.paths:
sys.stdout.write("| ")
else:
sys.stdout.write(" ")
print
paths = [((0, 0), (1, 0)), ((0, 0), (1, 0)), ((1, 0), (1, 1)), ((1, 1),
(2, 1)), ((1, 1), (1, 2)), ((0, 2), (1, 2)), ((1, 2), (2, 2)),
((0, 2), (0, 3)), ((0, 3), (1, 3)), ((1, 3), (2, 3)), ((2, 3),
(3, 3))]
m = Map(4, 4, 0, 0, paths)
while True:
m.print_map()
direction = raw_input("What direction do you want to move? [n/e/s/w] ")
m.move(direction)
请注意,我在底部添加了一个部分,用于创建地图并允许玩家在其周围移动。这是它运行时的样子:
Davids-MacBook-Air:test dgrtwo$ python Map.py
[u]-[ ] [ ] [ ]
|
[ ] [ ]-[ ] [ ]
|
[ ]-[ ]-[ ] [ ]
|
[ ]-[ ]-[ ]-[ ]
What direction do you want to move? [n/e/s/w] e
[ ]-[u] [ ] [ ]
|
[ ] [ ]-[ ] [ ]
|
[ ]-[ ]-[ ] [ ]
|
[ ]-[ ]-[ ]-[ ]
What direction do you want to move? [n/e/s/w] s
[ ]-[ ] [ ] [ ]
|
[ ] [u]-[ ] [ ]
|
[ ]-[ ]-[ ] [ ]
|
[ ]-[ ]-[ ]-[ ]
What direction do you want to move? [n/e/s/w] w
Cannot go west
[ ]-[ ] [ ] [ ]
|
[ ] [u]-[ ] [ ]
|
[ ]-[ ]-[ ] [ ]
|
[ ]-[ ]-[ ]-[ ]
What direction do you want to move? [n/e/s/w] e
[ ]-[ ] [ ] [ ]
|
[ ] [ ]-[u] [ ]
|
[ ]-[ ]-[ ] [ ]
|
[ ]-[ ]-[ ]-[ ]
可以对这段代码进行许多改进(特别是move
方法是重复的),但这是一个好的开始。尝试制作 20x20 的地图,您会看到它展开得很好。
ETA:我应该注意到print_map
可以用更短的形式重写为:
def print_map(self):
for y in range(0, self.height):
print "".join(["[%s]%s" %
("u" if self.x == x and self.y == y else " ",
"-" if ((x, y), (x + 1, y)) in self.paths else " ")
for x in range(0, self.width)])
print " " + " ".join(["|" if ((x, y), (x, y + 1)) in self.paths
else " " for x in range(0, self.width)])
但这有点激烈。