这是有效的棋步吗?


15

备用名称: ChessMoveQ

给定最多包含32个元素的列表,每个元素由4个元素组成,以及具有4个元素的第二个列表,请确定第二个输入中详细说明的移动是否是有效的国际象棋移动。

第一个列表指示所有32个部件在板上的位置。每个元素都将遵循结构<colour>, <piece-name>, <x-coord>, <y-coord>,例如["W", "K", 5, 1],它指示白色国王在上面5, 1e1在正常的棋盘上)。第一个输入的所有元素都是唯一的。<x-coord>并且<y-coord>始终在1到8之间。一个示例是:

[["B", "K", 3, 8], ["B", "Q", 1, 5], ["B", "N", 4, 7], ["B", "N", 7, 8],
 ["B", "B", 2, 4], ["B", "R", 4, 8], ["B", "R", 8, 8], ["B", "P", 1, 7],
 ["B", "P", 2, 7], ["B", "P", 3, 6], ["B", "P", 5, 6], ["B", "P", 6, 7],
 ["B", "P", 7, 7], ["B", "P", 8, 7], ["W", "K", 5, 1], ["W", "Q", 6, 3],
 ["W", "N", 3, 3], ["W", "B", 5, 2], ["W", "B", 6, 4], ["W", "R", 1, 1],
 ["W", "R", 8, 1], ["W", "P", 1, 3], ["W", "P", 2, 2], ["W", "P", 3, 2],
 ["W", "P", 4, 4], ["W", "P", 6, 2], ["W", "P", 7, 2], ["W", "P", 8, 3]]

代表董事会:

棋盘的例子

第二个输入将由与第一个输入的子列表相同的结构组成,但不是x和y坐标指示该片段在哪里,而是指示其试图移动到的位置。

对于上面的示例,有效的移动可能是["W", "B", 4, 3](主教向前和向左移动一个正方形),而无效的移动可能是["B", "R", 4, 1]由于车队必须穿过骑士,而典当才能到达该正方形。由于一次移动可能涉及多个片段,因此您必须测试指定的任何片段是否可以进行移动,而不仅仅是其中一个。例如,第一个示例仅对一个主教有效,但仍然是有效的举动。但是,两个黑鸦都无法执行第二步,因此无效。

您的任务是确定第二个输入中详述的移动是否是有效的国际象棋移动。规则的有效性取决于尝试移动的棋子(单击棋子的名称以获取有效棋子的图表):

  • 任何一块:任何块都不能移动到已经占据的正方形上或离开木板,除非该正方形被另一种颜色的一块占据。例如,一块白色可能会移动到一块被一块黑色占据的正方形上,但不能移动到一块白色占据的正方形上。此外,除了骑士之外,没有其他物件可以移动到被另一物件直接遮挡的正方形。
    • 如果ABC之间以直线(正交或对角线)直接位于A处,B块向正方形C的移动将被A块“直接阻碍” 。
  • 任何棋子:国王的位置也会影响棋子移动的有效性。如果满足以下两个条件之一,则此移动无效:
    • 通过移动一块与濒临灭绝的国王相同的一面,使国王可以检查。这仅在不反对的棋子移动而不是相对的棋子移动以使国王受阻的情况下才适用。
    • 将国王留在检查中,在这种情况下,它必须移出检查。因此,如果国王处于制止状态,并且该举动指示有另一枚棋子移动,则除非该另一枚棋子阻止了制衡,否则这是无效的举动。一个棋子可以通过以下两种方式之一防止检查:要么执行棋子,要么阻碍棋子与国王之间的路径。
    • “支票”是指国王的对手可以(如果轮到他们移动)可以合法地将棋子移动到国王身上的情况。此规则不适用于递归规则,即即使对手移动到该国王将使自己的国王受到控制,国王也将受到控制。
  • 棋子:棋子可以向前移动(即,如果是白色,则向上移动;如果是黑色,则向下)移动一个正方形到一个空置的正方形。还有三种特殊情况:
    • 如果pawn尚未移动(您可以使用Y坐标来确定;如果pawn的Y坐标为2,则白色pawn不会移动;如果pawny的Y坐标为7,则黑色pawn不会移动)。允许将两个正方形向前移动到一个空闲的正方形。
    • 如果在棋子的对角线上有一个对手的棋子(例如,棋子是白色,则位于棋子的西北方或东北方,如果棋子是黑色,则在西南方或东南方)允许将棋子移至相关的被占领方格上。
    • 如果典当按照常规国际象棋规则移动到最终的Y坐标(白色为8,黑色为1),则必须将其提升为相同颜色的皇后,新人,骑士或主教。出于此问题的目的,升迁的选择与举动是否有效(并且不能以输入格式表示)无关,但是必须允许会导致升迁的典当举动。
  • 主教:主教可以沿着任何连续的无障碍心向(即对角线)路径在1到8格之间移动。
  • 骑士:骑士可以移动的L形状,由以下(等效)移动之一组成:
    • 在任何基本方向上移动一个正方形,然后旋转90/270°,最后向前移动2个正方形。
    • 在任何基本方向上移动2个正方形,然后旋转90/270°,然后最后向前移动一个正方形。
    (请记住,尽管最后的方块仍然是合法的,但是骑士的步伐不能被中间的物品所阻挡。)
  • 白嘴鸦:白嘴鸦可以沿着任何连续无障碍的基本路径移动1到8格。
  • 皇后区:皇后区可以沿着任何连续的主干或心间(即对角线)无障碍路径移动1到8格。
  • 国王:国王的移动方式类似于皇后,但仅限于每步只能移动一个正方形(即,国王只能移动到与基数或对角线相邻的正方形)。提醒一下,您不能采取任何行动阻止国王的到来。因此,你也不能动摇你的国王。

