使用(x,y)坐标到达特定“村庄”(Python 3)

1 投票
3 回答
2492 浏览
提问于 2025-04-18 12:53

抱歉,标题跟我的问题不太相关。帮我想个标题,我会改的(如果可以的话)。

我想做的事情是这样的。我会尽量简短明了。

在一个坐标网格(0-9)上,会随机生成一些村庄。每个村庄都有一个类别、坐标和一个随机的村庄名称。

我已经成功地打印出了游戏板。现在我卡在了让玩家输入坐标以查看村庄详细信息的部分。

这是我目前写的代码。

def drawing_board():
board_x = '0 1 2 3 4 5 6 7 8 9'.split()
board_y = '1 2 3 4 5 6 7 8 9'.split()
total_list = [board_x]
for i in range(1,10):
    listy = []
    for e in range(0,9):
        if e == 0:
            listy.append(str(i))
        listy.append('.')
    total_list.append(listy)
return total_list
drawing = drawing_board()
villages = [['5','2'],['5','5'],['8','5']] #I would like these to be random 
                                      #and associated with specific villages.
                                      #(read below)
for i in villages:
    x = int(i[1])
    y = int(i[0])
    drawing[x][y] = 'X'

for i in drawing:
    print(i)
print()
print('What village do you want to view?')

这段代码打印出了游戏板。接下来我在想,能不能创建一个看起来像这样的类:

import random
class new_village():
    def __init__(self):
        self.name = 'Random name'
        x = random.randint(1,9)
        y = random.randint(1,9)
        self.coordinates = [x,y]
        tribe = random.randint(1,2)
        if tribe == 1:
            self.tribe = 'gauls'
        elif tribe == 2:
            self.tribe = 'teutons'

    def getTribe(self):
        print('It is tribe ' +self.tribe)

    def getCoords(self):
        print(str(self.coordinates[0])+','+str(self.coordinates[1]))

现在我卡住的部分是,怎么才能让玩家输入坐标并查看村庄的信息呢?

3 个回答

1

一般来说,你的 getTribe() 函数应该是 返回 部落,而不是 打印 它。不过,我会做的主要事情是创建一个单独的函数,用来测试一组给定的坐标是否和村庄的坐标相同。假设你把你的类改成了这样:

import random

class new_village():
    def __init__(self):
        self.name = 'Random name'
        x = random.randint(1,9)
        y = random.randint(1,9)
        self.coordinates = [x,y]
        tribe = random.randint(1,2)
        if tribe == 1:
            self.tribe = 'gauls'
        elif tribe == 2:
            self.tribe = 'teutons'

    def getTribe(self): return self.tribe

    def getCoords(self): return self.coordinates

    def areCoordinates(self, x, y):
        if [x, y] == self.coordinates: return True
        else: return False

    def printDetails(self):
        print 'Details for the Tribe are: '
        print '\t Tribe:', self.tribe 
        print '\t Coordinates: ', self.coordinates

然后,你有一堆村庄,比如:

In [10]: vs = [new_village() for i in range(3)]

In [11]: for v in vs: print v.getTribe(), v.getCoords()
teutons [8, 6]
gauls [6, 9]
teutons [1, 8]

这样的话,你就可以随时获取与特定坐标对应的村庄:

In [14]: map(lambda v: v.printDetails() , filter(lambda v: v.getCoords() == [8,6]  , vs))
Details for the Tribe are:
         Tribe: teutons
         Coordinates:  [8, 6]
Out[14]: [None]

如果村庄不存在的话:

In [15]: map(lambda v: v.printDetails() , filter(lambda v: v.getCoords() == [2,3]  , vs))
Out[15]: []

注意,代码的结构可能会导致在同一个坐标上生成多个村庄。这可以通过一个谨慎的 if 语句轻松处理。

1

你可以使用 input 来接收用户输入的字符串。因为你需要输入两个坐标,可能需要调用两次这个函数。拿到字符串后,可以通过 int() 把这些位置转换成整数。

如果你想生成随机位置,可以使用 random.randrange()。这个函数的用法是这样的:

num = random.randrange(start, stop) #OR
num = random.randrange(start, stop, step)

这个函数会随机生成一个从 startstop 的数字,但不包括 stop 本身。这和 range() 的用法差不多。第一个方法默认步长是1,而第二个方法你可以指定一个可选的第三个参数,来设置随机整数生成的步长。例如,如果 start = 2stop = 12,而 step = 2,那么它会随机生成一个来自 [2, 4, 6, 8, 10] 的整数。

7

你的代码有几个问题,这些问题让你无法干净利落地解决你的问题。

首先,我建议把 board_xboard_y 设为整数,而不是字符串,因为你在 new_village__init__ 方法里生成的是随机整数。

>>> board_x = list(range(10))
>>> board_y = list(range(1,10))
>>> board_x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> board_y
[1, 2, 3, 4, 5, 6, 7, 8, 9]

另外,我建议你创建一个列表,列出地图上所有还没有村庄的位置,方法如下:

locations = [(x,y) for x in board_x for y in board_y]

现在,你的代码中有一个关键问题,就是两个村庄可能会出现在 完全相同的位置。如果发生这种情况,当用户输入坐标时,你怎么知道应该打印哪个值呢?为了避免这种情况,你可以把 locations 传递给 __init__ 方法。

def __init__(self, locations):
    # sanity check: is the board full?
    if not locations:
        print('board is full!')
        raise ValueError

    # choose random location on the board as coordinates, then delete it from the global list of locations
    self.coordinates = random.choice(locations)
    del locations[locations.index(self.coordinates)]

    # choose name and tribe 
    self.name = 'Random name'
    self.tribe = random.choice(('gauls', 'teutons'))

既然你已经有了一个村庄的类,那么你的列表 villages 应该包含这个类的实例,也就是说,不应该是

villages = [['5','2'],['5','5'],['8','5']]

而应该是

villages = [new_village(locations) for i in range(n)] 

这里的 n 是你想要的村庄数量。为了方便后续查找,我建议创建一个字典,把地图上的位置映射到村庄实例:

villdict = {vill.coordinates:vill for vill in villages}

最后,现在处理用户输入并打印输入位置的村庄值就变得简单了。

>>> inp = tuple(int(x) for x in input('input x,y: ').split(','))
input x,y: 5,4
>>> inp
(5, 4)

你现在可以这样做:

if inp in villdict:
    chosen = villdict[inp]
    print(chosen.name)
    print(chosen.tribe)
else:
    print('this spot on the map has no village')

撰写回答