如何在没有循环依赖的情况下检查国际象棋规则?

时间:2015-02-20 02:10:39

标签: chess

我用C ++编写国际象棋程序。我遇到了一个我可能应该预见到的问题。程序找到所有可能移动的方式是尝试将每个块移动到板上的每个方块。执行此操作的函数称为calculateAllPossibleMoves。通过克隆游戏并在正在测试的作品上调用move来测试每个动作。移动无效时,move函数将抛出异常。如果没有抛出异常,那么该移动是有效的,并且它被添加到可能的移动列表中。

如果移动导致您的王被检查,则此移动无效。所以我有一个函数,它使用find-all-possible移动函数(让我们称之为inCheck)来查看对手的一个棋子是否会检查国王。

问题是,前面提到的move函数依赖于inCheck函数来确定移动是否导致检查。 inCheck使用calculateAllPossibleMoves查找可能导致国王的所有行动。 calculateAllPossibleMoves通过使用普通move函数模拟移动来查找所有可能的移动。这段代码永远运行,因为它是相互递归的。

为了尝试修复它,我所做的是通过传入一个整数来引入边缘情况。因此,当我调用move时,它会递减整数并将其传递,并且当再次调用move时,将使用较小的数字调用它。这样,无法递归是无法实现的。

然而,结果似乎有所不同,当我增加数字时,程序需要非常长时间运行。有没有更清洁的方法来解决这个问题?

2 个答案:

答案 0 :(得分:1)

为什么你没有所有国际象棋棋子继承的抽象类ChessPiece,以及其他32个对象或其他类游戏中支持类BoardPosition的东西。或者什么。

然后列出所有动作,只需通过活动(未捕获)棋子,并通过他们的动作进行每个循环(大多数是方向+平方数)。如果(1)way上没有任何棋子并且目标位置没有相同颜色的棋子,则移动有效;(2)未经测试移动的对手没有可能的棋子移动机会在更新的棋盘中捕获你的国王(因为那是什么检查 - 伙伴只是意味着你无法避免对手夺走你的国王)

答案 1 :(得分:1)

你真正需要的是一个calculateIntersectingMoves函数,它只是检测是否有任何碎片与有问题的正方形相交的有效移动,并将其调用以进行检查检测。

如果calculateAllPossibleMoves被准确命名,那么仅使用它来查看是否有任何可以到达特定方格的碎片是非常低效的;更糟糕的是,它会导致你提到的确切圆形。