正确计算同伴

时间:2014-02-07 08:24:05

标签: recursion logic chess

在国际象棋中为国王计算将死时,你是否确定其他玩家可能会对你的国王采取行动?或者你只考虑他们的单位?如果你说它是前者,那么就会出现像#34这样的矛盾;这句话是错误的"考虑这个图像,两个国王分开一个方形,他们的骑士从上面保护。如果我们假设可能的移动的定义必须防止基于敌人可能移动的检查,那么逻辑递归地交替。

  
      
  1. 首先,我们说我们的国王是从敌人的骑士那里得到的,所以我们被限制移动我们自己的骑士,因为我们必须逃脱。
  2.   
  3. 然后我们意识到骑士没有可以进入我们国王的广场,因为他将把他的国王放在我们的车上。毕竟,他没有检查我们的国王。
  4.   
  5. 然后我们意识到,从检查开始,我们现在能够将我们自己的骑士移动到敌人国王,迫使他从检查中移开并阻止他进一步选择。
  6.   
  7. 但是,我们注意到我们不能这样做,因为它会让我们与敌人一起检查。
  8.   
  9. 我们意识到,由于我们实际上无法移动我们的骑士,敌人国王实际上并没有受到控制,因此他可以自由地使用他的骑士攻击我们的国王。
  10.   
  11. 转到第2步(无论你已经多少次)。
  12.   

好吧,也许我们假设无论敌人的检查状态如何,触及范围总是很重要。如果我们的国王能够达到敌人骑士通常的攻击范围,我们认为这是一个检查,必须解决它。这是实际游戏的统治方式吗?对编程游戏逻辑时遇到的问题似乎是一个简单的解决方案,但我不确定它是否正确。

Both in check, or neither?

我做了一些思考并想出了这个分析: 我认为你已经证明,两个国王的情况都在受到控制(不一定是我所展示的董事会的情景)不能通过矛盾来存在。 一次只有一名球员可以移动。 因此,一个玩家进行初始移动,从没有国王的状态过渡到一些国王被检查。 根据规则,如果该球员的国王结果在支票中,则不允许这一举动。 (我会很快指出'结果的重要性) 这意味着无论如何定义检查,如果他的国王遇到这种情况,他就不能采取任何行动。 因此,从没有检查的检查的唯一过渡是对被检查的敌人。 敌人必须逃避检查,仍然遵循不进入一次检查的规则。 剩下的状态将是游戏结束或国王逃避检查。

所以我明白两位国王都无法入选。 现在我展示的电路板要么可以到达,要么无法到达。 让我们假设董事会可以到达,看看是否存在矛盾。 由于场景是对称的,所以我们暧昧地假设它已经白了。 这意味着黑色刚刚移动。 因此,黑王不受制于。 黑人国王只能由白骑士到达。 因此,白骑士必须受到某种规则的限制,才能攻击黑王。 可以强制执行该结论的唯一两个可能的规则是:

  
      
  1. 白骑士目前正在保护他的国王免受检查。
  2.   
  3. 白王已经受到检查,这一举动无法解决问题。
  4.   

首先,无论1如何,假设2为真。 白王正在检查中,攻击范围内唯一的一块是黑骑士。 然而,黑骑士不能攻击包含国王的广场,因为它会控制自己的国王。 因此1必须是真的,白王不受制于。 所以这两位国王都没有受到控制。 我们反转游戏板以查看是否可以访问。 假设具有以下更改的方案: 怀特在黑车上有一个主教2和1。 黑王是左边的一个方格。 白王是右边的一个方格。 没有国王在任何其他部分的范围内,因此假设这个初始状态是可达的可能是合理的。 黑骑士正在保护他的国王免受主教的伤害,所以它无法移动到白衣骑士手下。 白王向左移动。 现在白骑士正在保护白王,不能移动到黑骑士手下。 黑王向右移动一个方格。 因此,该方案是可达的。 唯一质疑的假设是,当考虑任何移动时,可以安全地假设计算检查规则。因此,国王可能来到一个单位的范围内,由于防止他自己的国王受到控制而不能攻击它。如果没有做出这样的假设,那么这些碎片就可以遵循不允许国王进入敌方单位的无限制攻击范围的规则。 现在,有趣的是看看这个场景是否可以在没有无限循环的情况下进行计算。 对于依赖项,我将使用箭头。 对于最初的白王向左移动, 白王 - >黑骑士停了 - >白主教攻击黑王 这些是单步计算,到目前为止依赖性没有循环。 为了让黑王向右移动, 黑王 - >白骑士停了 - >黑车攻击白王 仍然没有依赖。 那么当我们现在试图检查白骑士的可用行动时,包括攻击黑王? 白骑士停了 - >黑车攻击白王 如果白车攻击黑车怎么样? 白车停了 - >黑骑士袭击白王 白方的剩余选择是让国王向右或向下移动。

我们的结论,

  
      
  1. 在不违反“检查”的情况下,可以进入这个董事会状态。规则。
  2.   
  3. 这个委员会状态显然假设计算检查取决于可能的敌人移动,而不是简单的原生攻击范围。
  4.   
  5. 当达到这种状态时,两个国王都没有被检查。
  6.   
  7. 至少可能这不是僵局。 (如果总是未知)
  8.   

所以我终于在维基百科上找到了关于让另一位国王受到控制的规则,即使它会损害自己的国王。因此,我们不能在第2部分中做出假设,因此无法达到电路板状态。 "一块无法移动的东西,因为它会控制自己的国王(它固定在自己的国王身上)可能仍会向对方玩家提供支票。" 因此,我们对国际象棋明显的实际规则做出了最终结论,因为它遵循了检查规则,因此无法达到董事会状态。

我将选择icedtrees答案,因为遵循游戏规则的有价值的逻辑:

if for every move for player X (ignoring rules about king threats), 
player Y can capture player X's king next turn, 
then player X is in checkmate.

但是,我会将它们修复为以下内容:

{X is checkmate}
if and only if {
    For all legal moves:(move according to rule definition) X {
       There exists a generic move:(legal move A ignoring rules of protecting king A) Y such that {
          X king is captured
       }
    }
}

4 个答案:

答案 0 :(得分:4)

我可能会误解,但我认为你的问题很容易解决,因为它指出只有轮到你才能检查它。国际象棋与强制性相关联,强制要求为支票辩护,如果轮到你,你就不能这样做。

对于任何国际象棋的位置,定义轮到它是非常重要的,因为这背后有很多机制。在你的电路板位置,如果是黑色,则检查黑色,如果是白色,则检查白色。

即使这个位置是不可能的,你仍然可以定义一些关于有利于国际象棋计算的位置的好规则。

关于国际象棋中的将死的一些注释:

Checkmate实际上不是很直观,当你玩游戏时,你会开始注意到有趣的将死情况,这些情况没有多大意义。

在我看来,这是一种考虑将死的好方法:

  • 在一个合法的国际象棋比赛中,当被检者发生时,被检查的玩家无法阻止他的国王被对方玩家连续转向捕获。也就是说,国际象棋中的将死只不过是“提前一转结束游戏”,可以这么说。如果你忽略国际象棋中关于国王威胁的所有规则,但保留棋子的运动模式,计算机可以通过展望来计算敌人。

逻辑如下:

如果对于玩家X的每一次移动(忽略关于国王威胁的规则),玩家Y可以在下一回合捕捉玩家X的王,然后玩家X将被击杀。

以下是“检查和转义检查”的更完整版本:

鉴于玩家X轮到: 如果玩家X的国王处于玩家Y的移动范围内,那就是在检查中。如果这件作品无法逃脱检查,那就是将死。

有三种逃避检查的方法:

  1. 将你的国王移到一个没有受到攻击的广场
  2. 阻止交付支票
  3. 捕捉检查件。

答案 1 :(得分:1)

也许你过度思考: - )

