有効なチェスの動きですか?


15

代替名: ChessMoveQ

それぞれが4つの要素で構成される最大32個の要素のリストと、4つの要素を持つ2番目のリストが与えられた場合、2番目の入力で詳細な動きが有効なチェスの動きであるかどうかを判断します。

最初のリストは、ボード上の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]]

ボードを表します:

チェス盤の例

2番目の入力は、最初の入力のサブリストと同じ構造で構成されますが、x座標とy座標が作品の位置を示すのではなく、移動先を示します。

上記の例では、有効な移動は["W", "B", 4, 3](司教が1マスを左前方に移動する)であり、無効な移動は["B", "R", 4, 1]、ルークがナイトとポーンを通過してスクエアに到達する必要がある場合です。移動は時々複数のピースを参照する可能性があるので、指定されたピースの1つだけではなく、いずれかが移動できるかどうをテストする必要があります。たとえば、最初の例は1人の司教にのみ有効ですが、それでも有効な動きです。ただし、どちらの黒ルークも2番目の移動を実行できないため、無効です。

あなたの仕事は、2番目の入力で詳述された動きが有効なチェスの動きであるかどうかを判断することです。ルールの有効性は、移動しようとするピースによって異なります(有効な移動の図については、ピースの名前をクリックしてください)。

  • 任意のピース:他の色のピースでそのスクエアが占有されていない限り、ピースはすでに占有されている正方形に移動したり、ボードから移動したりすることはできません。たとえば、白い部分は黒い部分で占められている正方形に移動できますが、白い部分では移動できません。さらに、騎士以外の駒は、他の駒によって直接遮られているマスに移動できません。
    • ピースBから正方形Cへの移動は、ABCの間の直線(直交または斜め)に直接ある場合、ピースAによって「直接妨害」されます。
  • 任意のピース:キングの位置は、ピースの動きの有効性にも影響を与える可能性があります。これらの2つの条件のいずれかが満たされている場合、移動は無効です。
    • 絶滅の危機にある王と同じ側にある駒を動かすことにより、王をチェックするためにさらします。これは、反対側の駒がキングをチェックするために移動するのではなく、反対側の駒が移動する場合にのみ適用されます。
    • それが、その場合には、チェック、で王を残しているチェックの外に移動すること。したがって、キングがチェック中にあり、その動きが別の駒の移動を指示する場合、他の駒がチェックを妨げていない限り、それは無効な動きです。ピースは、チェックを実行するピースを取得するか、チェックを実行するピースとキングとの間のパスを妨害するかの2つの方法のいずれかでチェックを防ぐことができます。
    • 「チェック」とは、王の対戦相手が(移動する順番であれば)合法的にその王に駒を移動できる状況です。このルールは再帰的に適用されません。つまり、相手のキングがそのキングに移動しても自分のキングがチェックされたままになっても、キングはチェックされます。
  • ポーン:ポーンは、1つの正方形から空いている正方形に向かって前方に移動できます(つまり、白の場合は上向き、黒の場合は下向き)。また、3つの特別な状況があります。
    • ポーンがまだ移動していない場合(Y座標を使用してこれを決定できます。Y座標が2の場合、白いポーンは移動していません。Y座標が7の場合、黒いポーンは移動していません)、ポーン2つの正方形を空いている正方形に移動できます。
    • ポーンの前に敵の駒がある場合(つまり、ポーンが白の場合はポーンの北西または北東の正方形、黒の場合は南西または南東の正方形)、ポーンは、問題の占有されている広場に移動できます。
    • ポーンが通常のチェスルールで最終的なY座標(白の場合は8、黒の場合は1)に移動した場合、同じ色の女王、ルーク、騎士、または司教に昇格する必要があります。この質問の目的上、プロモーションの選択は、移動が有効かどうか(および入力形式で表現できない)には関係ありませんが、プロモーションをもたらすポーンの移動は許可する必要があります。
  • 司教:司教は、連続した遮るもののない(つまり斜めの)パスに沿って1から8マスの間を移動できます。
  • 騎士:騎士Lは、次の(同等の)動きのいずれかで構成される形状で移動できます。
    • 任意の基本方向に1つの正方形があり、その後90/270°回転し、最後に2正方形前進します。
    • 任意の基本方向に2マス、続いて90/270°回転し、1マスが最終的に前進します。
    (騎士の進路は、駒を挟むことによってブロックすることはできませんが、その最終的な正方形はまだ合法でなければなりません。)
  • ルーク:ルークは、障害物のない連続したパスに沿って1〜8マスの間を移動できます。
  • クイーンズ:クイーンズは、連続する枢機orまたはinter間(つまり斜め)の遮られていないパスに沿って1から8マスの間を移動できます。
  • キング:キングはクイーンと同じように動きますが、1動きにつき1マスしか動かないという制限があります(つまり、キングはカーディナルまたは斜めに隣接するマスにしか移動できません)。リマインダーとして、あなたは自分の王を制限する動きをすることはできません。したがって、あなたも王をチェックすることはできません。