国际象棋的规则还包含称为“城堡”和“传人”的特殊动作。但是,由于这些移动的合法性不仅取决于当前的位置,还取决于游戏的历史(并且由于castling要求一次移动两块,这与输入格式不符),因此您不应该考虑这些移动存在(即举棋不定或过失的举动应视为非法)。

您可以输出任何两个不同的结果来指示移动的有效性,并且可以在所需的方法中进行输入。如果愿意,您也可以选择0索引而不是1索引。这是一个,因此最短的代码获胜!

测试用例

Board
Move => Output (Reason)

[["B", "K", 3, 8], ["B", "Q", 1, 5], ["B", "N", 4, 7], ["B", "N", 7, 8], ["B", "B", 2, 4], ["B", "R", 4, 8], ["B", "R", 8, 8], ["B", "P", 1, 7], ["B", "P", 2, 7], ["B", "P", 3, 6], ["B", "P", 5, 6], ["B", "P", 6, 7], ["B", "P", 7, 7], ["B", "P", 8, 7], ["W", "K", 5, 1], ["W", "Q", 6, 3], ["W", "N", 3, 3], ["W", "B", 5, 2], ["W", "B", 6, 4], ["W", "R", 1, 1], ["W", "R", 8, 1], ["W", "P", 1, 3], ["W", "P", 2, 2], ["W", "P", 3, 2], ["W", "P", 4, 4], ["W", "P", 6, 2], ["W", "P", 7, 2], ["W", "P", 8, 3]]
["W", "R", 8, 2] => True (The rook on h1 can move forward one)

[['B', 'K', 6, 8], ['B', 'Q', 1, 7], ['B', 'N', 1, 3], ['B', 'N', 7, 1], ['B', 'B', 8, 8], ['B', 'B', 2, 5], ['B', 'R', 4, 3], ['B', 'R', 1, 5], ['B', 'P', 5, 5], ['B', 'P', 7, 2], ['B', 'P', 5, 7], ['B', 'P', 5, 6], ['B', 'P', 4, 4], ['W', 'K', 7, 3], ['W', 'Q', 3, 2], ['W', 'N', 4, 8], ['W', 'N', 7, 5], ['W', 'B', 1, 1], ['W', 'B', 8, 1], ['W', 'R', 1, 8], ['W', 'R', 3, 7], ['W', 'P', 8, 2], ['W', 'P', 6, 3], ['W', 'P', 4, 2], ['W', 'P', 1, 4], ['W', 'P', 8, 7]]
['W', 'N', 1, 5] => False (Neither knight to move to a5 from where they are)

[['B', 'K', 7, 3], ['B', 'Q', 2, 4], ['B', 'N', 5, 2], ['B', 'N', 1, 6], ['B', 'B', 7, 7], ['B', 'B', 1, 8], ['W', 'K', 7, 1], ['W', 'Q', 6, 1], ['W', 'N', 5, 6], ['W', 'N', 3, 3], ['W', 'B', 2, 2], ['W', 'B', 6, 5]]
['B', 'K', 8, 3] => False (The white bishop would put the king in check)

