import os,time,sys
'''
汉诺塔游戏
练习打印控制
'''
解塔列表=[] # 存放递归解塔的数据
# 使用\033[0;32;1m控制打印颜色,32表示绿色
胜利='''\033[0;32;1m
@@@@@@@@@@@@@@@@@@
@@@@ 胜 利! @@@
@@@@@@@@@@@@@@@@@@\n\033[0m'''
def 移动盘(r,a:list,b:list,c:list):
'''
移动盘
根据输入的字符r,确定各数组的变化,即盘的移动
数字代表每个盘及大小,数组代表每个轴上的盘
'''
if r=='A->B':b,a,c=a[:1] b,a[1:],c # 表示从A轴的最上方取一个盘移动到B轴的最上方,下面类推
elif r=='A->C':c,b,a=a[:1] c,b,a[1:]
elif r=='B->A':a,b,c=b[:1] a,b[1:],c
elif r=='B->C':a,c,b=a,b[:1] c,b[1:]
elif r=='C->A':a,b,c=c[:1] a,b,c[1:]
elif r=='C->B':a,b,c=a,c[:1] b,c[1:]
return [a,b,c]
# time.sleep(3)
def 递归解塔(n,a='A',b='B',c='C'):
'''
原始的汉诺塔解题,并将所有步骤放入解塔列表中
a,b,c代表柱名称
n表示层高
'''
global 解塔列表
if n==1:解塔列表.append(f'{a}->{c}')
else:
递归解塔(n-1,a,c,b)
解塔列表.append(f'{a}->{c}')
递归解塔(n-1,b,a,c)
def 打印控制(a:list,b:list,c:list):
'''
打印控制
根据输入的三个数组,打印当前汉诺塔的图形
'''
gao=len(a b c) 1 # 轴的高度,为塔高加一
nl=lambda a:[0 for _ in range(gao-len(a))] a # 使用0填充每个数组的长度为塔高加一
nls=[[aa,bb,cc] for aa,bb,cc in zip(nl(a),nl(b),nl(c))] # 构建新数组为每行盘的大小,无盘的以0填充
pan=lambda x:x*2 1 # 根据数据计算出盘的大小,也就是宽度,用于控制打印
kuan=pan(max(a b c))*3 3 # 根据最大盘的宽度设定底座的宽度
zhou=int(kuan/3) # 轴间距
打印=''
# 每行的每个轴的字符使用数组控制,并使用打印控制\033[0;31;1m****\033[0m 使其包裹的内容产生颜色效果
打印盘=lambda a:f"{' '*(zhou-a)}\033[0;3{a%6 if a%6>0 else 6};1m{'['*a}{a}{']'*a}\033[0m{' '*(zhou-a 1)}|"
print('','-'*((zhou 1)*6 2)) # 打印上边框
for l in nls: # 遍历每行的三轴的打印字符生成一行字符
for a in l:
打印 =打印盘(a)
print(f'|{打印}')
打印=''
print("| " f"\033[0;36;1m{('#'*(zhou*2))}\033[0m | "*3) # 根据轴间距打印塔底
print('','-'*((zhou 1)*6 2)) # 打印下边框
def 解塔演示(n):
'''
自动演示解开高度为n的汉诺塔
'''
global 解塔列表,胜利
递归解塔(n)
# print(f'总解:{l}')
time.sleep(2)
# 初始化汉诺塔并打印图形
a,b,c=list(range(1,n 1)),[],[]
os.system('cls')
print('电脑演示\n初始','::',[a,b,c])
打印控制(a,b,c)
time.sleep(1)
os.system('cls')
# 图形变化
for i,x in enumerate(解塔列表):
a,b,c=移动盘(x,a,b,c)
print(f'电脑演示\n{n}层汉诺塔第{i 1:0>5}步{x}','::',[a,b,c])
打印控制(a,b,c)
time.sleep(1) # 每打印一次就停留一秒
os.system('cls') # 每打印一次就清理屏幕,生成动态效果
print(f'{n}层汉诺塔第{i 1:0>5}步{x}','::',[a,b,c])
打印控制(a,b,c)
print(胜利)
解塔列表=[]
h=input('是否再来一局(y/n)?')
if h=='y':汉诺塔()
else:sys.exit()
def 汉诺塔():
'''
汉诺塔游戏
输入数值即生成初始的游戏层数
'''
输入='''
输入移动方向,并按回车键
输入“ab”表示从第左边第一柱移动盘到第二柱
输入“ca”表示从第三柱移动盘到第一柱,以此类推
输入“jt”电脑自动移动
输入“n”退出游戏
请输入移动方向:
'''
m=1
global 胜利
while m:
n=input('请输入一个大于0的整数,结束游戏请输入N并回车:')
try:
if n=='n' or n=='N':sys.exit()
else:
n=int(n)
if n==0:print('值不能为0!请重新输入。')
else:m=0;print(f'{n}层汉诺塔游戏开始!')
except:
print('您输入的不是一个整数,请重新输入,或者输入N,结束游戏!')
a,b,c=list(range(1,n 1)),[],[]
d={'a':a,'b':b,'c':c}
os.system('cls')
print(f'{"@"*n*6}--{n}"层汉诺塔游戏"--{"@"*n*6}')
打印控制(a,b,c)
ydl=['ab','ac','ba','bc','ca','cb']
ydd={x:f'{x[0].upper()}->{x[1].upper()}' for x in ydl}
while True:
x=input(输入)
if x in ydl:
y=ydd[x]
if len(d[x[0]])==0:print(f'错误!{y[0]}柱上没有可移动的盘!');continue
elif len(d[x[1]])==0 or d[x[0]][0]<d[x[1]][0]:
a,b,c=移动盘(y,a,b,c)
d={'a':a,'b':b,'c':c}
os.system('cls')
print(f'{"@"*n*6}--{n}"层汉诺塔游戏"--{"@"*n*6}')
打印控制(a,b,c)
if len(c)==n:
print(胜利)
h=input('是否再来一局(y/n)?')
if h=='y':汉诺塔()
else:sys.exit() # 退出程序
continue
else:print('非法移动,请重新输入!')
elif x=='jt':解塔演示(n)
elif x=='n':print('游戏结束!');sys.exit()
else:print('输入错误,请重新输入!')
if __name__ == '__main__':
汉诺塔()
下面是演示效果
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved