汉诺塔(C#版)

汉诺塔介绍:有三个柱子,X柱子上有n个大小不同的盘子,现借助Y柱子将所有盘子搬到Z柱子上。
规则1:一次只能搬动一个盘子;
规则2:盘可以放在三个柱子的任意一个柱子上;
规则3:任何时刻都不能将大的盘子放在小的盘子上面。

n个盘子最少要搬2的n次方减一次。

说明:当n=1时,只需要将它从X柱子上搬到Z柱子上;
          当n>1时,可以看成是先把1~n-1个盘子从X柱子搬到Y柱子上,把第n个盘子从
          X柱子搬到Z柱子上,再把1~n-1个盘子从Y柱子搬到Z柱子上。
  hanoi(int n, char x, char y, char z)的含义是将n个盘子从X柱子搬到Z柱子,中间可借助Y柱子
  move(char c1, int number, char c2)的含义是将第number个盘子从C1柱子搬到C2柱子上

本人是用大小不同的一些按钮控件来表示盘子的。窗体设计图如下:

汉诺塔(C版) - 水到绝境是飞瀑 - 水到绝境是飞瀑的博客

 

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace HannoiTower
{
    public partial class Form1 : Form
    {
        int n;
        char x = 'x', y = 'y', z = 'z';//标示三个柱子
        int [] count = new int[3]{0,0,0};//记录三个柱子上面的盘子数量
        Button[] disks;//用按钮代表盘子
        public Form1()
        {
            InitializeComponent();
        }

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)//comboBox的值改变时触发
        {
            n = int.Parse(comboBox1.SelectedItem.ToString());//取得选中的值
            disks = new Button[n];
            for (int i = 0; i < n; i++)
            {
                disks[i] = new Button();
                disks[i].Text = (i+1).ToString();
                disks[i].Size = new Size(10 * (i+1), 20);
                disks[i].Location = new Point(100 - 5 * (i+1), 500 - 20 * (n - i));
                disks[i].ForeColor = Color.Red;
                disks[i].BackColor = Color.Green;
                this.Controls.Add(disks[i]);//将控件加载到窗体上
            }
            count[0] = n;//第一根柱子数量给n
        }
        private void Form1_Load(object sender, EventArgs e)
        {
           
        }
      

        public void hanoi(int n, char x, char y, char z)
        {
           
            if (n == 1)
            {
                move(x, 1, z);
                Thread.Sleep(1000);
            }
            else
            {
                hanoi(n - 1, x, z, y);
                move(x, n, z);             
                Thread.Sleep(1000);
                hanoi(n-1,y,x,z);
            }      
        }
        public void move(char c1, int number, char c2)
        {
            if (c1 == 'x' && c2 == 'y')//X柱子到Y柱子
            {
                count[1]++;//先修改每个柱子上盘子的数量
                count[0]--;//之后修改对应的按钮的坐标值
                disks[number-1].Location = new Point(300 - 5 * (number + 1),500 - 20 * count[1]);
                resultBox.Text += "X--→Y\n";
            }
            else if (c1 == 'x' && c2 == 'z')//X柱子到Z柱子
            {
                count[2]++;
                count[0]--;
                disks[number-1].Location = new Point(500 - 5 * (number + 1), 500 - 20 * count[2]);
                resultBox.Text += "X--→Z\n";
            }
            else if (c1 == 'y' && c2 == 'x')//Y柱子到X柱子
            {
                count[0]++;
                count[1]--;
                disks[number-1].Location = new Point(100 - 5 * (number + 1), 500 - 20 * count[0]);
                resultBox.Text += "Y--→X\n";
            }
            else if (c1 == 'y' && c2 == 'z')//Y柱子到Z柱子
            {
                count[2]++;
                count[1]--;
                disks[number-1].Location = new Point(500 - 5 * (number + 1), 500 - 20 * count[2]);
                resultBox.Text += "Y--→Z\n";
            }
            else if (c1 == 'z' && c2 == 'x')//Z柱子到X柱子
            {
                count[0]++;
                count[2]--;
                disks[number-1].Location = new Point(100 - 5 * (number + 1), 500 - 20 * count[0]);
                resultBox.Text += "Z--→X\n";
            }
            else//Z柱子到Y柱子
            {
                count[1]++;
                count[2]--;
                disks[number-1].Location = new Point(300 - 5 * (number + 1), 500 - 20 * count[1]);
                resultBox.Text += "Z--→Y\n";
            }
        }
        private void btnstart_Click(object sender, EventArgs e)
        {
            hanoi(n, x, y, z);//调用方法
        }
    }
}

这些是本人所写的代码,本人保留所有解释权。呵呵……

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值