欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#解决汉诺塔问题DEMO

程序员文章站 2022-05-26 15:17:09
汉诺塔问题是学习递归的入门问题,这里用c#简单实现了一个汉诺塔之间传递盘子的小程序 通过简单绘图实现盘子在几个塔之间的转换: namespace 汉诺塔...

汉诺塔问题是学习递归的入门问题,这里用c#简单实现了一个汉诺塔之间传递盘子的小程序

C#解决汉诺塔问题DEMO

通过简单绘图实现盘子在几个塔之间的转换:

namespace 汉诺塔
{
  //盘子类
  class hanioitem
  {
    public int hanoiitemheight { get; set; }//盘子的高度
    public int hanoiitemwidth { get; set; }//盘子的宽度
    public point hanoiitempoint { get; set; }//画盘子的起始点
  }
}

namespace 汉诺塔
{   
  public partial class frmshow : form
  {

    list<hanioitem> hanioitemsa = new list<hanioitem>();//塔a中的盘子集合
    list<hanioitem> hanioitemsb = new list<hanioitem>();//塔b中的盘子集合
    list<hanioitem> hanioitemsc = new list<hanioitem>();//塔c中的盘子集合
    pen p;//画笔
    graphics haniopica;//塔a的画布
    graphics haniopicb;//塔b的画布
    graphics haniopicc;//塔c的画布    
    int tag;//盘子个数    
  
    public frmshow()
    {      
      initializecomponent();     
    }

    /// <summary>
    /// 初始化3个picturebox画布
    /// </summary>
    public void initialtools()
    {     
       p = new pen(color.black);
       haniopica = hanoipica.creategraphics();
       haniopicb = hanoipicb.creategraphics();
       haniopicc = hanoipicc.creategraphics();
    }
      
    public void initialgraphics()
    {
      int hanioitemheight = 15;//塔中盘子的高度
      int haniostartitemwidth = 90;//第一个盘子的宽
      point haniostartitemp = new point(15, 135);//第一个盘子起始点

      initialtools();          
      tag = convert.toint16(this.tag.tostring());

      hanioitemsa.clear();
      hanioitemsb.clear();
      hanioitemsc.clear();

           
      //初始化塔a上的盘子     
      int diffrence = (90 - 30) / tag;//两个盘子之间宽度之差

      for (int i = 1; i <= tag; i++)
      {
        hanioitem item = new hanioitem();
        item.hanoiitemwidth = haniostartitemwidth;
        item.hanoiitemheight = hanioitemheight;
        item.hanoiitempoint = haniostartitemp;
        hanioitemsa.add(item);

        haniostartitemwidth -= diffrence;
        haniostartitemp.x += diffrence / 2;       
      }

      //为汉诺塔画盘子
      showhanoigraphics();
    }

    /// <summary>
    /// 画3个塔中的盘子
    /// </summary>
    private void showhanoigraphics()
    {      
      haniopica.clear(this.backcolor);
      haniopicb.clear(this.backcolor);
      haniopicc.clear(this.backcolor);

      //为汉诺塔a画初始线条      
      haniopica.drawline(p, 0, 150, 120, 150);
      haniopica.drawline(p, 60, 0, 60, 150);

      //为汉诺塔b画初始线条     
      haniopicb.drawline(p, 0, 150, 120, 150);
      haniopicb.drawline(p, 60, 0, 60, 150);

      //为汉诺塔c画初始线条      
      haniopicc.drawline(p, 0, 150, 120, 150);
      haniopicc.drawline(p, 60, 0, 60, 150);

      //画a塔的盘子
      for (int i = 0; i < hanioitemsa.count; i++) 
      {
        haniopica.drawrectangle(p, hanioitemsa[i].hanoiitempoint.x, hanioitemsa[i].hanoiitempoint.y - i * 15, hanioitemsa[i].hanoiitemwidth, hanioitemsa[i].hanoiitemheight);
      }
     
      //画b塔的盘子
      for (int i = 0; i < hanioitemsb.count; i++)
      {
        haniopicb.drawrectangle(p, hanioitemsb[i].hanoiitempoint.x, hanioitemsb[i].hanoiitempoint.y - i * 15, hanioitemsb[i].hanoiitemwidth, hanioitemsb[i].hanoiitemheight);
      }
     
      //画c塔的盘子
      for (int i = 0; i < hanioitemsc.count; i++)
      {
        haniopicc.drawrectangle(p, hanioitemsc[i].hanoiitempoint.x, hanioitemsc[i].hanoiitempoint.y - i * 15, hanioitemsc[i].hanoiitemwidth, hanioitemsc[i].hanoiitemheight);
      }
     
    }

    /// <summary>
    /// 汉诺塔核心递归函数
    /// </summary>
    /// <param name="n">盘子个数</param>
    /// <param name="a">塔a</param>
    /// <param name="b">塔b</param>
    /// <param name="c">塔c</param>
    private void hanio(int n, list<hanioitem> a, list<hanioitem> b, list<hanioitem> c)
    {
      if (n == 1)
      {
        haniomove(a, c);
      }

      else
      {
        hanio(n - 1, a, c, b);
        haniomove(a, c);
        hanio(n-1,b,a,c);
      }
    }
    
    /// <summary>
    /// 盘子移动画图实现
    /// </summary>   
    private void haniomove(list<hanioitem> x, list<hanioitem> y)
    {        
      hanioitem item = new hanioitem();
      item = x[x.count-1];
      x.remove(item);//塔x移除一个盘子
      y.add(item); //塔y添加一个盘子      
      showhanoigraphics();
      system.threading.thread.sleep(1000);  
    }

    private void btnok_click(object sender, eventargs e)
    {     
      hanio(tag, hanioitemsa, hanioitemsb, hanioitemsc);
    }

    private void frmshow_paint(object sender, painteventargs e)
    {         
      initialgraphics();
    }      
  }
}