这是来自工作国际象棋程序的算法,该算法在人类方面相对较强:

  • 生成要移动的一侧的伪合法移动列表。通过伪合法,我的意思是不要费心去验证所产生的移动是否会使该方的国王受到控制。省略此验证可以节省验证从未搜索过的移动的时间。
  • 对于 搜索的每次移动,请确认它不会让一边移动进行检查。
  • 如果每一步都让国王受到控制,那么移动的一方要么已经交配,要么已经陷入僵局。
  • 如果要移动的一方当前正在检查中,那么它就会交配。否则就会陷入僵局。

答案 2 :(得分:1)

一方面,这个董事会职位不可能遥遥无期。

1)您是如何在不移动任何棋子的情况下将车队和国王从第一和第八位降下来的?

2)支票被定义为您的国王受到敌方进攻的状态。 CheckMATE是您在检查中并且无法合法退出检查的情况。

3)如果轮到您,并且您的其中一个棋子能够抓住对手的国王,那么您是否可以放任自己选择也没关系:这是谁的国王先死?

4)尽管如此,如果轮到你了,而你的对手处于检定中,则这意味着没有一个玩家注意到你的对手在了检定中(在这种情况下,您要回去并确保他们可以并且可以做到)请先检查,然后再执行其他操作),否则没人会注意到它是将死的。

因此,轮到您时,您无法完成检定,但在确定对国王的威胁时,对立国王的安全性无关紧要。

答案 3 :(得分:0)

我天真的做法可能就是这样。

player.startTurn();
if (player.isInCheck()
    if(player.king.hasNoLegalMoves() && player.cannotProtectKing())
        game.checkMate(player);

function isInCheck() {
    boolean isInCheck = false;
    for (Piece p : player.Opponent)
        if (p.canAttack(player.king) {
            isInCheck = true;
            return;
        }

我可能在这里遗漏了一些东西,但我不明白为什么不会这么简单。