チェスのルールには、「キャスティング」と「エンパッサン」と呼ばれる特別な動きも含まれています。ただし、これらの動きの合法性は、現在の位置だけでなくゲームの履歴にも依存するため(また、キャストには2つのピースを同時に移動する必要があり、入力形式に適合しません)、これらの動きのどちらも考慮する必要はありません存在する(つまり、キャスティングまたは入場者になる動きは違法と見なされるべきです)。

移動の有効性を示すために、任意の2つの異なる結果を出力できます。また、希望する方法で入力を取得できます。必要に応じて、ポジションに1インデックスではなく0インデックスを選択することもできます。これはので、最短のコードが勝ちです!

テストケース

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)

この課題はサンドボックス化されました。説明なくダウン票を受け取ったので、とにかく投稿することにしました


「同じ側の駒が動き、王にチェックをさせます。」-この文言は、見出しを移動したため、今では収まらないようです。「この作品を動かすと王がチェックを
受ける

この質問はSandboxで採択されましたが、今はここでは説明が1つもありません。どうしてダウン投票したのかを教えてもらうために私にできることは何もありませんが、少なくとも影に黙って立っているのではなく、あなたの行動を説明する良識があります。この投稿を改善できると思われる場合は、自分自身を説明せずにポットショットを撮るのではなく、方法を提案してください。
ケアニアンコヒーリングアーイング

2
誰もそれを断っていません...?
-FlipTack

1
入力としてピースの2D配列を取得できますか?
ovs

1
@ovsはい、それは容認できるようです
ケアード・コイナーリンガー

回答:


3

Python 2python-chessを使用)、 141138134133132 バイト

本当に興味深いコードを実行しなくても-しかし、これはゴルフの言語や(あえて言及しますが)Mathematicaと競合できるでしょうか?

