华容道系列-开篇 :《华容道与数据结构》
2005-12-28 11:00
274 查看
此为转贴,原文出处:http://zhenyulu.cnblogs.com/articles/74712.html本系统文章,后续篇章,也请在原作者处阅读。本系列内容将分成两大部分:《华容道与数据结构》以及《华容道与设计模式》,两者之间会有一些交叉。
其实编写"华容道"的想法早在上大学时就有了,那时候我在《科学》杂志上读到胡华旦的一篇文章《"华容道"难题的计算机解》后心潮澎湃,非得用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便可。具体设计方案以及基本算法描述我会在下一篇文章中公布。
(待续)
一、 序言
这个学期给学生上《设计模式》的课程,有些学生提出找些题目练练手,增强一些实战经验,我决定让他们编写"华容道"游戏。说实在的,当时并没有深思熟虑。后来自己仔细想想,发现这里面东西还真不少,甚至包括下学期我才给他们开设的课程《数据结构》中的大量内容。所以我决定自己先来尝试一下。其实编写"华容道"的想法早在上大学时就有了,那时候我在《科学》杂志上读到胡华旦的一篇文章《"华容道"难题的计算机解》后心潮澎湃,非得用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便可。具体设计方案以及基本算法描述我会在下一篇文章中公布。
(待续)
相关文章推荐
- 华容道系列-开篇
- javascript zero to hero系列(1 开篇)
- 【数据结构_不那么数据结构系列_1027】舞伴问题
- 我思故我在系列—数据结构面试NO.30题(题目搜集整理者JULY,非常感谢!!)
- 数据结构系列之希尔排序详解
- 【数据结构系列】线段树(Segment Tree)
- 数据结构系列之快速排序详解
- EPLAN API 入门系列- 开篇
- 数据结构系列之链表——单链表插入值为num的节点
- 数据结构系列之链表——循环链表(约瑟夫环)
- 重学数据结构系列之——栈
- 读书笔记:C++ Primer系列(1)—— 开篇
- 纸上谈兵系列(算法与数据结构)
- Redis设计与实现系列-基本数据结构-链表和压缩列表
- 博客开篇以及Flex快速入门系列说明
- 一,撸基础篇系列,JAVA的那些数据结构应用
- Thinkphp源码分析系列–开篇
- BugFix系列---开篇介绍
- Java代码优化系列(一)开篇立碑
- 数据结构系列教程(一)