美文网首页程序员
8年C++大神教你开发:象棋人工智能算法的C++实现(二)

8年C++大神教你开发:象棋人工智能算法的C++实现(二)

作者: Python编程导师 | 来源:发表于2019-03-11 20:49 被阅读9次
image.png

有了上一期的铺垫,本期就可以实现诸如马走日、象走田等各种棋子的走棋算法了。为了方便后期人工智能算法的实现,我们写一个总的canMove函数,在这个总的canMove函数里调用各种类型棋子的canMove函数来判断各种棋子选择的路径能不能走得通。
这是小编准备的C/C++学习资料,加小编C/C++学习群(825414254)获取一整套系统性学习的C/C++教程

QQ截图20190309205647.jpg

总的canMove函数的源代码:

image

本期主要介绍相对简单的士、兵、相、马的走棋算法。

1.士的走棋算法

士的走棋规则:只能在米字格(大本营)内行走,且一次只能沿着对角线斜着走一步。

上canMoveSHI函数的源代码:

image

算法解析:红方和黑方的米字格范围不同,红方米字格的范围:row:02,col:35;黑方米字格的范围:row:79,col:35。要想让士沿着对角线斜着走,就是想让移动前后的横坐标差的绝对值和纵坐标差的绝对值都为1,横纵各移动一个单位长度。

士的行走图示:

image

2.兵的走棋算法

兵的走棋规则:无论过没过河,纵向上都不能走回头路。没过河的时候只能纵向走,过了河才可以横向走。

上canMoveBING函数的源代码:

image image

算法解析:兵的走棋算法的实现就比士的要难,既要处理每次移动的长度又要区分过河前和过河后的情况。实现不能走回头路的方法是计算行坐标差,以下图所示为例,以上一期博客所述的坐标系为准,红方在上,黑方在下,则红兵不能走回头路的控制条件就是行坐标差(当前位置的行坐标-目标位置的行坐标)必须为-1,黑兵不能走回头路的控制条件就是行坐标差(当前位置的行坐标-目标位置的行坐标)必须为1。实现过河与否的判断则是通过简单的行坐标范围来界定。实现步长为1的控制则更为简单,即行坐标差的绝对值为1且列坐标差的绝对值为0(或行坐标差的绝对值为0且列坐标差的绝对值为1)。

image

3.相的走棋算法

相的走棋规则:走田字格。若所跨田字格的中心位置有棋子存在,此时为“别象眼”,相便不能完成行走。相不能过河。

上canMoveXIANG函数的源代码:

image

算法解析:实现走田字格的控制条件即是行坐标差的绝对值为2且列坐标差的绝对值为2(横纵方向上的移动步长都为2)。实现过河与否的判断则是通过简单的行坐标范围来界定。别象眼检验是相的走棋算法的核心部分,此处运用了一点初中数学知识,即中点坐标的求法,田字格对角线上的中点的坐标为((相的当前行坐标+目标位置行坐标)/2,(相的当前位置列坐标+目标位置列坐标)/2)。确定了象眼的行列坐标再调用上期博客介绍的beStone函数即可得知象眼处是否有棋子,若有棋子相则不能完成行走。

相的行走图示:

image

4.马的走棋算法

马的走棋规则:走日字格(横向移动1格且竖向移动2格or横向移动2格且竖向移动1格)。移动2格的那个方向上距离马当前位置最近的位置上若有棋子存在,则此时为“别马腿”,马便不能完成行走。

上canMoveMA函数的源代码:

image

算法解析:实现走日字格的方法是控制行坐标差的绝对值为1且列坐标差的绝对值为2(或行坐标差的绝对值为2且列坐标差的绝对值为1)。要想实现别马腿的检验就要先确定马的“绊脚石”的行列坐标,若马的移动步长为2的方向为横向,则该“绊脚石”的坐标为(马的当前位置行坐标,(马的当前位置列坐标+目标位置列坐标)/2);若马的移动步长为2的方向为纵向,则该“绊脚石”的坐标为((马的当前位置行坐标+目标位置行坐标)/2,马的当前位置列坐标)。

马的行走图示:

image

看到这里可能有人会说,我不会使用Qt开发项目,不用担心,整个项目的算法都可以抽象到控制台应用程序(黑框框)中,大家可以先动脑筋实现一下。如果后期还有人提问在黑框框中如何实现,我会视具体情况在后面的博客中加以介绍。

相关文章

网友评论

    本文标题:8年C++大神教你开发:象棋人工智能算法的C++实现(二)

    本文链接:https://www.haomeiwen.com/subject/srjipqtx.html