将步骤(x,y)坐标列表中的直线运动简化

6
在我的游戏中,我有一个元组列表 (x,y):
solution = [(36, 37), (36, 36), (36, 35), (37, 35), (38, 35),  (38, 34),  (38, 33), (38, 32)]

这个列表描述了玩家从点(36,37)移动到点(38,32)应该执行的动作。

我想将这个列表简化为以下内容:

opti = [(36, 37), (36, 35), (38, 35), (38, 32)]

这意味着我想将任何固定x(或固定y)的一系列步骤缩减为仅第一个和最后一个步骤。

我正在努力想出一种算法来实现这一点。我已经尝试了两个多小时,以下是我目前正在努力解决的问题:

solution = [(36, 37), (36, 36), (36, 35), (37, 35), (38, 35),  (38, 34),  (38, 33), (38, 32)]
opti = [solution[0]]
for i in range(len(solution)):
    if opti[-1][0] == solution[i][0]:
        pass
    elif opti[-1][1] == solution[i][1]:
        pass
    else:
        opti.append(solution[i])

最终,opti等于[(36, 37), (37, 35), (38, 34)],这不是我想要的... 有人可以指导我正确的做法吗?

1
这个“我想要将x固定(或y固定)的步骤系列缩减为仅保留第一步和最后一步”的说法对我来说不是很清楚。为什么(36, 36)被删除而(36, 35)没有被删除呢? - Gabriel
(36, 35)没有被删除,因为它是固定为36的最后一个元素。同时,(36, 35)也标志着第二条直线的开始(其中y固定为35)。这意味着:第一条直线:(36,37)至(36,35), 第二条直线:(36,35)至(38,35), 第三条直线:(38,35)至(38,32) - Bad Player
1
@Gabriel OP 想要固定 x 或固定 y 移动中的第一步和最后一步。 - C.Nivs
2个回答

1
你可以尝试这样做: 当迭代列表(solution)时,将前一个位置和后一个位置与当前位置进行比较,以检查所有点是否在同一条直线上。如果在同一条直线上,则跳过,否则将其添加到最终列表(opti)中。
solution = [(36, 37), (36, 36), (36, 35), (37, 35), (38, 35),  (38, 34),  (38, 33), (38, 32)]
opti = [solution[0]]
for i in range(1, len(solution) -1 ):
    if solution[i-1][0] == solution[i][0] and solution[i][0] == solution[i+1][0]:
        pass
    elif solution[i-1][1] == solution[i][1] and solution[i][1] == solution[i+1][1]:
        pass
    else:
        opti.append(solution[i])
opti.append(solution[-1])

print(opti)

输出:

[(36, 37), (36, 35), (38, 35), (38, 32)]

我希望这能有所帮助,如有疑问请随时联系。

1
完美地工作了,谢谢! 我之前没有想到在末尾添加opti.append(solution[-1])。 在我的尝试中,我也尝试测试i-1和i+1,但我搞错了范围,我使用了for i in range(len(solution)),这导致了索引超出范围的错误。 - Bad Player
不客气。我完全能理解,这种情况发生在每个人身上。祝你好运。 - Kaushal Sharma

1

如果点不在一条直线上,请保留它们。

pad = [(None, None)]
opti = [(x, y)
        for (x0, y0), (x, y), (x1, y1)
            in zip(pad + solution, solution, solution[1:] + pad)
        if not (x0 == x == x1 or y0 == y == y1)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接