国际象棋:获取所有合法的国际象棋棋子

问题描述 投票:9回答:5

我正在制作国际象棋,除了一件东西外,几乎获得了所有东西:我需要制造它,以使玩家无法将棋子移动到棋盘上。我在解决这个问题上遇到了麻烦。

我现在在伪代码中产生有效动作的内容是:类getMoveLocations(我将位置定义为国际象棋中那些正方形之一):如果此位置在范围之内,并且位于该位置的棋子是敌人的棋子,并且模拟的移动不会使棋盘受到控制,则将该位置添加到该棋子可以移动到的可能位置。

问题是我如何检查棋盘是否处于“检查中”状态。在我的代码中,它通过收集所有敌人的移动位置并查看这些敌人的移动位置是否与国王的位置重叠来认为棋盘处于“检查”状态。

不幸的是,这是无限循环开始的地方;为了收集所有敌人的电影位置,每个敌人的可能移动位置都需要确保其移动不会使其受到控制。为了确保没有敌人的位置受到控制,它必须收集所有盟友的潜在移动位置,等等。等等。

我很困惑如何获得有效的算法。尽管我的代码“理论上”具有逻辑意义,但无法实现。我对A)一种更有效的方法来检查所有合法举动感兴趣,或者对B)一种解决此无限循环的方法感兴趣。

我正在制作国际象棋,除了一件东西外,几乎获得了所有东西:我需要制造它,以使玩家无法将棋子移动到棋盘上。我在解决问题上遇到麻烦...

java infinite-loop
5个回答
8
投票

有一种更有效的方法来确定一方是否处于受制状态:您只需从国王向外扫描,看看是否发现有可以攻击它的碎片。例如,从国王的位置检查是否有任何敌人的主教沿着对角线等。您根本不需要生成移动列表,因此不需要递归。这是一些伪代码:

function leftInCheck(board, sideToCheck) {

   // one of the four rays for bishop/queen attacks
   d := 0
   while (king rank + d, king file + d) is on the board
      piece := board[king rank + d][king file + d]
      if piece is an enemy bishop or queen
         return true
      if piece is not an empty square   // a piece blocks any potential
         break                          // attack behind it so we can stop
      d := d + 1

   // do this for all the other forms of attack
   ...

   return false
}

2
投票

修改getMoveLocations程序以接受一个标志,该标志指示是否担心进入支票状态。例如,如果一块被固定,它仍然可以移动以捕获对方的国王。如果该标志设置为忽略检查风险,则跳过检查测试将破坏递归。


1
投票

如果采取行动允许敌方能够向您的国王发起进攻行动,则该行动将使您的身旁受到限制(因此不允许这样做)。>>

[请注意,将自己置于对位的状态与将对手置于对位的状态不同-当您将对手置于对位状态时,他们会做出回应。如果您可以进行检查,那么您将有0次机会进行回复。他们将能够俘虏您的国王,这将永远是正确的举动,无论他们所处的位置有多糟糕,甚至即使他们“处于支配地位”-他们都赢了!此后一无所有。


0
投票

[似乎有些张贴者对国际象棋引擎了解不多,所以在尝试争论之前,请仔细阅读并进行研究:

而不是检查它们是否可以移动到那里,而是检查它们是否可以在此处攻击。无论如何,您以后可能会希望将其用于评估功能...


0
投票

基于标题:国际象棋:获取所有合法象棋棋子

© www.soinside.com 2019 - 2024. All rights reserved.