对于棋盘的表示当前比较先进的思想是“位棋盘”。“位棋盘”用于国际象棋非常便捷,因为国际象棋的棋盘正好有64个格子,可以将一个棋盘的信息用一个64位的变量来表示。其基本思想就是用位上的值是1或0来表示棋子在棋盘相应位置上的存在与否,这样做的好处是可以通过位操作运算来加快局面评估和着法生成的速度。当用于中国象棋时需要进行拼凑以表示中国象棋棋盘的90个格子……
由于考虑到本人目前水平精力均着实有限。当前应以实现本程序为首要目标,而不是致力于高质量算法研究,所以就偷懒采用了传统的较为简单的“棋盘数组”——即用一个9*10的数组来存储棋盘上的信息,数组的每个元素存储棋盘上相应位置是何种棋子。这种表示方法简单易行。按此方法棋盘的初始情形如下所示:
BYTE CChessBoard[9][10] = {
R, 0, 0, P, 0, 0, p, 0, 0, r,
H, 0, C, 0, 0, 0, 0, c, 0, h,
E, 0, 0, P, 0, 0, p, 0, 0, e,
A, 0, 0, 0, 0, 0, 0, 0, 0, a,
K, 0, 0, P, 0, 0, p, 0, 0, k,
A, 0, 0, 0, 0, 0, 0, 0, 0, a,
E, 0, 0, P, 0, 0, p, 0, 0, e,
H, 0, C, 0, 0, 0, 0, c, 0, h,
R, 0, 0, P, 0, 0, p, 0, 0, r
};
其中”0”表示无棋子,”R”表示红车,”r”表示黑车等等(详见后面的代码),也就是我们给棋盘进行了如下图所示的编号,并约定红方棋子总在棋盘的下方。
下面是CChessDef.h的代码。该头文件定义了象棋相关的基本数据结构,包括棋子棋盘的表示,行棋的基本结构类型等。我同时使用了两种方式来为一个棋子命名,这是为了在有些情况下见名知意而在其它情况下能简单快捷地表示。
// CChessDef.h
////////////////////// 基本类型定义 //////////////////////////////////////////
typedef char BYTE;
typedef struct _point{
BYTE x;
BYTE y;
} POINT ; // 棋盘上的点的结构
typedef struct _cchessmove{
POINT ptFrom; // 起点
POINT ptTo; // 目标点
int nScore; // 该走法的历史得分
} CCHESSMOVE ; // 走法结构
////////////////////// 下棋方定义 ////////////////////////////////////////////
const int HUMAN = 1; // 人
const int COMPUTER = 0; // 电脑
const int RED = 1; // 红方
const int BLACK = 0; // 黑方
////////////////////// 棋子定义 //////////////////////////////////////////////
//红方棋子定义 红
const BYTE K = 1; // 帅
const BYTE A = 2; // 仕
const BYTE E = 3; // 相
const BYTE H = 4; // 马
const BYTE R = 5; // 车
const BYTE C = 6; // 炮
const BYTE P = 7; // 兵
//黑方棋子定义 黑
const BYTE k = 8; // 将
const BYTE a = 9; // 士
const BYTE e = 10; // 象
const BYTE h = 11; // 马
const BYTE r = 12; // 车
const BYTE c = 13; // 炮
const BYTE p = 14; // 卒
//红方棋子定义
#define RED_K K
#define RED_S A
#define RED_X E
#define RED_M H
#define RED_J R
#define RED_P C
#define RED_B P
//黑方棋子定义
#define BLACK_K k
#define BLACK_S a
#define BLACK_X e
#define BLACK_M h
#define BLACK_J r
#define BLACK_P c
#define BLACK_B p
//判断该棋子为哪一方
const int SideOfMan[15] ={0, RED, RED, RED, RED, RED, RED, RED,
BLACK, BLACK, BLACK, BLACK, BLACK, BLACK, BLACK, };
//此数组将作为一个“函数”来使用。类似 int SideOfMan( BYTE );
/////////////////////// 棋局定义//////////////////////////////////////////////
// 棋盘上棋子分布
BYTE CChessBoard[9][10] = {
R, 0, 0, P, 0, 0, p, 0, 0, r,
H, 0, C, 0, 0, 0, 0, c, 0, h,
E, 0, 0, P, 0, 0, p, 0, 0, e,
A, 0, 0, 0, 0, 0, 0, 0, 0, a,
K, 0, 0, P, 0, 0, p, 0, 0, k,
A, 0, 0, 0, 0, 0, 0, 0, 0, a,
E, 0, 0, P, 0, 0, p, 0, 0, e,
H, 0, C, 0, 0, 0, 0, c, 0, h,
R, 0, 0, P, 0, 0, p, 0, 0, r
};
// end of CChessDef.h