JavaScript中国象棋程序(1) 您所在的位置:网站首页 象棋棋子大小顺序讲解 JavaScript中国象棋程序(1)

JavaScript中国象棋程序(1)

2024-04-11 17:47| 来源: 网络整理| 查看: 265

“JavaScript中国象棋程序” 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序。这是教程的第1节。

程序的最终效果点击这里查看。

这一系列共有9个部分:

0、JavaScript中国象棋程序(0)- 前言 1、JavaScript中国象棋程序(1)- 界面设计 2、JavaScript中国象棋程序(2)- 校验棋子走法  3、JavaScript中国象棋程序(3)- 电脑自动走棋 4、JavaScript中国象棋程序(4)- 极大极小搜索算法 5、JavaScript中国象棋程序(5)- Alpha-Beta搜索 6、JavaScript中国象棋程序(6)- 克服水平线效应、检查重复局面 7、JavaScript中国象棋程序(7)- 置换表 8、JavaScript中国象棋程序(8)- 进一步优化

 

这一节我们设计图形界面,显示初始化棋局。当点击某棋子时,弹窗提示所点击的具体棋子。效果如下:

 

 

1.1、棋盘表示

中国象棋有10行9列,很自然地想到可以用10×9矩阵表示棋盘。事实上,我们使用16×16矩阵来表示一个扩充了的虚拟棋盘。

如上图所示,灰色部分为真实棋盘,置于虚拟棋盘之中。这么做可以快速判断棋子是否走出边界。例如象沿田字走,如果走到真实棋盘之外的虚拟棋盘中,说明走法不合法。

容易想到使用二维数组表示16×16矩阵,这样棋盘上的一个位置需要两个变量表示。一个走法包括起点和终点,就需要四个变量。如果使用长度为256的一维数组表示,一个位置只需一个变量,这就可以减少计算量。因此用一维数组表示16×16矩阵。

一维矩阵和二维矩阵之间的转换也很简单:

// 将二维矩阵转换为一维矩阵 function COORD_XY(x, y) { return x + (y > 4; } // 根据一维矩阵,获取二维矩阵列数 function FILE_X(sq) { return sq & 15; }

其中,sq & 15是通过位运算取余,与sq % 16结果相同(可参考篇文章)。

再使用一个辅助数组,标识虚拟棋盘中,哪些位置属于真实棋盘:

var IN_BOARD_ = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];

要判断某位置是否在真实棋盘,可使用函数:

function IN_BOARD(sq) { return IN_BOARD_[sq] != 0; } 1.2、棋子表示

使用整数表示棋子:

 

红方

8

9

10

11

12

13

14

黑方

16

17

18

19

20

21

22

棋子这样表示,可以快速判断某棋子属于红方还是黑方,如下表所示:

红方棋子

黑方棋子

十进制

二进制

十进制

二进制

8

0000 1000

16

0001 0000

9

0000 1001

17

0001 0001

10

0000 1010

18

0001 0010

11

0000 1011

19

0001 0011

12

0000 1100

20

0001 0100

13

0000 1101

21

0001 0101

14

0000 1110

22

0001 0110

可以看出:

红方棋子 & 8 = 1

黑方棋子 & 16 = 1

1.3、字符串表示局面

使用数组表示局面,程序处理起来很方便,但是再网上传递棋局很不方便。我们可以用一行字符串表示一个局面,这就是FEN格式串,一种使用ASCII码字符描述国际象棋局面的标准,当然也可应用于中国象棋。中国象棋的初始局面可表示为:

rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1

(1)、红色区域,表示棋盘布局,小写表示黑方,大写表示红方。一个字母表示一个棋子,对应关系如下。

红方

字母

黑方

字母

对应单词

K

k

king

A

a

advisor

B

b

bishop

N

n

knight

R

r

rook

C

c

cannon

P

p

pawn

至于为什么马不用H(horse),象不用E(elephant),这是为了与国际象棋相对应。如果没有棋子,则用数字表示出相邻连续的空位数。中国象棋共有十行,每行都用一个字符串表示,行间使用正斜杠分割。例如:

  rnbakabnr表示: 

  9表示:第二行都是空格。

  1c5c1表示:

(2)、绿色区域,表示轮到哪一方走子,“w”表示红方,“b”表示黑方。(没有用r表示红方,我想也是为了与国际象棋对应吧,毕竟国际象棋是黑白两色。)

(3)、深紫色区域,在中国象棋中没有意义,始终用“-”表示。

(4)、紫红色区域,在中国象棋中没有意义,始终用“-”表示。

(5)、蓝色区域,表示双方没有吃子的走棋步数(半回合数),通常该值达到120就要判和(六十回合自然限着),一旦形成局面的上一步是吃子,这里就标记“0”。

(6)、棕色区域,表示当前的回合数。

我们的程序就是使用FEN串初始化棋局的,这就涉及到了将FEN串转化为一维棋局数组。暂时不考虑哪方走子,只解析红色部分,伪代码如下:

// 将FEN串转为一维数组 行变量 y = 3 列变量 x = 3 var c = FEN串第一个字符; while (c != " ") { if (c == "/") { // 换行 x = 3; y ++; if (y > 12) { break; } } else if (c >= "1" && c = "A" && c


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有