中国象棋棋盘java_Java中国象棋博弈程序探秘[2]——棋盘的表示

本文探讨了如何使用Java实现中国象棋的棋盘表示,选择了棋盘数组方式,避免了位棋盘在9x10棋盘上的复杂性。通过棋盘数组存储棋子位置,并提供了移动棋子的方法`makeMove`和撤销操作`unMove`,其中`isValidMove`判断移动合法性。文章还介绍了辅助类`LatestMotion`用于记录棋子移动的历史信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

棋盘的表示

转载请保留作者信息:

作者:88250

MSN & Gmail & QQ:DL88250@gmail.com

在象棋博弈程序中,首先我们要确定下棋盘-棋子的数据结构描述。

当前,主要有两种棋盘-棋子(以下称之为“局面”, situation)表示法,一种是“棋盘数组”,另一种是“位棋盘”。

由于位棋盘最初是国际象棋(8*8, 刚好64bits)里引入的,而中国象棋是9*10的棋盘,不易用位棋盘表示。但是,位棋盘最大的优点就是奇高的运算效率与空间节省。所以,多数参加博弈比赛或是商业博弈软件都是用位棋盘作为基本的数据结构的。

本文以棋盘数组表示法表示一个局面,因为这样便于阅读代码的人理解。这里,我们要做一个决定:是否使用object-oriented的开发。

使用面向对象开发,棋子可以从抽象到具体,各种搜索算法与控制可以使用一些设计模式获得很好的代码可读性与易修改性。但是,博弈程序的核心是要高效,对象技术给我们带来的优点的代价就是性能问题(我曾经尝试过用很面向对象的观点写这个程序,效率很低下)。所以,我们应该以面向过程的方式开发这个象棋程序(Java写过程化代码,貌似有点不伦不类- -!)。

作出决定后,棋盘可以表示如下:

chessboard = new int[][]{

{1, 0, 0, 4, 0, /**/ 0, 11, 0, 0, 8},

{2, 0, 3, 0, 0, /**/ 0, 0, 10, 0, 9},

{5, 0, 0, 4, 0, /**/ 0, 11, 0, 0, 12},

{6, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 13},

{7, 0, 0, 4, 0, /**/ 0, 11, 0, 0, 14},

{6, 0, 0, 0, 0, /**/ 0, 0, 0, 0, 13},

{5, 0, 0, 4, 0, /**/ 0, 11, 0, 0, 12},

{2, 0, 3, 0, 0, /**/ 0, 0, 10, 0, 9},

{1, 0, 0, 4, 0, /**/ 0, 11, 0, 0, 8},

};

其中,0表示无子,1~14分别代表了一种棋子。

这里,没有使用Java的enum类型,主要是当心性能的问题(JDK1.5后的enum也很面向对象的,呵呵)。而且,以常量代替枚举我认为并不会给理解程序带来太大的障碍(1就是红车)。

要移动棋子的化只需如下操作:

/**

* Move a chessman to destination. If the point at

* (fromX, fromY) has no any chessman, do nothing.

* There is three condition when we makeMove a chessman:

* @param fromX x coordinate of which chessman do this move

* @param fromY y coordinate of which chessman do this move

* @param toX x coordinate of which chessman's destination

* @param toY y coordinate of which chessman's destination

* @return

*

if the (fromY, fromY) has no chessman or

* the move is invalid, returns Constants.MOVE_INVALID,

* value of it equals to -100

*

if move successfully, returns the destination ID. the ID maybe

* a chessman ID(be eaten) or 0(empty chessboard grid)

*

*/

final public int makeMove(int fromX, int fromY, int toX, int toY) {

int chessman = chessboard[fromX][fromY];

if (chessman == 0) {

// invalid move

return -100;

}

if (isValidMove(fromX, fromY, toX, toY)) {

// backup motion

int latestBeEaten = chessboard[toX][toY];

latestMotions.push(new LatestMotion(chessman,

fromX, fromY,

toX, toY,

latestBeEaten,

isRedGo));

// move

chessboard[fromX][fromY] = 0;

chessboard[toX][toY] = chessman;

isRedGo = !isRedGo;

return latestBeEaten;

} else {

// invalid move

return -100;

}

}这个方法里有一个重要的方法:isValidMove,用于判断一次移动是否合法。还有一个历史招法记录stack,用于unMove:

/**

* Undo the latest motion.

*/

final public void unMove() {

LatestMotion latestMotion = latestMotions.pop();

// recovery move

chessboard[latestMotion.fromX][latestMotion.fromY] = latestMotion.who;

// recovery eaten

chessboard[latestMotion.toX][latestMotion.toY] = latestMotion.killed;

// recovery who's go

isRedGo = latestMotion.isRedGo;

}LatestMotion这个类是用于描述最近一次移动棋子的信息:/*

* @(#)LatestMotion.java

* Author: 88250 , http://blog.csdn.net/DL88250

* Created on May 24, 2008, 5:03:23 PM

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License as published by

* the Free Software Foundation; either version 3 of the License, or

* (at your option) any later version.

*

* This program is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

* GNU Library General Public License for more details.

*

* You should have received a copy of the GNU General Public License

* along with this program; if not, write to the Free Software

* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

package cn.edu.ynu.sei.chinesechess.infrastructure.common;

/**

* A chessman's latest motion.

* @author 88250 , http://blog.csdn.net/DL88250

* @version 1.1.0.0, May 28, 2008

*/

final public class LatestMotion {

/**

* who do this motion

*/

public int who;

/**

* x coordinate of chessman' location

*/

public int fromX;

/**

* y coordinate of chessman' location

*/

public int fromY;

/**

* x coordinate of chessman's destination

*/

public int toX;

/**

* y coordinate of chessman's destination

*/

public int toY;

/**

* the chessman killed other chessman

*/

public int killed;

/**

* is red's turn?

*/

public boolean isRedGo;

/**

* Constructor with parameters.

* @param who who do the motion

* @param fromX x coordinate of chessman's location

* @param fromY y coordinate of chessman's location

* @param toX x coordinate of chessman's destination

* @param toY y coordinate of chessman's destination

* @param killed the chessman killed other chessman

* @param isRedGo is red's turn?

*/

public LatestMotion(int who, int fromX, int fromY, int toX, int toY, int killed,

boolean isRedGo) {

this.who = who;

this.fromX = fromX;

this.fromY = fromY;

this.toX = toX;

this.toY = toY;

this.killed = killed;

this.isRedGo = isRedGo;

}

}至此,我们基本已经可以使用这个棋盘进行中国象棋的博弈了 : )

(郁闷。。。。Blog的“插入代码”功能坏了- -#)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值