注:のpython-チェスがあるは、PyPIのパッケージはとの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)`)

3つの項目の入力を受け入れるフルプログラム:

  1. FENレコードの先頭-最初の2つのフィールドを含む文字列。これは、ボードの状態と移動する色を定義するためです(これはOPの入力の情報であるため、フィールド3から6はOPによって「固定」されているため、入力の一部ではありません)
  2. 移動しようとするピース名(OPで指定されている-のいずれかPRNBQK
  3. 名前の部分がどこに移動しようとされている広場a1では0b1され1、... a2され8、...、h8です63

有効な入力が与えられるとプログラムは終了コードを介して出力します。

  • 1 移動が有効なものである場合(プログラムはゼロによる除算によりエラーを発生させた)。
  • 0 そうではありません(プログラムは正常に終了しました)

(しないでくださいオンラインで試してください!(python-chessパッケージはそこにインストールされておらず、TIOはインターネット接続を許可しないため、ヘッダーのpip-installコードは機能しません)。

Pythonのべき乗演算子は作成します1**1 == 1**0 == 0**0 == 1が、0**1 == 0
... hence 1/0**1によりゼロ除算エラーが発生し1/1**1、while 、、1/1**0および1/0**0すべてが成功することに注意してください
(...とPythonでそれFalseTrueイクエートへ01それぞれ)。


2
これは完全に有効な答えですが、組み込み専用のMathematicaの答えに似た不正行為のように感じられます。
ケアニコインヘリンガー

私が一番上に置くはい、それ故にコメント「本当に面白いのコードのいずれかを実行しないと...」私はいくつかのより多くの時間があるとき多分私は(このモジュールをインポートすることはできません:))ゼリーいずれかを実行します
ジョナサン・アラン・

1
...まだ手間がかかることに注意してください。
ジョナサンアラン

に再配置str(S.piece_at(m.from_square))==p forするとp==str(S.piece_at(m.from_square))for、1バイト節約されます。
ザカリー

ああ、はい-ザカリーI @感謝はちょうど私がからパースことができるかどうかを確認するために探していたrepr置き換えるために使用したバッククォートstr...救うために
ジョナサン・アラン

3

正規表現(PCRE2)、 931の 925 837バイト

このソリューションは、1つのボード状態と移動ではなく、2つのボード状態が正規表現に渡されるという点で、問題ステートメントとは異なります。この動きは、2つの取締役会の状態の違いから推測されます。そこで、この質問で提供された形式でテストケースを取り、ボード上の記述されたピースのすべてのインスタンスを見つけ、それぞれで目的の位置に移動して正規表現を評価することをTIOプログラムの仕事にしましたその可能性がある場合、正規表現によって有効なものが報告されているかどうかを確認します。これで問題ない場合はお知らせください。位置+移動として正規表現を実装することは可能ですが、エレガントさははるかに劣り、深刻なリファクタリングが必要になります。

:ボード白色片が大文字と黒が小文字である8×8 ASCIIで表現されたP AWN、K Nの IGHT、Bの iショップ、R OOK、Qの ueen、Kを INGを。黒の側(8位)が上にあり、白の側(1位)が下にあります。各ランクは改行で区切られ、空の四角はとしてマークされ-ます。2つのボードの位置は、余分な改行で区切られています。

このプロジェクトの実際の目的は、単一の動きだけでなく、ゲーム全体を検証することです。現在の進行状況については、以下を参照してください。

()?(?>|((.|
(?=.)){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はそうではありません)サポートされているが、少なくとも)。通行人とキャスティングの完全なルールが実施されます。

完全な正規表現(PCRE1 –まだリターゲットされていない)[regex101.com]によって検証されたサンプルゲームを次に示します

無効な移動は、後続のすべてのボード位置が一致/強調表示されない結果になります。チェックメイト/膠着の検出、したがって勝者が誰であるか(またはそれが引き分けかどうか)の検出はまだ実装されていません。そのため、この例の最終的なボードの状態は強調表示されていません。

以下は、代数表記をこの正規表現で認識される形式に変換するC / C ++プログラムです。現在、代数表記法は、ソースコード内にインラインで配列の形式で配置する必要があります。各移動には個別の文字列が使用されますが、stdinまたはコマンドライン引数から単一の文字列として読み取り、移動のシーケンス全体がスペースで区切られますドットで終わる移動番号が計画されています。

また、完全なゲームを純粋に代数チェス表記で検証する正規表現を開始しました。標準の初期位置が暗示されています。必要なのは、入力の最後(ムーブのリストの後)に追加される空の「スクラッチボード」です。これを完全に実装することは可能だと確信しており、いつか完成させる予定です。


数独検証の質問のために3000バイトの正規表現の怪物を吐き出して以来、それほど多くの恐怖に満たされていません(勝利の答えが75未満であると考えると、大きな間違いです)。本当にあなたが問題を解決するために正規表現を使用するときに時々 、あなたは二つの問題で終わるポイントが証明
バリューインク

@ValueInkへえ、多分あなたは正しいかもしれませんが、私はその完全な非実用性に関係なく(あるいはそのために)それを楽しんでいます。あなたのコメントは、その数独の質問に答えようとするきっかけになりましたが、200バイトしか管理できませんでした。しかたがない。
デッドコード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.