First we try, then we trust

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

本系列内容将分成两大部分:《华容道与数据结构》以及《华容道与设计模式》,两者之间会有一些交叉。

一、 序言

这个学期给学生上《设计模式》的课程,有些学生提出找些题目练练手,增强一些实战经验,我决定让他们编写"华容道"游戏。说实在的,当时并没有深思熟虑。后来自己仔细想想,发现这里面东西还真不少,甚至包括下学期我才给他们开设的课程《数据结构》中的大量内容。所以我决定自己先来尝试一下。

其实编写"华容道"的想法早在上大学时就有了,那时候我在《科学》杂志上读到胡华旦的一篇文章《"华容道"难题的计算机解》后心潮澎湃,非得用C语言写一个,可最终因为种种原因没有做成,现在也是圆我的一个梦想吧。

目前网上能够搜索到很多"华容道"计算机解的源代码,但用面向对象语言站在数据结构以及设计模式角度编写的几乎没有。我想尝试成为第一个吃螃蟹的人。在正式开始写这个系列之前,我曾经考虑过很久将代码定位在一个什么层面上,是教学还是应用。其实数据结构与设计模式的应用是一个很自然的事情,不应该为了模式而模式,但出于教学目的又必须明确用了哪些模式,这又违背了模式的思想,我会尽量找到一个合适的平衡点。另外,为了兼顾内存使用和运算效率以及通用性的要求,最好能够应用泛型编程,但目前绝大多数人恐怕还在使用.net 2003,所以我最终选择了放弃泛型技术。

最后,由于本人水平有限,而且是边做边写,难免会有些疏漏,希望大家能够谅解。


二、 对棋盘布局的说明

我们在程序中研究的棋盘布局的限制条件是:最大子只允许有一个;最小子允许有4或8个(棋子总数相应为10至12个),其余棋子任选;棋盘上必须和只允许有两个空格。

另外需要明确的就是棋盘上任意两个相同形状、相同摆放的棋子是"同质"的,在计算机看来没有任何区别。如图:

 

计算机将认为以上两个棋局是完全相同的,也就是说计算机不会记录"人物"信息,只存储"布局"信息。这样做的目的一方面可以减少内存空间占用,另外一方面可以将UI与解题过程剥离开,降低耦合,允许各自变化。


三、 棋盘布局的表示方法

下面的布局是网上一个公开源代码的VB6.0程序,作者刘峻松,Email地址(liujunsong@yahoo.com.cn)。在他的程序中是这样描述一个棋盘布局的:

棋盘状态说明:用12个整数来表示棋盘的开始状态,每个整数用两位表示,目前的算法只支持5员大将,大将可以横放,也可以竖放。棋盘的大小为高度5,宽度4,从上到下,从左到右为棋子位置来排号,其中第一位是曹操的位置,2-6代表5员大将,7-10代表4个小卒,11-12代表两个空格的位置。整个棋盘的取值范围是1-20,当曹操走动第14个位置时行走成功。初始化的状态"021801040912101114151720"代表"横刀立马"布局。

 

在这个表述中,12个整数将占用12×4=48个字节。即便用字符串来描述的化,每个布局还是要占用24个字节的长度。在进行一个复杂棋局的运算中,这样的布局要生成几万个,会占用1M左右的空间。算上其它内容,内存占用还会更大。

如果抛弃"人物"信息,内存占用将大大降低。经过优化后,可以使用4个字节来描述一个布局(10子或12子布局均可)。这样,我们只需使用一个Int32便可。具体设计方案以及基本算法描述我会在下一篇文章中公布。


(待续)

posted on 2004-12-09 09:45  吕震宇  阅读(10285)  评论(8编辑  收藏  举报