汉诺塔游戏玩法介绍(攻略和编程实现)

汉诺塔游戏介绍

汉诺塔是根据一个传说形成的数学问题。描述如下:有三根杆子 A、B、C 。 A 杆上 N 个 穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至 C 杆:

  • 每次只能移动一个圆盘
  • 大盘不能叠在小盘上面

可将圆盘临时置于 B 杆,也可将从 A 杆移出的圆盘重新移回 A 杆,但都必须遵循上述两条规则。问:如何移?最少要移动多少次?

最早发明这个问题的人是法国数学家爱德华·卢卡斯。传说越南河内某间寺院有三根银棒,上串 64 个金盘。寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子。预言说当这些盘子移动完毕,世界就会灭亡。这个传说叫做梵天寺之塔问题。但不知道是卢卡斯自创的这个传说,还是他受他人启发。

若传说属实,僧侣们需要 264−12^{64}-1264−1步才能完成这个任务,若他们每秒可完成一个盘子的移动,就需要 5849 亿年才能完成。整个宇宙现在也不过 137 亿年。

这个传说有若干变体:寺院换成修道院、僧侣换成修士等等。寺院的地点众说纷纭,其中一说是位于越南的河内,所以被命名为“河内塔”。另外亦有“金盘是创世时所造”、“僧侣们每天移动一盘”之类的背景设定。

递归解法

这个游戏,只要手机上下个 APP ,N 从小到大玩一会,也就知道其中的套路了。如果有一个盘,那么直接将这个盘从 A 挪到 C即可。如果有两个盘,需要先将小盘挪到 B,大盘挪到 C,再将小盘挪到 C,以此类推……

可以看到,解法的基本思想是递归。假设有 A、B、C 三个塔,A 塔有 N 块盘,目标是把这些盘全部移到 C 塔。那么先把 A 塔顶部的 N-1 块盘移动到 B 塔,再把 A 塔剩下的大盘移到 C,最后把 B 塔的 N-1 块盘移到 C。要先把 N-1 块盘挪到B,就需要先把 N-2 块盘挪到 C……如此递归地使用下去, 就可以求解。从这也可以看到需要总的步数为 2N−12^N-12N−1。

一个简单的 MATLAB 代码如下:

function hanoi2(n)
%a上原有盘数为n的汉诺塔。
han(n,'a','b','c')
function han(n,a,b,c)
if n==1
ex(a,c)
else
han(n-1,a,c,b)
ex(a,c)
han(n-1,b,a,c)
end
function ex(a,b)
disp ([a '-->' b])

非递归算法

事实情况是,在现实生活中,给你这个游戏,你总不能老想着递归的事情,来完成这个游戏吧,对于脑子不灵光的同学,容易搞迷糊。所以,我们当遇到这个游戏的时候,需要一条“黄金准则”,来指导我们完成这个游戏。

我玩了两个小时这个游戏,琢磨出来一个准则,能够在现实生活中指导我们完成这个游戏,本质上还是递归,只不过有一些更好的理解方式。

