华容道问题求解_详细设计(7)之布局设计器

(续上文)
尽管横刀立马是经典的也是广为人知的一个华容道开局,这并不意味着,它是唯一的。笔者网搜了一下,发现其经典开局居然有很多。下面开局转自知乎。

知乎华容道经典48开局

48开局如下图所示:
在这里插入图片描述

布局输入

一开始笔者想采用类似VS界面输入控件的方法,发现这样做比较麻烦,就采用了由用户自己输入类型的方法进行布局的录入。录入时,只需要输入对应的类型的,系统自动完成棋子的其余属性的设定。棋子类型前文曾经提起过,为了方便描述再列举如下:

 ///  _type = 5 , the blank block on the board, size is (1,1) (width, height)
 ///        = 1, the soldier block , size is (1,1)
 ///        = 2, the vertical blcok, size is (2,1) 张飞,赵云,马超,黄忠 
 ///        = 3, the horizaontal blcok , size is (1,2) 关羽
 ///        = 4 , the biggest block , size is (2,2) 曹操
 ///        = 0, null, this area is out of the board 
为了保持一致性,布局时的底层输入控件也采用了一个5*4的控件数组,这样在映射实际的布局时,转换比较方便。

控件动态生成,并同时增加了按键的事件处理代码。设计器的界面如下:

在这里插入图片描述
区域1 中进行基本布局的录入,区域2 显示效果,并且可以录入每个棋子的名称。录入时,只需要录入棋子左上角的类型即可,其余部分,程序自动完成。输入部分棋子时的截图如下
在这里插入图片描述

布局保存

保存采用了现成的 三方库 Newtonsoft,它将对象的实例转化为Json格式的文件进行保存。我们仅需把一个对象的定义和实例交给它处理就可以了。

代码实现

包括两部分,文字版和头像版。头像版中,每个棋子将对应一个头像文件。

控件生成

为了便于后续的操作,控件是生成在容器里。为了支持各种容器,使用了模板。

       private void InitDesignControls<T1,T2>(T2 containerCtrl, string preFix) where T1 : Control, new() where T2 : Control

       {
           T1[,] controls = new T1[4, 5];
           int x = _txtSize.Width; // 横向间距  
           int y = _txtSize.Height; // 纵向间距  
           x = 2;
           for (int i = 1; i <= 4; i++)
           {
               y = 16;
               for (int j = 1; j <= 5; j++)
               {
                   controls[i - 1, j - 1] = Activator.CreateInstance<T1>();
                   var control = controls[i - 1, j - 1];
                   control.Name = string.Format("{0}_{1}{2}",preFix, i, j); // 设置名称  


                   control.Location = new Point(x, y); // 设置位置  
                   control.Font = _txtFont; // 设置字体和大小  
                   control.Size = _txtSize; // 设置适当的大小

                   if (control is TextBox textBox)
                   {
                       textBox.TextAlign = HorizontalAlignment.Center;
                       textBox.MaxLength = 1;
                       textBox.KeyDown += Txt_NN_KeyDown;
                       textBox.KeyUp += Txt_NN_TextChanged;
                   }
                   else if (control is Label label)
                   {
                       // Handle Label specific properties or events
                       label.AutoSize = false;
                       label.BorderStyle = BorderStyle.FixedSingle;
                   }
                   containerCtrl.Controls.Add(control); // 将TextBox添加到GroupBox中  

                   control.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Txt_NN_KeyDown);
                   control.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Txt_NN_TextChanged);
                   control.TextChanged += new System.EventHandler(this.setTxtBkColor);

                   y += _txtSize.Height + 2; ; // 重置y位置以开始新的一行  
                }
              x += _txtSize.Width + 2; // 更新x位置以添加下一个TextBox到同一行  
           }
       }

代码中增加KeyDown ,KeyUp和TextChanged 事件代码, 代码的功能是完成录入的检测和后续Demo容器内的控件显示处理。

增加头像

为了使棋子更加形象生动,后期增加了头像的录入功能。这样,用户就可以使用自己喜欢的图片作为棋子的头像了。录入头像的界面如下

在这里插入图片描述
操作简述

在这里插入图片描述
点击下方的棋子,在上面会出现对应的头像(如果已经录入过)。然后可以再用粘贴的方式将需要的图片拷贝进去,再点击 Apply按钮就完成了一个棋子头像的录入。都完成之后,再点击下面的保存按钮,就完成了一个布局的录入。也可以选择磁盘上的文件,不再赘述。
在这里插入图片描述
录入后的布局会出现在主界面的下拉列表中,就可以游戏或者查找最优解了。如图
在这里插入图片描述

布局变换简单研究

布局很多,但是这些布局是真正的独立布局,还是可以转换的呢?为了探究这背后的真相,笔者增加了这方面的简单功能,就是检测两个布局是否可以通过移动棋子互相转换,也即检测它们是不是同一个布局。
看下面的界面
在这里插入图片描述
分别在1 和2 的列表中选择不同的布局,然后点击长条按钮,程序会尝试将1的布局转换为2,如果成功,说明它们的本质是一个布局的不同形式而已。
例如上面的布局的检查结果如下
在这里插入图片描述检测结果标明 横刀立马和 指挥若定是相关的,实际上就是同一个布局的不同形式而已。
点击 右上方的 [>>] 按钮可以查看转换过程。使用这个功能,可以发现48个布局中有不少布局其实都是一个布局的变种。
例如横刀立马和 指挥若定,经过22步移动就可以相互转化
如图所示
在这里插入图片描述
再如:
在这里插入图片描述
这两个布局显然是不能转换的,尝试查找的结果如下:

在这里插入图片描述
至此,华容道最优步数查找的程序终于告一段落,了却了一个小心愿。后笔者可能会尝试写一个操作系统,目的是了解一下操作系统的工作原理以及挑战一下自己的能力。

marasun BJFWDQ
2024-03-12

I will go to Ninghai to take part in a marathon that will take place on 17 Mar. Just a log.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值