[['B', 'K', 7, 6], ['B', 'Q', 8, 3], ['B', 'N', 7, 7], ['B', 'N', 8, 7], ['B', 'B', 2, 2], ['B', 'B', 3, 8], ['B', 'R', 1, 1], ['B', 'R', 1, 6], ['B', 'P', 8, 5], ['B', 'P', 4, 3], ['B', 'P', 8, 6], ['W', 'K', 7, 8], ['W', 'Q', 7, 2], ['W', 'N', 5, 1], ['W', 'N', 4, 6], ['W', 'B', 1, 2], ['W', 'B', 2, 6], ['W', 'R', 4, 4], ['W', 'R', 3, 6], ['W', 'P', 5, 2], ['W', 'P', 6, 2]]
['B', 'N', 5, 8] => False (The white queen currently has the king in check, and this move doesn't prevent that)

[['B', 'K', 7, 6], ['B', 'Q', 8, 3], ['B', 'N', 7, 7], ['B', 'N', 8, 7], ['B', 'B', 2, 2], ['B', 'B', 3, 8], ['B', 'R', 1, 1], ['B', 'R', 1, 6], ['B', 'P', 8, 5], ['B', 'P', 4, 3], ['B', 'P', 8, 6], ['W', 'K', 7, 8], ['W', 'Q', 7, 2], ['W', 'N', 5, 1], ['W', 'N', 4, 6], ['W', 'B', 1, 2], ['W', 'B', 2, 6], ['W', 'R', 4, 4], ['W', 'R', 3, 6], ['W', 'P', 5, 2], ['W', 'P', 6, 2]]
['B', 'N', 7, 5] => True (The king is in check, and the knight blocks that)

[['B', 'K', 8, 3], ['B', 'Q', 6, 5], ['B', 'N', 7, 8], ['B', 'N', 3, 7], ['B', 'B', 4, 1], ['B', 'B', 1, 1], ['W', 'K', 7, 7], ['W', 'Q', 7, 1], ['W', 'N', 2, 2], ['W', 'N', 1, 3], ['W', 'B', 3, 5]]
['B', 'B', 2, 2] => True (takes the white knight)

[['B', 'K', 6, 1], ['B', 'Q', 6, 2], ['W', 'K', 8, 1]]
['B', 'Q', 7, 1] => True (Smallest checkmate possible, in terms of bounding box)

这个挑战被沙盒化了。它收到了投票,没有任何解释,所以我还是决定将其发布


“同一边的一块移动,使国王可以检查。” -现在您将标题移到下方时,该措辞似乎不合适。我将其更改为诸如“移动此块会使国王检查”
FlipTack

这个问题在“沙箱”中被否决了,现在这里没有一个解释。我无法做任何让您告诉我为什么投票的理由,但至少要有体面的方式来解释自己的行动,而不是在阴影中保持沉默。如果您认为这篇文章可以改善,请提出建议,而不要在不解释自己的情况下大发雷霆。
caird coinheringaahing

2
没人反对吗...?
FlipTack

1
我们能否获得二维的零件阵列作为输入?
ovs '17

1
@ovs是的,这似乎可以接受
caird coinheringaahing

Answers:


3

Python 2(with python-chess), 141138134133132 字节

无需编写任何真正有趣的代码-但这也许可以与高尔夫语言或(敢于提及)Mathematica竞争?

注意:python-chessPyPI将包安装Python的2.7.9+有:
python -m pip install python-chess

import chess
a,p,n=input()
S=chess.Board(a+' - - 0 1')
for m in S.legal_moves:1/(m.to_square!=n)**(`p`in`S.piece_at(m.from_square)`)

接受三项输入的完整程序:

  1. FEN记录的开头-包含前两个字段的字符串。这是为了定义板的状态以及正在移动的颜色(因为这是OP中输入中的信息,而3到6字段由OP“固定”,因此不应成为输入的一部分)
  2. 试图移动的零件名称(如操作说明中所述-之一PRNBQK
  3. 命名的块试图移动到的正方形a10b11,... a28,...,h863

程序通过其退出代码输出给定有效输入的输出:

  • 1 如果移动是有效的(程序引发错误-由于除以零);
  • 0 它不是(程序正常退出)

(不要)在线尝试!(因为python-chess软件包没有安装在那里,并且TIO不允许Internet连接,所以标头中的pip-install代码将无法工作)。

需要注意的是在Python幂运算符使得1**1 == 1**0 == 0**0 == 1但是0**1 == 0
......因此1/0**1零错误提出了一个划分,同时1/1**11/1**01/0**0所有成功的
(......这在Python FalseTrue等同于01分别)。


2
这是一个非常有效的答案,但有点像作弊,类似于仅内置的Mathematica答案。
caird coinheringaahing

是的,因此我将注释放在顶部“不做任何真正有趣的代码...”,也许当我有更多时间时,我将做一个果冻(无法导入此模块:))
乔纳森·艾伦·

1
...请注意,您仍然需要付出一些努力。
乔纳森·艾伦

重新排列str(S.piece_at(m.from_square))==p forp==str(S.piece_at(m.from_square))for,应节省一个字节。
扎卡里

嗯,是的-感谢@Zacharý我只是想看看我是否可以通过repr使用反引号进行解析以替换str保存...
Jonathan Allan

3

正则表达式(PCRE2),931 925 837字节

该解决方案与问题陈述不同,因为有两个板状态传递给了正则表达式,而不是一个板状态和一个移动。从两个板状态之间的差异可以推断出这一举动。因此,我以TIO程序的工作来采取此问题提供的格式的测试用例,在板上找到所描述块的所有实例,并逐个尝试将其移到目标位置并评估正则表达式在这种可能性下,查找正则表达式是否报告了任何有效内容。如果这样不好,请告诉我;可以将正则表达式作为位置+移动来实现,但这种方式不太优雅,需要进行认真的重构。

:该板在8×8 ASCII其中白件是大写和黑色小写表示P芒,K Ñ飞行, ishop,- [R OOK,Q ueen,ķ ING。黑人一侧(第8位)在顶部,白人一侧(第1位)在底部。每个等级之间用换行符分隔,空方格标记为-。这两个板的位置之间用多余的换行符隔开。

该项目的实际目的是验证整个游戏,而不仅仅是单招。有关当前的进展情况,请参见下文。

()?(?>|((.|
(?=.)){2})((?=(\X{72})-))((?=(?(1)[-a-z]|[-A-Z])))((?5)(?(?=(.*
)
)[qnrb]|p))((?5)(?(?=(?8){8}
)[QNRB]|P)))(?>((.)(?=(?5)\11)|(?(m)$)((?(1)(-(?=(?9))(?=(?3){8}((?3){9})?P(?4))(?(-1)(?=(?8){4}
))|[a-z](?=(?9))(?=(?3){7}(?2)?P(?4)))|(p(?4)((?=(?3){8}((?3){9})?-(?7))(?(-1)(?=(?8){7}
))|(?=(?3){7}(?2)?[A-Z](?7)))))|(?<e>(?6).)?(?=(?i:(?|(?(e)|(B|Q))(?27)(?(e)(B|Q))|(?(e)|(R|Q))(?31)(?(e)(R|Q))|(?(e)|(N))(?34)(?(e)(N))|(?(e)|(K))(?35)?(?(e)(K))))(?(e)(?<=(?!(?6)).)(?4)|(?6).(?5)\19))(?(e)(?=(?5)\20)|(?!(?6)).(?4)))(?<m>)|(?(+1)$)(.))+
)+\k<m>
(?!\X{0,70}((?(1)p|k)(?=(?3){7}(?2)?(?(1)K|P))|(?i:(?<E>(?!(?6))K)?((?(E)|((?6)[BQ]))(()?((?(-1)-)(?3){7}(?(-2)(?2)))+)(?(E)(?-4))|(?(E)|((?6)[RQ]))(-*|((?(-1)-)(?3){8})+)(?(E)(?-3))|(?(E)|((?6)N))((?<=..)(?2){3}|(?=.)(?2){5}|(?2){8}(?2)?)(?(E)(?-2)))(?(E)|(?&E))|K((?3){7,9})?K)))

在线尝试!

印刷精美,部分不贴合(绝对后向引用更改为相对,捕获组更改为非捕获,或在某些情况下为速度而原子化):

# Chess move validation regex (PCRE)
()?                 # decide whether to evaluate this as white's or black's move; \1 set = white, \1 unset (NPCG) = black
(?>|                # subroutines:
  ((.|\n(?=.)){2})                  # (?3) = for moving within the board, without wrapping to the next board, (?2) = (?3){2}
  ((?=                              # (?4) = assert that position of just-consumed piece is vacated on the next turn
    (\X{72})                        # (?5) = skip to the position of the just-consumed piece on the next turn
  -))
  ((?=(?(1)[-a-z]|[-A-Z])))         # (?6) = assert that the piece at the current position belongs to the current player's opponent or is empty
  ((?5)(?(?=(.*\n)\n)[qnrb]|p))     # (?7) = black pawn that might be promoted, (?8) = .*\n
  ((?5)(?(?=(?8){8}\n)[QNRB]|P))    # (?9) = white pawn that might be promoted
)
(?>
  (?>
    # Handle squares that don't change (empty->empty or pieces that doesn't move)
    (.)(?=(?5)\g{-1}) |
    # Handle a piece that moves (and optionally captures an enemy piece)
    (?(m)$)  # allow only one move to be made per turn
    (?>
      (?(1)
        (?:                                                         # white pawn
            -  (?=(?9))(?=(?3){8}((?3){9})?P(?4))(?(-1)(?=(?8){4}\n)) |   # move 1 or 2 spaces forward
          [a-z](?=(?9))(?=(?3){7}(?2)?     P(?4))                     )   # capture diagonally
      |
        (?:p(?4)(?:                                                 # black pawn
          (?=(?3){8}((?3){9})?  -  (?7))(?(-1)(?=(?8){7}\n)) |            # move 1 or 2 spaces forward
          (?=(?3){7}(?2)?     [A-Z](?7)) )                   )            # capture diagonally
      ) |
      # bishops, rooks, queens, knights, or kings
      (?<e>(?6).)?   # decide between scanning forward (<e> is unset) or backwards (<e> is captured)
      (?=
        (?i:
          (?|
            (?(e)|(B|Q)) (?&B)  (?(e)(B|Q)) | # bishops or queens
            (?(e)|(R|Q)) (?&R)  (?(e)(R|Q)) | # rooks or queens
            (?(e)|(N  )) (?&N)  (?(e)(N  )) | # knights
            (?(e)|(K  )) (?&K)? (?(e)(K  ))   # kings
          )
        )
        (?(e)(?<=(?!(?6)).)(?4)|(?6).(?5)\g{-2})   # verify that the piece moved, and optionally captured piece, are of the correct color
      )
      (?(e)(?=(?5)\g{-1})|(?!(?6)).(?4))   # verify that the piece moved is the same type and color at its destination in the next turn's board position
    )(?<m>) |
    (?(+1)$)(.)  # handle the destination/source square that a piece moved to/from (only allow matching one of these per turn)
  )+\n
)+
\k<m>         # assert that a move has taken place
\n
# don't allow moving into check  
(?!
  \X{0,70}
  (?:
    # pawns (capture diagonally)
    (?(1)p|k)(?=(?3){7}(?2)?(?(1)K|P)) |
    # bishops, rooks, queens, knights, or kings
    (?i:
      (?<E>(?!(?6))K)?   # decide between scanning forward (<E> is unset) or backwards (<E> is captured)
      (?:
        (?(E)|((?6)[BQ])) (?<B>()?((?(-1)-)(?3){7}(?(-2)(?2)))+)         (?(E)(?-4)) | # bishops or queens
        (?(E)|((?6)[RQ])) (?<R>-*|((?(-1)-)(?3){8})+)                    (?(E)(?-3)) | # rooks or queens
        (?(E)|((?6) N  )) (?<N>(?<=..)(?2){3}|(?=.)(?2){5}|(?2){8}(?2)?) (?(E)(?-2))   # knights
      )
      (?(E)|(?&E)) |
      K(?<K>(?3){7,9})?K   # kings
    )
  )
)

-88字节(通过使用非原子子例程调用),因此从PCRE1重定向到PCRE2

上面的版本已被修改,不允许传递或滚动,但是整个项目目前处于一种状态,在此状态下,它可以验证每种类型的移动,从初始棋盘状态开始(必须是标准国际象棋的开始位置– Chess960不是支持,但至少)。强制执行传人和cast割的全部规则。

这是一个由完整正则表达式(PCRE1-尚未重新定向)[regex101.com]验证的示例游戏

无效的移动将导致每个后续的电路板位置都不匹配/突出显示。尚未实现将死/僵局的检测,从而无法检测出谁是赢家(或是否是平局);这就是为什么此示例中最终的董事会状态未突出显示的原因。

这是一个C / C ++程序,它将代数符号转换为此正则表达式可识别的格式。当前,代数表示法必须在源代码中以内联数组的形式放置,每次移动都使用单独的字符串,但要从stdin或命令行参数中将其读取为单个字符串,且整个移动顺序都用空格分隔以及以点结尾的移动编号。

我还从一个正则表达式开始,该正则表达式完全用代数国际象棋符号验证了整个游戏,并隐含了标准的初始位置。它所需要的只是在输入末尾(在移动列表之后)添加一个空的“草稿板”。我很确定有可能完全实现它,并计划在某个时候完成它。


自从我为Sudoku验证问题咳出3000字节的正则表达式怪胎以来,我还没有感到那么恐惧(这是一个巨大的错误,考虑到获胜的答案不到75个)。真实地证明了一点,有时当您使用正则表达式解决问题时,最终会遇到两个问题
Value Ink

@ValueInk嘿,也许您是对的,但不管它(完全是)不切实际,我都喜欢它。您的评论激发了我尝试回答Sudoku问题的​​能力,但我只管理了200个字节。那好吧。
Deadcode '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.