尽管代码似乎阻止将零添加到列表中,但是列表中出现了意外的0

时间:2017-08-30 19:22:22

标签: python list function class min

我正在使用Python开发基于磁贴的游戏。出于某种原因,如果指定的图块不是左上方的图块或与其相邻,我的函数会找到距指定图块和最近的水图块的距离(在图块空间中),并保持返回0。如果指定的图块本身是水图块,则该函数通常仅返回0。我测试了左上方的瓷砖,即使它是水,它在这种情况下仍然会像它应该的那样返回0,当然也可以正常地与其周围的瓷砖进行任何其他编辑。就像我说的那样,任何与左上方瓷砖不相邻的瓷砖在任何情况下都不会起作用,它总是返回0。

如果我测试一个非水瓦片,那么0应该不会出现的原因是该函数将相对于所有水瓦片测试的瓦片的距离附加到列表,然后找到该列表的最小值并返回它。由于非水瓦片不在水瓦片列表中,因此不应该存在测量指定瓦片与其自身之间的距离的情况,这将导致0.我做了一些自我测试并确认了水瓦片列表确实只包含水瓦片的坐标,当然在功能中指定了指定的瓦片,因此不存在错误。

以下是我的代码。它最初是用codeskulptor编写的,并使用随机模块和simplegui模块,但由于这个问题不涉及其中任何一个我剥离它们。我还删除了与此问题无关的所有代码,所以不要担心试图指出我可能遇到的其他潜在问题。我也为可怕的命名惯例深表歉意。我调整了代码以在Pycharm中工作,以便更多人能够诊断它。非常感谢。

编辑:我注意到我正在谈论这个代码产生的物理空间,当这个版本实际上没有。我会给你一些参考点:

-tiles [0]将位于左上方

-tiles [1]将位于tile [0]

的右侧

-tiles [80]将在tile [0]下面,因为每行是80个瓦片

此外,所讨论的功能是靠近顶部的“distance_from_water”。

def distance(tile1, tile2):
    # returns the distance of two tiles
    return abs((tile2.x - tile1.x) + (tile2.y - tile1.y))


def distance_from_water(tile, index):
    # cycles through every water tile and adds the distances
    # of them relative to a specified tile to a list, then returns
    # the lowest distance
    water_tiles = []
    water_tile_proximities = []
    for element in range(0, len(index)):
        if index[element].iswater == True:
            water_tiles.append(element)
    for element in water_tiles:
        water_tile_proximities.append(distance(index[tile], index[element]))
    lowest_distance = min(water_tile_proximities)
    return lowest_distance


canvaswidth = 1280
canvasheight = 800

tile_size = 16
tile_slots = int((canvaswidth / tile_size) * (canvasheight / tile_size))
tile_slot_locations = [[(tile_size / 2), (tile_size / 2)]]

for element in range(0, (tile_slots - 1)):
    # finds how many discrete locations for tiles there are based on the canvas size
    if tile_slot_locations[element][0] > (canvaswidth - (tile_size / 2)):
        tile_slot_locations[element][0] = (tile_size / 2)
        tile_slot_locations[element][1] += tile_size
    tile_slot_locations.append([((tile_slot_locations[element][0]) + tile_size), tile_slot_locations[element][1]])
tiles = []
colors = ["blue", "green", "darkgreen", "grey", "khaki", "brown"]


class Tile(object):
    list_of_all_tiles = []

    def __init__(self, location, color):
        self.location = location
        self.color = color
        self.dimensions = ((location[0] + (tile_size / 2), location[1] + (tile_size / 2)),
                           (location[0] + (tile_size / 2), location[1] - (tile_size / 2)),
                           (location[0] - (tile_size / 2), location[1] - (tile_size / 2)),
                           (location[0] - (tile_size / 2), location[1] + (tile_size / 2)),
                           (location[0] + (tile_size / 2), location[1] + (tile_size / 2)))
        self.x = (location[0] - (tile_size / 2)) / tile_size
        self.y = (location[1] - (tile_size / 2)) / tile_size
        Tile.list_of_all_tiles.append(self)
        # determine the type
        if color == "blue":
            self.iswater = True
            self.island = False
            self.isforest = False
            self.ismountain = False
            self.issand = False
            self.isinn = False
        if color == "green":
            self.iswater = False
            self.island = True
            self.isforest = False
            self.ismountain = False
            self.issand = False
            self.isinn = False
        if color == "darkgreen":
            self.iswater = False
            self.island = False
            self.isforest = True
            self.ismountain = False
            self.issand = False
            self.isinn = False
        if color == "grey":
            self.iswater = False
            self.island = False
            self.isforest = False
            self.ismountain = True
            self.issand = False
            self.isinn = False
        if color == "khaki":
            self.iswater = False
            self.island = False
            self.isforest = False
            self.ismountain = False
            self.issand = True
            self.isinn = False
        if color == "brown":
            self.iswater = False
            self.island = False
            self.isforest = False
            self.ismountain = False
            self.issand = False
            self.isinn = True


for element in range(0, len(tile_slot_locations)):
    # cycles through and assigns the Tile class
    # using every tile slot location and saves in "tiles" list
    tile = Tile(tile_slot_locations[element], colors[0])
    tiles.append(tile)

tiles[120].island = True
tiles[120].iswater = False
tiles[1].island = True
tiles[1].iswater = False
tiles[80].island = True
tiles[80].iswater = False
tiles[81].island = True
tiles[81].iswater = False
tiles[3].island = True
tiles[3].iswater = False

print(distance_from_water(3, tiles))

2 个答案:

答案 0 :(得分:4)

你的distance()功能从根本上被破坏了 - 如果他们的X差异是他们的Y差异的负面,它能够为任意相隔很远的棋子返回零距离。表达式应为:

abs(tile2.x - tile1.x) + abs(tile2.y - tile1.y)

而不是:

abs((tile2.x - tile1.x) + (tile2.y - tile1.y))

答案 1 :(得分:1)

不幸的是距离不是你唯一的问题。

是一个非常相似的错误
tile_slots = int((canvaswidth / tile_size) * (canvasheight / tile_size))

你最想要的地方

tile_slots = int(canvaswidth / tile_size) * int(canvasheight / tile_size)

在你写的python3中

tile_slots = (canvaswidth // tile_size) * (canvasheight // tile_size)

更多提示

虽然我不认为您的图块表示是理想的,但您可以大规模地缩短确定类型块

# determine the type
self.iswater    = color == "blue"
self.island     = color == "green"
self.isforest   = color == "darkgreen"
self.ismountain = color == "grey"
self.issand     = color == "khaki"
self.isinn      = color == "brown"