
一、 概述:
跳棋在我国是一项老少皆宜、流传广泛的益智型棋类游戏。由于其规则简单,
一玩就懂,一辈子都不会忘,所以几乎每个人从小到大都下过跳棋。如果您不愿陷入激烈的
思考和竞争,那么无疑本游戏可以使您回到一种更平和、产生美好回忆的心情之中。
在此我把近十天的成果做一个简要的介绍,尽量把问题说得清楚细致。希望与
对跳棋编程有同样兴趣的伙伴们好好讨论一下,也希望下一版本的跳棋做得更好。
这个跳棋游戏主要有下几个特点:界面漂亮,操作简单,功能简洁,老少兼宜。
我爸爸都很喜欢下。整个跳棋的源码你可以下载。
二、 跳棋整体设计
UML 类图:
先给跳棋整个代码做一个整体介绍,说明每个包,每个类具体作用:
1. org.yushang.jumpchess.app
AppJumpChess.java 实现的漂亮的窗体界面,标题栏和各种按钮,设置玩家个数及类型(人,
或是计算机)。

2. org.yushang.jumpchess.audio
WavePlayer.java 主要用于播放游戏中各种声音效果,比较简单。
3. org.yushang.jumpchess.image
ImageLoader.java 主要用于从资源文件中导入各种图片背景,比较简单。
4. org.yushang.jumpchess.Interface
Animation.java 是用于播放动画的超类�
AnimationGO.java 是用于播放棋子走动的动画�
AnimationSelect.java 是用于播放棋子被选中后,“抖动”动画效果�
Drawer.java 主要是静态地显示棋盘、棋子、下棋位置等图片�
JumpChessControl.java 是一个很复杂的类,控制玩家下棋顺序、棋子棋盘的显示、动画
显示、以及响应玩家的下棋的鼠标事件。�
5. org.yushang.jumpchess.pkg
Chess.java 棋子类,说明棋子的颜色以及索引号等信息。�
ChessBoard.java 棋盘类:�
索引功能:为棋子和棋盘坐标建立索引关系,根据棋子的可快速检索出该棋子
的坐标或根据坐标快速检索出该位置是否有棋子。由于这两项功能在下棋过程中使用频率很
高,因此对性能要求也很高。
下棋规则:设定了下棋规则,可以是传统的规则,也可以隔空跳规则。这是一
个麻烦的工作。涉及数据结构方面的知识,有图的生成和最短路径搜索两个难点。
RealChessBoard 和 VirtualChessBoard 是 ChessBoard 派生类:
RealChessBoard 中建立了棋子和棋盘坐标建立真正的索引关系。而 VirtualChessBoard 是
建立在 RealChessBoard 基础之上的,VirtualChessBoard 只是保存当已走动的棋子坐标变
化情况,这样 VirtualChessBoard 的数据量很小,提高计算机下棋智能计算速度,这一优点
在介绍计算机下棋策略详细讨论。RealChessBoard 和 VirtualChessBoard 只是创建方式有
点区别,使用上没有任何差别,这也是多态性的一个运用。

Player.java 玩家类�
保存了玩家棋子颜色、昵称、敌对玩家,棋子摆放初始区域等信息。同时输出下棋路径,为
播放动画作准备。
有两个 Play 和 Man 两个派生类,计算机玩家的下棋由 org.yushang.jumpchess.strategy 控
制,而人玩家的下棋要由用户鼠标事件来驱动。这两个类实现这两个不同的功能。
6. org.yushang.jumpchess.pub
BoardArea.java 这把棋盘各玩家所处的位置编号成 6 个区域。该类可得到自己区域包含
哪些坐标(getAreaPositions)。也可得到和自己相对区域(getOppsiteArea)。�
Color.java 是棋子颜色类�
Director.java 棋盘任何一坐标位置(非棋盘边界),在放六个方向上都有相邻的坐标位
置,�
Map.java、Node.java、Nodes.java 三个文件是和数据结构“图”相关的三个类。�
Position.java 棋盘坐标类,有三个功能:设定了棋盘边界、给定一方向可以得到该方向
上相邻的坐标、计算与另一坐标的距离。�
7. org.yushang.jumpchess.strategy
计算机下棋策略主要有以下几个方面:
� 计算出己方所有可能走法
� 选出一个跳得最远(尽快让自己获胜)的棋子和走法。
� 选择一个最可能阻碍对方前行的棋子和走法。
� 尽可能选择可为下一步提供最有利条件的棋子和走法
� 对以上几项做综合分析,得出较好的走法。
Analyser.java:策略分析类,运用对各种策略进行综合分析, 得出较好的下棋位置。
Strategy.java:策略基类。
MainStrategy.java:让棋子跳得最远的策略
DoubleStrategy.java: 为下一步提供最有利条件的策略
OppsiteScore.java:尽可能阻碍对方前行的策略
三、 界面设计:
因为这是一个游戏,应该在界面上下点功夫,早就不是 DOS 时代了,应该不会
有人喜欢玩一个界面很难看的游戏。同时界面要简洁,功能也不必太多,但基本功能却一定

要做好,让用户玩得痛快。下图是界面:
界面看起来很复杂其实很简单,棋盘是图片,按钮也是图片,都是贴上去的。这里有两个难
点:
1. 标题栏制作:
�去掉原有的标题栏:
创建 Shell 的时候加上 SWT.NO_TRIM 参数就没有边框和标题栏了
sShell = new Shell(SWT.NO_TRIM);
�生成自己的标题栏
创建一个 Label,放到 Shell 的(0,0)位置,设置一下图片就可以了
Title.jpg 是一个图片:
final ImageLoader imageTitle = new ImageLoader(sShell.getDisplay(), "Title.jpg");

// ImageLoader 是自己创建的类,用于载入 Title.jpg,
lblTitle = new Label(parent, SWT.NO_BACKGROUND);
lblTitle.setImage(imageTitle.getImage());//设置 Image 属性
lblTitle.setBounds(0, 0, 800, 28);//设置位置和大小
�如何移动 Shell
标题栏做好了,问题成于这个 Label 假标题栏无法移动 Shell,怎么办呢?只要当鼠标在
lblTitle 上拖动时,程序就要调整 Shell 的位置,才能完成原有标题栏的效果。
代码图如下:
Static boolean mouseDown = false; //鼠标是否按下的标记
Static Point lastMousePoint = null; //按下鼠标时的位置
lblTitle.addMouseListener(new MouseAdapter( {
//按下鼠标时
public void mouseDown(MouseEvent e) {
mouseDown = true; //设置按下标记
lastMousePoint = new Point(e.x, e.y); //记录按下的位置
}
//鼠标释放时
public void mouseUp(MouseEvent e) {
mouseDown = false; //清除按下标记
}
});
lblTitle.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent e) {
if (mouseDown) { //鼠标在 lblTitle 上移动,且鼠标已按下
Point nowMousePoint = new Point(e.x, e.y);//鼠标的新位置