用ASCII

时间:2018-03-20 17:52:20

标签: python recursion ascii visualization towers-of-hanoi

我熟悉河内塔的递归功能。

现在我需要可视化动作,用星号表示光盘(我猜盘数=星号数是有道理的。)

是否有人提示如何使用

逐步绘制光盘移动
        *                           
       ***                        ***
      *****                      *****            *
     --------------------       -----------------------     ...    

或类似的?

这是我教授提供的示例代码,我确实理解递归是如何工作的。但在Python的一次演讲之后,我必须说我对可视化任务感到有些不知所措。

def hanoi(n, p1, p2, p3):
    if n==1:
        print("move from %d to %d" %(p1, p3))
    else:
        hanoi(n-1, p1, p3, p2)
        print("move from %d to %d " %(p1, p3))
        hanoi(n-1, p2, p1, p3)

    return

if __name__=='__main__':
    j=int(input('Input the number of disk to be moved:\n'))
    print('Number of disk to be move is %d \n'%j)
    hanoi(j, 1, 2, 3)

非常感谢帮助!

1 个答案:

答案 0 :(得分:1)

正如Phi Lipp所说,你需要一个国家的想法。

状态可以通过多种方式表示,但最终目标是您在屏幕上打印的X×Y字符网格。

例如,如果我们想要打印

  *
 ***
*****

我们可以将其作为3x5数组存储在代码中。

[
  [' ', ' ', '*', ' ', ' '],
  [' ', '*', '*', '*', ' '],
  ['*', '*', '*', '*', '*'],
]

然后你可以循环并打印它。

for row in state:
    for character in row:
        print(character, end='')

丑陋的捷径将是

print('\n'.join(''.join(y) for y in x))

现在,如果您将此视为电影,则动画的每一帧都是X x Y数组。每个框架也是代码中的一个打印语句。困难在于改变行动,例如“从1移动到3”,成为州代表。

如果我们使用X by Y数组作为状态,则很难从space1移动到space2,因为字符数组不会告诉您有关环的数量以及环在空间中的大小1。这表明我们需要更好的状态。

这是非常开放的,但是一个解决方案是如果我们应用面向对象的编程,我们可以定义Ring和Tower对象,其中塔是环的集合。因此,动作会在塔之间移动环,并且Rings和Tower对象的状态用于创建X by Y数组。

我会懒惰并将一个环表示为一个整数,而塔是一个3 deques的数组。初始状态看起来像

from collections import deque
towers = [deque([1,2,3]), deque(), deque()]

现在你需要一个从塔U移动到塔V的功能:

def move_ring(from, to):
    top_ring = from.popleft()
    to.append(top_right)

最后,您需要从塔/环状态转换为可打印的X by Y数组。每次渲染每个塔都会更容易,每个环都在:

def render_ring(ring):
    result = '*' * ring  # the character * repeated ring times.
    return result.center(user_input) # add the spaces required

def render_tower(tower):
    result = []
    for ring in tower:
        result.append(render_ring(ring))
    return result

最后,我们希望将塔组合成一个可打印的阵列。您可以使用zip

def render_final(塔):     tower_results = []     塔楼塔楼:         tower_results.append(render_tower(塔))     result = []     对于zip中的all_rows(结果):         result.append( ''。加入(ALL_ROWS))     返回结果

现在您应该能够打印出结果并查看动画的帧。

这可以帮助您走上正确的轨道。请将上面的代码视为伪代码,因为它未经过测试。我也不建议使用整数和deques列表作为您的状态,因为这不会影响代码的清洁度。

还有一件事,如果你打印出结果,它将不会很漂亮,因为文本将打印和向下滚动。但是,如果您使用内置的curses库,则可以获得漂亮的输出。