根据字符串所在的位置对地图上的字符串元素进行计数,并用计数填充网格

Count string elements on a map based on where strings are and fill grid with the counts

我有一个名为 my_map 的列表,其中包含两种不同类型的字符串值“.”和 '&'。现在,对于每个值 [x][y] 这是一个 '.'我想计算在“.”旁边的八个方向中的任何一个方向上找到“&”的次数。

我创建了一个网格来存储计数,但我无法正确制定我的条件。我不能使用 numpy 数组。

注意:'S' 和 'E' 被视为“.”

 my_map = ['................' '....&...........' '..........E.....'
 '&&..&...........' '....&&&.........' '......&&&&..&&..'
 '................' '.......&........' '.....&.&........'
 '....S...........' '.......&.&&.....']

def create_grid(my_map):
    grid = [[0]*(len(my_map[0])) for x in range(len(my_map))]
    return grid

grid = create_grid(my_map)

for x, y in [(x,y) for x in range(len(my_map)) for y in range(len(my_map[0]))]:
    #any '&' north ?
    if my_map[x][y+1]== '&' and my_map[x][y]=='.': 
        grid[x][y]+= 1
        #any '&' west ?
        if my_map[x-1][y]== '&' and my_map[x][y]=='.': 
            grid[x][y]+=1
            #any '&' south ?
            if my_map[x][y-1]== '&'and my_map[x][y]=='.': 
                grid[x][y]+=1
                #any '&' east ?
                if my_map[x+1][y]== '&'and my_map[x][y]=='.': 
                    grid[x][y]+=1
                    #any '&' north-east ?
                    if my_map[x+1][y+1] == '&'and my_map[x][y]=='.': 
                        grid[x][y]+=1
                        #any '&' south-west ?
                        if my_map[x-1][y-1] == '&'and my_map[x][y]=='.': 
                            grid[x][y]+=1
                            #any '&' south-east ?
                            if my_map[x+1][y-1]== '&'and my_map[x][y]=='.': 
                                grid[x][y]+=1
                                #any '&' north-west?
                                if my_map[x-1][y+1]== '&'and my_map[x][y]=='.': 
                                    grid[x][y]+=1

 #desired output for first 3 rows
grid = [[0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0],[2,2,1,1,2,1,0,0,0,0,0,0,0,0,0,0]]

此刻,我得到一个 'IndexError: string index out of range'。我不知道如何限制范围所以它仍然是 correct.The 到目前为止我唯一能管理的是一个网格显示所有 '.' 的 1s所有“&”均为 0。

我认为嵌套条件在这里不合适;对于要评估的内部条件,每个外部条件都必须为真。它们应该相互独立且顺序。

手工枚举每一个条件也很费力而且容易出错。对于每个单元格,邻居可能居住的方向最多有 8 个,我们对每个方向进行完全相同的检查。循环是执行此操作的合适构造;每个循环迭代检查一个相邻的单元格,确定它是否在边界内以及是否具有适当的字符。

此外,由于您的网格几乎没有 &,因此只对 & 个字符执行邻居检查是有意义的。对于每一个,增加相邻 . 的计数。如果网格主要是 & 个字符,则执行相反的操作。

my_map = [
    '................', 
    '....&...........',
    '..........E.....',
    '&&..&...........', 
    '....&&&.........', 
    '......&&&&..&&..',
    '................', 
    '.......&........', 
    '.....&.&........',
    '....S...........', 
    '.......&.&&.....'
]

grid = [[0] * len(x) for x in my_map]
directions = [
    [-1, 0], [1, 0], [0, 1], [0, -1], 
    [-1, -1], [1, 1], [1, -1], [-1, 1]
]

for row in range(len(my_map)):
    for col in range(len(my_map[row])):
        if my_map[row][col] == "&":
            for x, y in directions:
                y += row
                x += col

                if y < len(my_map) and y >= 0 and \
                   x < len(my_map[y]) and x >= 0 and \
                   my_map[y][x] != "&":
                    grid[y][x] += 1

for row in grid:
    print(row)

输出:

[0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[2, 2, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 2, 0, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[2, 2, 1, 2, 0, 0, 0, 4, 3, 2, 1, 1, 2, 2, 1, 0]
[0, 0, 0, 1, 2, 4, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0]
[0, 0, 0, 0, 0, 1, 3, 4, 4, 2, 1, 1, 2, 2, 1, 0]
[0, 0, 0, 0, 1, 1, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 1, 3, 2, 3, 2, 2, 1, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1, 0, 0, 0, 0]

与原始地图扫雷风格叠加的版本:

0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 1 & 1 0 0 0 0 0 0 0 0 0 0
2 2 1 2 2 2 0 0 0 0 0 0 0 0 0 0
& & 1 2 & 4 2 1 0 0 0 0 0 0 0 0
2 2 1 2 & & & 4 3 2 1 1 2 2 1 0
0 0 0 1 2 4 & & & & 1 1 & & 1 0
0 0 0 0 0 1 3 4 4 2 1 1 2 2 1 0
0 0 0 0 1 1 3 & 2 0 0 0 0 0 0 0
0 0 0 0 1 & 3 & 2 0 0 0 0 0 0 0
0 0 0 0 1 1 3 2 3 2 2 1 0 0 0 0
0 0 0 0 0 0 1 & 2 & & 1 0 0 0 0

Try it!