using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
namespace 汉诺塔递归
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int i; //移动的次数
public PictureBox[] Plate = new PictureBox[11];//实例化一个盘子对象 将其显示在picturebox 中 最多有11个
const int PlateHeight = 17; //盘片厚度
private ArrayList A = new ArrayList();//可变长数组 表示三个柱子
private ArrayList B = new ArrayList();
private ArrayList C = new ArrayList();
//ArrayList 就是数组列表,它位于System.Collections名称空间下,是集合类型。
private void load_plate(int n)
{
//加载盘片
//盘片编号从上往下1,2,...n
for (i = 1; i <= n; i++)
{
Plate[i] = new PictureBox();//循环将每个盘子 picturebox实例化
this.Controls.Add(Plate[i]);?????????????????????
Plate[i].Left = 49 + (n - i) * 5;
Plate[i].Top = 167 - (n - i + 1) * PlateHeight;//多减去一个 盘子的厚度 因为有底座
Plate[i].Width = 98 - (n - i) * 10;//宽度 / 2 +48=100 即可保证盘子在柱子中间
Plate[i].Height = PlateHeight;//盘子高度不变
Plate[i].Tag = i; //设置盘片编号
Plate[i].Image = new Bitmap("Plate.bmp"); //盘子图片
Plate[i].SizeMode = PictureBoxSizeMode.StretchImage;//调整盘子大小 通过 拉伸收缩图像适应设置的盘子大小
Plate[i].Parent = pictureBox1;//设置盘子父容器 为picturebox 将其显示在picturebox中???????????????
}
for (i = n; i >= 1; i += -1)
{
A.Add(i); //A数组列表添加条目 即将盘子显示在A柱中
}
}
private void Hanoi(int n, char x, char y, char z)
{
if (n == 1)
{
MoveDisc(x, 1, z);//编号为1的盘子从x到z
}
else
{
Hanoi(n - 1, x, z, y); //n-1个盘子从x经z到y,
MoveDisc(x, n, z);//编号为n的盘子从x到z
Hanoi(n - 1, y, x, z); //n-1个盘子从y经x到z,
}
}
private void MoveDisc(char x, int n, char z)
{
int j,t=0;
i = i + 1;
this.Text = i + ":Move disc " + n + " from " + x + " to " + z;//标题栏显示移动方向 统计移动步数
//从源柱对应数组列表中删除盘片n
if (x.Equals('A')) A.Remove(n);
if (x.Equals('B')) B.Remove(n);
if (x.Equals('C')) C.Remove(n);
//向目标柱对应数组列表中添加盘片n
switch (z)
{
case 'A':
A.Add(n); t = A.Count;//获得当前A数组中的元素个数
break;
case 'B':
B.Add(n); t = B.Count;
break;
case 'C':
C.Add(n); t = C.Count;
break;
}
//动画效果移动棋子
int oldtop,newtop,step1;
oldtop = Plate[n].Top;
//首先垂直方向向上移动到顶部
newtop = 0;
for (j = oldtop; j >= newtop; j -= 1)//从当前位置移动到顶端 每一个像素移动一次
{
Plate[n].Top = Plate[n].Top -1;
System.Windows.Forms.Application.DoEvents();//处理队列中消息 可以实现实时响应 实现盘子运动 防止循环时间太长假死
}
//其次水平方向移动
step1 = (z - x) / Math.Abs( z- x);//返回+1 -1
for (j = 0; j <= Math.Abs(z - x) * 170; j += 1) //柱子之间间隔170像素?????????????????????168
{
Plate[n].Left = Plate[n].Left + step1;//改变盘子距离容器左边的距离可能左移 可能右移
System.Windows.Forms.Application.DoEvents();
}
//再垂直方向向下移动
oldtop = 0;
newtop = pictureBox1.Height - (t+1) * PlateHeight;// 多减一个盘子高度 为底座厚度
// step1 = (newtop - oldtop) / Math.Abs(newtop - oldtop);
for (j = oldtop; j <= newtop; j += 1)
{
Plate[n].Top = Plate[n].Top + 1;
System.Windows.Forms.Application.DoEvents();
}
}
private void button2_Click(object sender, System.EventArgs e)//汉诺塔演示动画
{
int n = Convert.ToInt16(TextBox1.Text);//转化为16位有符号整数
if (n>=1&&n<=10)
{
load_plate(n);//将盘子显示在A柱上
//int Num;
char x = 'A';
char y = 'B';
char z = 'C';
// i = 0;
//Num = n;
Hanoi(n, x, y, z);
}
else
{
MessageBox.Show("请输入合适的数量!", "warn");
TextBox1.Text = null;
}
}
private void load_plate1(int n)
{
for (i = n; i >= 1; i -= 1)
{
pictureBox1.Image.Dispose();
pictureBox1.Image = null;
// Plate[i].Image=null;
}
}
private void button1_Click(object sender, EventArgs e)
{
int n = Convert.ToInt16(TextBox1.Text);//转化为16位有符号整数
load_plate1(n);
load_plate(n);
/* int n = Convert.ToInt16(TextBox1.Text);
load_plate(n);
for (int i = 0; i < n; i++)
{
Plate[i].Image.Dispose(); ;
}
pictureBox1.Show();
*/
}
}
}