我正在使用Python编写一个算法,用于玩this游戏。
游戏中瓷砖的当前状态是以字典形式表示的:
{
<tile_id>: {
'counters': <number of counters on tile or None>,
'player': <player id of the player who holds the tile or None>,
'neighbours': <list of ids of neighbouring tile>
},
...
}
我有另一个字典,存储所有“满”的瓷砖(即具有比其邻居少一个计数器且
player
为我自己的瓷砖)。这个名为full_tiles
的字典与上面的board
字典形式相同。我现在正在尝试创建一个列表
chains
,其中列表中的每个元素都是我的至少与一个其他满瓷砖相邻的满瓷砖的字典(即一系列满瓷砖)。因此,这将是我在棋盘上所有单独链的列表。以下是我目前的代码:
for tile_id, tile in full_tiles.items(): #iterates through all full tiles
current_tile = {tile_id : tile} #temporarily stores current tile
if not chains: #if chains list is empty
chains.append(current_tile) #begin list
else: #if list is not empty
for index, chain in enumerate(chains): #iterate though list of chains
if not (current_tile in chain): #if current tile is not in current chain
for tile_id2, tile2 in chain.items(): #iterate through tiles in current chain
for neighbour in tile2["neighbours"]: #iterate through each neighbour of current tile
#neighbour is in the form of tile_id
if neighbour in chain: #if current tile's neighbour is in chain
chain[tile_id] = tile #add tile to chain
由于代码只能在模拟游戏的应用程序中运行,因此对我来说很难测试、调试和检查其是否正常工作。如您所见,这个代码块中有许多嵌套循环,很难跟进。此刻我无法集中思维,无法确定这个混乱的代码是否会按照我的期望正常运行。
在我写这篇文章时,我刚刚意识到——在代码的第7行——我只检查当前图块是否不在当前链中,因此会有相交的链,这当然会是一团糟。我需要首先检查当前图块是否不在任何链中,而不仅仅是一个链。
除了这个错误之外,我的代码能否实现我想要的目标?或者您能否推荐一种更简单、更整洁的方法?(一定有!)
如果我没有提供关于如何运行代码或需要进一步解释的任何信息(例如
board
字典的内容),请告诉我。提前感谢您的任何帮助。
编辑:不幸的是,由于时间限制,我必须完成这个项目,而且这是我第一次使用Python工作,目前我缺乏使用下面给出的资源来优化我的解决方案所需的语言知识。这是我的最终非常丑陋和混乱的解决方案,最终可以正常工作,并且在代码处理的小数据集上效率不太低。
for x in range(0, len(my_hexplode_chains) - 1):
match_found = False
for y in range(x + 1, len(my_hexplode_chains)):
for tile_id_x, tile_x in my_hexplode_chains[x].items(): #compare each chain in list
for tile_id_y, tile_y in my_hexplode_chains[y].items(): #to every other chain
for neighbour in tile_x["neighbours"]: #if tiles in different lists
if neighbour == tile_id_y: #are neighbours
match_found = True
my_hexplode_chains[x].update(my_hexplode_chains[y]) #append one chain to the other
del my_hexplode_chains[y] #delete appended chain
if match_found: #continue loop at next chain
break #very ugly way to do this
if match_found:
break
if match_found:
break
if match_found:
break
Tile
类,并将其映射到一个Tile
列表。 - erip