方法如下,为了描述的方便,我将盘从小到大从 1 开始依次编号。
[

  • 第一步:初始化。先判断 N 是奇数还是偶数,如果是奇数,先挪一个盘到 C,如果是偶数,先挪一个盘到B。
  • 第二步:找 1 所在杆子,数出和 1 的连号数目(例: 123467 ,前 4 个和 1 依次相连,那么连号为 4),假设连号数目为 k。
  • 第三步:找到 k+1 号盘所在的杆,把它挪到除 1 所在的杆之外的另外一个杠(不妨称为其他杆)。
  • 第四步,若 k+1 为奇数,那么将 1 挪到原 k+1 号盘所在的杆,否则,挪到现 k+1 号盘所在的杆(其它杆)。
  • 判断是否结束,没结束,回到第二步。

看起来比较麻烦,顺几遍就知道其中的奥妙了。根据我琢磨出来的这个算法,我也写了个 MATLAB 程序如下:

%% 汉诺塔游戏编程
function Hanoi()
clc
clear
close all
%% 参数设定和初始化
N = 3;
A = N:-1:1;
B = [];
C = [];
State = {A,B,C};
State_desc = {'A','B','C'};
%% 执行第一步
steps = 1;
if mod(N,2)==0State{2} = State{1}(end);disp(['Step' num2str(steps) ':' State_desc{1} '->' State_desc{2}]);
elseState{3} = State{1}(end);disp(['Step' num2str(steps) ':' State_desc{1} '->' State_desc{3}]);
end
State{1}(end) = [];
show_state();%%
while length(State{3})~=N %这是结束的标志steps  = steps + 1;set_ind_contain_one = find_element(1,State{1},State{2},State{3});num_adj = num_adjacent(State{set_ind_contain_one});ele_move = num_adj+1;set_ind_contain_ele_move = find_element(ele_move,State{1},State{2},State{3});left_set_ind = setdiff(1:3, [set_ind_contain_one set_ind_contain_ele_move]) ;State{left_set_ind}(end+1) = State{set_ind_contain_ele_move}(end);State{set_ind_contain_ele_move}(end) = [];disp(['Step' num2str(steps) ':' State_desc{set_ind_contain_ele_move} '->' State_desc{left_set_ind}]);show_state();steps  = steps + 1;if mod(ele_move,2)==1State{set_ind_contain_ele_move}(end+1) = State{set_ind_contain_one}(end);State{set_ind_contain_one}(end) = [];disp(['Step' num2str(steps) ':' State_desc{set_ind_contain_one} '->' State_desc{set_ind_contain_ele_move}]);show_state();else State{left_set_ind}(end+1) = State{set_ind_contain_one}(end);State{set_ind_contain_one}(end) = [];disp(['Step' num2str(steps) ':' State_desc{set_ind_contain_one} '->' State_desc{left_set_ind}]);show_state();endendfunction show_state()disp(['      A=[' num2str(State{1}) ']']);disp(['      B=[' num2str(State{2}) ']']);disp(['      C=[' num2str(State{3})  ']']);endendfunction num = num_adjacent(S)
len = length(S);
diffS = S - (len:-1:1);
num = length(find(diffS==0));
endfunction Set_ind = find_element(ele,A,B,C)
if ismember(ele,A)Set_ind = 1;
elseif ismember(ele,B)Set_ind = 2;
elseSet_ind = 3;
endend

仿真和可视化界面

别人还做了这个游戏的仿真和可视化界面,可以用来学习 MATLAB 的GUI。

对于的程序如下:

hf=figure('name','汗诺塔游戏仿真');    %加标题
axis([0,12,0,12]);     %画坐标
set(hf,'color','w');       %填充背景
hold on;       %保持图形
axis('off');       %隐藏网络线
rectangle('position',[0,0,12,0.5],'FaceColor',[0,1.0,0]);    %画底版
line([3;3],[0.5,8],'color','r','linestyle','-','linewidth',1.5);
line([6;6],[0.5,8],'color','r','linestyle','-','linewidth',1.5);
line([9;9],[0.5,8],'color','r','linestyle','-','linewidth',1.5);    %画出三条路线
a=line([3;3],[0.5,1.0],'color','c','linestyle','-','linewidth',65); %画出一号长方体木块
b=line([3;3],[1.0,1.5],'color','b','linestyle','-','linewidth',45);%画出二号长方体木块
c=line([3;3],[1.5,2.0],'color','k','linestyle','-','linewidth',30); %画出三号长方体木块
d=line([3;3],[2.0,2.5],'color','y','linestyle','-','linewidth',25);%画出四号长方体木块e=line([3;3],[2.5,3.0],'color','m','linestyle','-','linewidth',15);%画出五号长方体木块%设置五木板的运动
%设置五号长方体木块的运动,竖直向上运动到第一条路线的最上方
t1=2.5;  dt=0.05;
while t1<=8t1=t1+dt;set(e,'xdata',[3;3],'ydata',[t1;t1+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第三条路线的最上方
t2=3;   dt=0.05;
while t2<=9t2=t2+dt;set(e,'xdata',[t2;t2],'ydata',[t1;t1+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第三条路线的下方
t3=8;   dt=0.05;
while t3>=0.5t3=t3-dt;set(e,'xdata',[9;9],'ydata',[t3;t3+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置四号长方体木块的运动,竖直向上运动到第一条路线的最上方
t4=2.0;   dt=0.05;
while t4<=8t4=t4+dt;set(d,'xdata',[3;3],'ydata',[t4;t4+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end           % 设置四号长方体木块的运动,水平运动到第二条路线的最上方
t5=3;   dt=0.05;
while t5<=6t5=t5+dt;set(d,'xdata',[t5;t5],'ydata',[t4;t4+0.5]);drawnow;    set(gcf,'doublebuffer','on');    %消除震动
end     % 设置四号长方体木块的运动,竖直向下运动到第二条路线的最下方
t6=8;   dt=0.05;
while t6>=0.5t6=t6-dt;set(d,'xdata',[6;6],'ydata',[t6;t6+0.5]);drawnow;  set(gcf,'doublebuffer','on');    %消除震动
end        %设置五号长方体木块的运动,竖直向上运动到第三条路线的最上方
t7=0.5;   dt=0.05;
while t7<=8t7=t7+dt;set(e,'xdata',[9;9],'ydata',[t7;t7+0.5]);drawnow;    set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,水平运动到第二条路线的最上方
t8=9;   dt=0.05;
while t8>=6t8=t8-dt;set(e,'xdata',[t8;t8],'ydata',[t7;t7+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第二条路线的下方
t9=8;    dt=0.05;
while t9>=1.0t9=t9-dt;set(e,'xdata',[6;6],'ydata',[t9;t9+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end           % 设置三号长方体木块的运动,竖直向上运动到第一条路线的上方
t10=1.5;    dt=0.05;
while t10<=8t10=t10+dt;set(c,'xdata',[3;3],'ydata',[t10;t10+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置三号长方体木块的运动,水平运动到第三条路线的上方
t11=3;    dt=0.05;
while t11<=9t11=t11+dt;set(c,'xdata',[t11;t11],'ydata',[t10;t10+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end         % 设置三号长方体木块的运动,竖直向下运动到第三条路线的下方
t12=8;    dt=0.05;
while t12>=0.5t12=t12-dt;set(c,'xdata',[9;9],'ydata',[t12;t12+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end     % 设置五号长方体木块的运动,竖直向上运动到第二条路线的上方
t13=1;   dt=0.05;
while t13<=8t13=t13+dt;set(e,'xdata',[6;6],'ydata',[t13;t13+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,水平运动到第一条路线的最上方
t14=6;   dt=0.05;
while t14>=3t14=t14-dt;set(e,'xdata',[t14;t14],'ydata',[8;8+0.5]);drawnow;set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第一条路线的下方
t15=8;   dt=0.05;
while t15>=1.5t15=t15-dt;set(e,'xdata',[3;3],'ydata',[t15;t15+0.5]);drawnow; set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向上运动到第二条路线的上方
t16=0.5;  dt=0.05;
while t16<=8t16=t16+dt;set(d,'xdata',[6;6],'ydata',[t16;t16+0.5]);drawnow;   set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,水平运动到第三条路线的上方
t17=6;   dt=0.05;
while t17<=9t17=t17+dt;set(d,'xdata',[t17;t17],'ydata',[8;8.5]);drawnow;set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向下运动到第三条路线的下方
t18=8;dt=0.05;
while t18>=1t18=t18-dt;set(d,'xdata',[9;9],'ydata',[t18;t18+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第一条路线的上方
t19=1.0;dt=0.05;
while t19<=8t19=t19+dt;set(e,'xdata',[3;3],'ydata',[t19;t19+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end          % 设置五号长方体木块的运动,水平运动到第三条路线的上方
t20=3;dt=0.05;
while t20<=9t20=t20+dt;set(e,'xdata',[t20;t20],'ydata',[8;8.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第三条路线的下方
t21=8; dt=0.05;
while t21>=1.5t21=t21-dt;set(e,'xdata',[9;9],'ydata',[t21;t21+0.5]);drawnow;set(gcf,'doublebuffer','on');    %消除震动
end
% 设置二号长方体木块的运动,竖直向上运动到第一条路线的上方
t22=1.0;  dt=0.05;
while t22<=8t22=t22+dt;set(b,'xdata',[3;3],'ydata',[t22;t22+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置二号长方体木块的运动,水平运动到第二条路线的上方
t23=3;   dt=0.05;
while t23<=6t23=t23+dt;set(b,'xdata',[t23;t23],'ydata',[t22;t22+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置二号长方体木块的运动,竖直向下运动到第二条路线的最下方
t24=8;   dt=0.05;
while t24>=0.5t24=t24-dt;set(b,'xdata',[6;6],'ydata',[t24;t24+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第三条路线的上方
t25=1.5;  dt=0.05;
while t25<=8t25=t25+dt;set(e,'xdata',[9;9],'ydata',[t25;t25+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,水平运动到第二条路线的上方
t26=9;   dt=0.05;
while t26>=6t26=t26-dt;set(e,'xdata',[t26;t26],'ydata',[t25;t25+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第二条路线的下方
t27=8;   dt=0.05;
while t27>=1.0t27=t27-dt;set(e,'xdata',[6;6],'ydata',[t27;t27+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向上运动到第三条路线的上方
t28=1.5;  dt=0.05;
while t28<=8t28=t28+dt;set(d,'xdata',[9;9],'ydata',[t28;t28+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,水平运动到第一条路线的上方
t29=9;   dt=0.05;
while t29>=3t29=t29-dt;set(d,'xdata',[t29;t29],'ydata',[t28;t28+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向下运动到第一条路线的下方
t30=8;   dt=0.05;
while t30>=1.0t30=t30-dt;set(d,'xdata',[3;3],'ydata',[t30;t30+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第二条路线的上方
t31=1.0;  dt=0.05;
while t31<=8t31=t31+dt;set(e,'xdata',[6;6],'ydata',[t31;t31+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,水平运动到第一条路线的上方
t32=6;   dt=0.05;
while t32>=3t32=t32-dt;set(e,'xdata',[t32;t32],'ydata',[t31;t31+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第一条路线的下方
t33=8;   dt=0.05;
while t33>=1.5t33=t33-dt;set(e,'xdata',[3;3],'ydata',[t33;t33+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置三号长方体木块的运动,竖直向上运动到第三条路线的上方
t34=0.5;  dt=0.05;
while t34<=8t34=t34+dt;set(c,'xdata',[9;9],'ydata',[t34;t34+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置三号长方体木块的运动,水平运动到第二条路线的上方
t35=9;   dt=0.05;
while t35>=6t35=t35-dt;set(c,'xdata',[t35;t35],'ydata',[t34;t34+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置三号长方体木块的运动,竖直向下运动到第二条路线的下方
t36=8;   dt=0.05;
while t36>=1.0t36=t36-dt;set(c,'xdata',[6;6],'ydata',[t36;t36+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第三条路线的上方
t37=1.5;  dt=0.05;
while t37<=8t37=t37+dt;set(e,'xdata',[3;3],'ydata',[t37;t37+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第三条路线的最上方
t38=3;   dt=0.05;
while t38<=9t38=t38+dt;set(e,'xdata',[t38;t38],'ydata',[t37;t37+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第三条路线的下方
t39=8;   dt=0.05;
while t39>=0.5t39=t39-dt;set(e,'xdata',[9;9],'ydata',[t39;t39+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向上运动到第二条路线的上方
t40=2.5;  dt=0.05;
while t40<=8t40=t40+dt;set(d,'xdata',[3;3],'ydata',[t40;t40+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置四号长方体木块的运动,水平运动到第二条路线的最上方
t41=3;   dt=0.05;
while t41<=6t41=t41+dt;set(d,'xdata',[t41;t41],'ydata',[t40;t40+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向下运动到第二条路线的下方
t42=8;   dt=0.05;
while t42>=1.5t42=t42-dt;set(d,'xdata',[6;6],'ydata',[t42;t42+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第三条路线的上方
t43=0.5;  dt=0.05;
while t43<=8t43=t43+dt;set(e,'xdata',[9;9],'ydata',[t43;t43+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第二条路线的最上方
t44=9;   dt=0.05;
while t44>=6t44=t44-dt;set(e,'xdata',[t44;t44],'ydata',[t43;t43+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第二条路线的下方
t45=8;   dt=0.05;
while t45>=2.0t45=t45-dt;set(e,'xdata',[6;6],'ydata',[t45;t45+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置一号长方体木块的运动,竖直向上运动到第一条路线的上方
t46=0.5;  dt=0.05;
while t46<=8t46=t46+dt;set(a,'xdata',[3;3],'ydata',[t46;t46+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置一号长方体木块的运动,水平运动到第三条路线的最上方
t47=3;   dt=0.05;
while t47<=9t47=t47+dt;set(a,'xdata',[t47;t47],'ydata',[t46;t46+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置一号长方体木块的运动,竖直向下运动到第三条路线的最下方
t48=8;   dt=0.05;
while t48>=0.5t48=t48-dt;set(a,'xdata',[9;9],'ydata',[t48;t48+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第二条路线的上方
t49=2.0;  dt=0.05;
while t49<=8t49=t49+dt;set(e,'xdata',[6;6],'ydata',[t49;t49+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第一条路线的最上方
t50=6;   dt=0.05;
while t50>=3t50=t50-dt;set(e,'xdata',[t50;t50],'ydata',[t49;t49+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第一条路线的最下方
t51=8;   dt=0.05;
while t51>=0.5t51=t51-dt;set(e,'xdata',[3;3],'ydata',[t51;t51+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向上运动到第二条路线的上方
t52=1.5;  dt=0.05;
while t52<=8t52=t52+dt;set(d,'xdata',[6;6],'ydata',[t52;t52+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置四号长方体木块的运动,水平运动到第三条路线的最上方
t53=6;   dt=0.05;
while t53<=9t53=t53+dt;set(d,'xdata',[t53;t53],'ydata',[t52;t52+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向下运动到第三条路线的下方
t54=8;   dt=0.05;
while t54>=1.0t54=t54-dt;set(d,'xdata',[9;9],'ydata',[t54;t54+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第一条路线的上方
t55=0.5;  dt=0.05;
while t55<=8t55=t55+dt;set(e,'xdata',[3;3],'ydata',[t55;t55+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第三条路线的最上方
t56=3;   dt=0.05;
while t56<=9t56=t56+dt;set(e,'xdata',[t56;t56],'ydata',[t55;t55+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第三条路线的下方
t57=8;   dt=0.05;
while t57>=1.5t57=t57-dt;set(e,'xdata',[9;9],'ydata',[t57;t57+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置三号长方体木块的运动,竖直向上运动到第二条路线的最上方
t58=1.0;  dt=0.05;
while t58<=8t58=t58+dt;set(c,'xdata',[6;6],'ydata',[t58;t58+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置三号长方体木块的运动,水平运动到第一条路线的最上方
t59=6;   dt=0.05;
while t59>=3t59=t59-dt;set(c,'xdata',[t59;t59],'ydata',[t58;t58+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置三号长方体木块的运动,竖直向下运动到第一条路线的最下方
t60=8;   dt=0.05;
while t60>=0.5t60=t60-dt;set(c,'xdata',[3;3],'ydata',[t60;t60+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第三条路线的上方
t61=1.5;  dt=0.05;
while t61<=8t61=t61+dt;set(e,'xdata',[9;9],'ydata',[t61;t61+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第二条路线的最上方
t62=9;   dt=0.05;
while t62>=6t62=t62-dt;set(e,'xdata',[t62;t62],'ydata',[t61;t61+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第二条路线的下方
t63=8;   dt=0.05;
while t63>=1.0t63=t63-dt;set(e,'xdata',[6;6],'ydata',[t63;t63+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向上运动到第三条路线的最上方
t64=1.0;  dt=0.05;
while t64<=8t64=t64+dt;set(d,'xdata',[9;9],'ydata',[t64;t64+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置四号长方体木块的运动,水平运动到第一条路线的最上方
t65=9;   dt=0.05;
while t65>=3t65=t65-dt;set(d,'xdata',[t65;t65],'ydata',[t64;t64+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向下运动到第一条路线的下方
t66=8;   dt=0.05;
while t66>=1.0t66=t66-dt;set(d,'xdata',[3;3],'ydata',[t66;t66+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第二条路线的最上方
t67=1.0;  dt=0.05;
while t67<=8t67=t67+dt;set(e,'xdata',[6;6],'ydata',[t67;t67+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第一条路线的最上方
t68=6;   dt=0.05;
while t68>=3t68=t68-dt;set(e,'xdata',[t68;t68],'ydata',[t67;t67+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第一条路线的下方
t69=8;   dt=0.05;
while t69>=1.5t69=t69-dt;set(e,'xdata',[3;3],'ydata',[t69;t69+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置二号长方体木块的运动,竖直向上运动到第二条路线的上方
t70=0.5;  dt=0.05;
while t70<=8t70=t70+dt;set(b,'xdata',[6;6],'ydata',[t70;t70+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置二号长方体木块的运动,水平运动到第三条路线的最上方
t71=6;   dt=0.05;
while t71<=9t71=t71+dt;set(b,'xdata',[t71;t71],'ydata',[t70;t70+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置二号长方体木块的运动,竖直向下运动到第三条路线的最下方
t72=8;   dt=0.05;
while t72>=1.0t72=t72-dt;set(b,'xdata',[9;9],'ydata',[t72;t72+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第一条路线的最上方
t73=1.5;  dt=0.05;
while t73<=8t73=t73+dt;set(e,'xdata',[3;3],'ydata',[t73;t73+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置五号长方体木块的运动,水平运动到第三条路线的最上方
t74=3;   dt=0.05;
while t74<=9t74=t74+dt;set(e,'xdata',[t74;t74],'ydata',[t73;t73+0.5]);drawnow;     set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第三条路线的最下方
t75=8;   dt=0.05;
while t75>=1.5t75=t75-dt;set(e,'xdata',[9;9],'ydata',[t75;t75+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
%设置四号长方体木块的运动,竖直向上运动到第一条路线的最上方
t76=1.0;   dt=0.05;
while t76<=8t76=t76+dt;set(d,'xdata',[3;3],'ydata',[t76;t76+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end           % 设置四号长方体木块的运动,水平运动到第二条路线的最上方
t77=3;   dt=0.05;
while t77<=6t77=t77+dt;set(d,'xdata',[t77;t77],'ydata',[t76;t76+0.5]);drawnow;    set(gcf,'doublebuffer','on');    %消除震动
end     % 设置四号长方体木块的运动,竖直向下运动到第二条路线的最下方
t78=8;   dt=0.05;
while t78>=0.5t78=t78-dt;set(d,'xdata',[6;6],'ydata',[t78;t78+0.5]);drawnow;  set(gcf,'doublebuffer','on');    %消除震动
end        %设置五号长方体木块的运动,竖直向上运动到第三条路线的最上方
t79=2.0;   dt=0.05;
while t79<=8t79=t79+dt;set(e,'xdata',[9;9],'ydata',[t79;t79+0.5]);drawnow;    set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,水平运动到第二条路线的最上方
t80=9;   dt=0.05;
while t80>=6t80=t80-dt;set(e,'xdata',[t80;t80],'ydata',[t79;t79+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第二条路线的下方
t81=8;    dt=0.05;
while t81>=1.0t81=t81-dt;set(e,'xdata',[6;6],'ydata',[t81;t81+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end           % 设置三号长方体木块的运动,竖直向上运动到第一条路线的上方
t82=0.5;    dt=0.05;
while t82<=8t82=t82+dt;set(c,'xdata',[3;3],'ydata',[t82;t82+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置三号长方体木块的运动,水平运动到第三条路线的上方
t83=3;    dt=0.05;
while t83<=9t83=t83+dt;set(c,'xdata',[t83;t83],'ydata',[t82;t82+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end         % 设置三号长方体木块的运动,竖直向下运动到第三条路线的下方
t84=8;    dt=0.05;
while t84>=1.5t84=t84-dt;set(c,'xdata',[9;9],'ydata',[t84;t84+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end     % 设置五号长方体木块的运动,竖直向上运动到第二条路线的上方
t85=1;   dt=0.05;
while t85<=8t85=t85+dt;set(e,'xdata',[6;6],'ydata',[t85;t85+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,水平运动到第一条路线的最上方
t86=6;   dt=0.05;
while t86>=3t86=t86-dt;set(e,'xdata',[t86;t86],'ydata',[8;8+0.5]);drawnow;set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第一条路线的下方
t87=8;   dt=0.05;
while t87>=0.5t87=t87-dt;set(e,'xdata',[3;3],'ydata',[t87;t87+0.5]);drawnow; set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向上运动到第二条路线的上方
t88=0.5;  dt=0.05;
while t88<=8t88=t88+dt;set(d,'xdata',[6;6],'ydata',[t88;t88+0.5]);drawnow;   set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,水平运动到第三条路线的上方
t89=6;   dt=0.05;
while t89<=9t89=t89+dt;set(d,'xdata',[t89;t89],'ydata',[8;8.5]);drawnow;set(gcf,'doublebuffer','on');    %消除震动
end
% 设置四号长方体木块的运动,竖直向下运动到第三条路线的下方
t90=8;dt=0.05;
while t90>=2.0t90=t90-dt;set(d,'xdata',[9;9],'ydata',[t90;t90+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向上运动到第一条路线的上方
t91=0.5;dt=0.05;
while t91<=8t91=t91+dt;set(e,'xdata',[3;3],'ydata',[t91;t91+0.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end          % 设置五号长方体木块的运动,水平运动到第三条路线的上方
t92=3;dt=0.05;
while t92<=9t92=t92+dt;set(e,'xdata',[t92;t92],'ydata',[8;8.5]);drawnow;
set(gcf,'doublebuffer','on');    %消除震动
end
% 设置五号长方体木块的运动,竖直向下运动到第三条路线的下方
t93=8; dt=0.05;
while t93>=2.5t93=t93-dt;set(e,'xdata',[9;9],'ydata',[t93;t93+0.5]);drawnow;set(gcf,'doublebuffer','on');    %消除震动
end   


对应的程序如下:

function hano_auto(level)
if nargin < 1level=6;
end
hold on,axis equal
axis(0.5+[0,120,0,60])
set(gca,'xtick',[],'ytick',[],'xcolor','w','ycolor','w')
set(gca,'color','k')
ground=[120.5,1.5;120.5,0.5;0.5,0.5;0.5,1.5];
column_1=[21,1.5;21,44;19,44;19,1.5];
column_2=[61,1.5;61,44;59,44;59,1.5];
column_3=[101,1.5;101,44;99,44;99,1.5];
step=0;
arrow=[1];k=1.5;control=1;
A=[];B=[];C=[];
A=level:-1:1;
block_1=@(l,h)[20+2*l,3*h-1.5;20+2*l,3*h+1.5;20-2*l,3*h+1.5;20-2*l,3*h-1.5];
block_2=@(l,h)[60+2*l,3*h-1.5;60+2*l,3*h+1.5;60-2*l,3*h+1.5;60-2*l,3*h-1.5];
block_3=@(l,h)[100+2*l,3*h-1.5;100+2*l,3*h+1.5;100-2*l,3*h+1.5;100-2*l,3*h-1.5];
block__=@(l,p)[p+2*l,45-1.5;p+2*l,45+1.5;p-2*l,45+1.5;p-2*l,45-1.5];
set(gcf,'tag','co','CloseRequestFcn',@clo);function clo(~,~)control=0;delete(findobj('tag','co'));clfcloseend function draw(~,~)delete(findobj(gcf,'type','text'))delete(findobj(gcf,'type','patch'))text(5,-4,'step=')text(20,-4,num2str(step))text(5,-10,'level=')text(20,-10,num2str(level))text(34,-4,'use the key(\leftarrow \rightarrow) to move the claw')text(34,-10,'use the key(\uparrow \downarrow) to pick or land the block')fill(ground(:,1),ground(:,2),'w','EdgeColor','none')fill(column_1(:,1),column_1(:,2),'w','EdgeColor','none')fill(column_2(:,1),column_2(:,2),'w','EdgeColor','none')fill(column_3(:,1),column_3(:,2),'w','EdgeColor','none')text(40*arrow(1)-20-2,55,'\downarrow','Color','w','Fontsize',25)if length(arrow)==2p=40*arrow(1)-20;block=block__(arrow(2),p);fill(block(:,1),block(:,2),'w','EdgeColor','none')  endfor i=1:length(A)block=block_1(A(i),k*i);fill(block(:,1),block(:,2),'w','EdgeColor','none')   endfor i=1:length(B)block=block_2(B(i),k*i);fill(block(:,1),block(:,2),'w','EdgeColor','none')   endfor i=1:length(C)block=block_3(C(i),k*i);fill(block(:,1),block(:,2),'w','EdgeColor','none')   endif length(C)==levelpause(0.2)buttonName1=questdlg('Congratulations! You win','you win','close','restart','next level','close');if isempty(buttonName1)buttonName1='end';endif strcmp(buttonName1,'restart')hano_auto(level)endif strcmp(buttonName1,'close')close;endif strcmp(buttonName1,'next level')if level<10hano_auto(level+1)endif level==10msgbox('it is already the highest level')endendendendfunction key(event)switch eventcase 'leftarrow'if arrow(1)-1~=0arrow(1)=arrow(1)-1;step=step+1;endcase 'rightarrow'if arrow(1)-3~=0arrow(1)=arrow(1)+1;step=step+1;endcase 'uparrow'if length(arrow)==1if (arrow(1)==1)&&(~isempty(A))arrow=[arrow(1),A(end)];A(end)=[];endif (arrow(1)==2)&&(~isempty(B))arrow=[arrow(1),B(end)];B(end)=[];endif (arrow(1)==3)&&(~isempty(C))arrow=[arrow(1),C(end)];C(end)=[];endendcase 'downarrow'if length(arrow)==2if (arrow(1)==1)if isempty(A)A=[A,arrow(2)];arrow(2)=[];elseif A(end)>arrow(2)A=[A,arrow(2)];arrow(2)=[];endendendif (arrow(1)==2)if isempty(B)B=[B,arrow(2)];arrow(2)=[];elseif B(end)>arrow(2)B=[B,arrow(2)];arrow(2)=[];endend           endif (arrow(1)==3)if isempty(C)C=[C,arrow(2)];arrow(2)=[];elseif C(end)>arrow(2)C=[C,arrow(2)];arrow(2)=[];endendendendendpause(0.2)if control==1draw()elsepauseendend
draw()
matrix=[1 2 3];
digui(level,matrix)function digui(n,structdigui)if n==1move(structdigui(1),structdigui(3));elsedigui(n-1,[structdigui(1),structdigui(3),structdigui(2)])move(structdigui(1),structdigui(3))digui(n-1,[structdigui(2),structdigui(1),structdigui(3)])endendfunction move(a,b)while arrow(1)~=aif arrow(1)>akey('leftarrow')endif arrow(1)<akey('rightarrow')endendkey('uparrow')while arrow(1)~=bif arrow(1)>bkey('leftarrow')endif arrow(1)<bkey('rightarrow')endendkey('downarrow')endend

汉诺塔游戏玩法介绍(攻略和编程实现)相关推荐

  1. 时空猎人无尽之塔初级玩法解析攻略

    时空猎人是一款格斗类的手机网游,自从2012年11月手游版时空猎人发行以来,就凭借其DNF式的打斗快感,配以炫丽的魔法效果带给诸位玩家前所未有的畅快体验.虽说时空猎人已成为一款经典的老游戏,可是老玩家 ...

  2. 崽崽是什么?崽崽游戏玩法以及攻略

    1.崽崽是一个玩法多的游戏.里面有超多的玩法,比如:装扮自己的专属人物.在地图中跑酷和玩耍,当然也可以玩着迷藏. 2.崽崽起源下载入口.首先要下载崽崽 然后随便点一个创作过地图的大佬,再点进个人主页的 ...

  3. 【使用递归玩通关汉诺塔游戏】算法01-递归(斐波那契数列、汉罗塔问题)-java实现

    递归 定义:在一个方法(函数)的内部调用该方法(函数)本身的编程方式 简而言之就是 "自己调自己" 在玩游戏之前让我们先对递归有一个简单的了解吧! 5.1 递归简介 递归必须有一个 ...

  4. python玩汉诺塔游戏攻略

    def hanio(n,x,y,z):'汉诺塔游戏攻略'if n == 1:print('%s-->%s'%(x,z))else:#将n-1个从x放到y上 借助zhanio(n-1,x,z,y) ...

  5. 头脑风暴--原生JS实现汉诺塔游戏

    介绍 今天写了一个汉诺塔游戏,我想大家应该都玩过,先给大家看看具体是什么样吧. 源码已上传github:github链接 很遗憾,也就只有3个圆盘我可以顺利通过,哈哈~~~,如果谁可以玩更高的级别,还 ...

  6. c#语言编写汉诺塔游戏,c# 实现汉诺塔游戏

    汉诺塔游戏一旦掌握了规律,其实是有点单调和无聊的,不过却是学习递归的一个绝佳例子,想当初学习老谭C的时候,就卡在这儿好长时间. 对初学编程的人来说,递归本身就不易理解,如果使用C语言没有好的调试环境就 ...

  7. java实现汉诺塔游戏(递归)(附超详细易懂注释)

    我们很容易能想到,可以用递归来实现汉诺塔游戏.因为要将n(n>1)个盘子从"源"柱子移到"目标"柱子,我们要先把n-1个盘子从"源"柱 ...

  8. linux开发汉诺塔游戏程序,汉诺塔游戏终极版

    今天,我完成了汉诺塔游戏终极版.使用一个脚本来输出汉诺塔自动运行的步骤,再通过管道提供给汉诺塔游戏,实现了自动完成汉诺塔. 在去年我用C语言写完汉诺塔游戏时,一直有个未完成的心愿.我希望能让汉诺塔自动 ...

  9. python汉诺塔游戏_Python实战:搭建汉诺塔小游戏,快和小伙伴一起玩玩吧

    汉诺塔游戏:看谁能在短时间内将排好顺序的圈,按同样的顺放在另一根柱子上,每次只能动一个. 今天用python搭建汉诺塔小游戏(简约版) 代码亲测有效!源代码如下: #左中右塔用一个列表存储 left ...

  10. Py:递归求解汉诺塔,简单的几行编程可以搞定很高层的三柱汉诺塔游戏

    Py:递归求解汉诺塔,简单的几行编程可以搞定很高层的三柱汉诺塔游戏 目录 输出结果 核心代码 输出结果 核心代码 def hanoi(n,x,y,z):if n==1:print(x,'--→',z) ...

最新文章

  1. 软件工程白盒测试的流图怎么画_功能安全理论 | 黑盒 与 白盒
  2. php curl异步跳转,php curl批处理--可控并发异步
  3. hdu-2199 Can you solve this equation?(二分+精度)
  4. D进制的A+B (20)
  5. Cisco 2811 语音网关+callmanager拨打外线详解配置
  6. endp 汇编start_常见汇编代码
  7. Java面向对象之抽象方法抽象类、接口的使用
  8. bat文件打开一闪就没了_批量提取文件名
  9. wxpython网站_wxpython学习笔记
  10. 简述hdfs工作原理_简述HDFS的原理?
  11. 隔离式DC-DC变换器市场现状及未来发展趋势
  12. 【计算机基础】防火墙
  13. QtChart使用教程
  14. MINA框架客户端的使用
  15. CSR8系列ROM版本芯片介绍
  16. catia今天突然打不开了_catia打不开的解答
  17. 从空间、时间和时空动力学角度研究大脑的动态特性
  18. Yeti Feather贴图着色与Arnold 渲染
  19. Unity 将图片转换成 sprite 格式
  20. 【论文阅读笔记】:CGD: Multi-View Clustering via Cross-View Graph Diffusion

热门文章

  1. 《百度输入法》导致EXCEL 无法使用快捷键Ctrl+;插入日期
  2. 仓库如何盘点?使用盘点机盘点有什么好处?仓库盘点方法?
  3. CSS Flexbox布局
  4. 2020年10月 Hacktoberfest 纪念版T恤还是种树
  5. gan的几种变体_推荐系统系列第6部分,用于协作过滤的自动编码器的6种变体
  6. HIVE 实现均匀抽样
  7. staruml 依赖于 libgcrypt11 (= 1.4.5);然而:未安装软件包 libgcrypt11。
  8. 中文不能输入超过20,英文输入不能超过40个
  9. cents7 mysql数据库安装和配置
  10. cents7配置gradle4