FENポジションが合法かどうかを知る方法は?


19

私は個人的なプロジェクトを行っており、ある時点でFENの位置を検証する必要があります。私はいくつかの基本的なチェックから始めました。もの。

しかし、FENが合法であることを完全に確認するには、他にどのようなチェックを行う必要がありますか?

回答:


18

一般的なポジションの99.99%以上を検証する必要がある、よく整理されたリストを次に示します。

ボード:

  • ちょうど8つの列があります
  • 空の正方形とピースの合計は、ランク(行)ごとに8になります
  • 空の四角には連続した数字はありません

キングス:

  • 正確に1つのw_kingと1つのb_kingがあるかどうかを確認します
  • キングが1マス離れていることを確認してください

チェック:

  • 非アクティブな色はチェックされていません
  • アクティブな色のチェックは3回未満です(トリプルチェックは不可能です)。2の場合、ポーン+(ポーン、ビショップ、ナイト)、ビショップ+ビショップ、ナイト+ナイトではない

ポーン:

  • 各色のポーンは8個以下です
  • ポーンは最初または最後のランク(行)にありません。それらは間違った開始位置にあるか、昇格する必要があるためです。
  • エンパッサン広場の場合; (例えば、それは上にある必要があり、それが合法的に作成されたかどうx3か、x6その前に正しい色からのポーン()、専用アンパッサン広場、それが空になっているの背後にある1がなければならない、ランク)
  • Preventが(例えば行方不明ポーンよりも昇進の作品を持っextra_pieces = Math.max(0, num_queens-1) + Math.max(0, num_rooks-2)...た後、extra_pieces <= (8-num_pawns)あなたが同じ正方形の色から2つ(またはそれ以上)の司教を持っている場合、これらは唯一のポーンの昇格を介して作成することができ、あなたが含まれている必要があり、また、あなたが司教のための特別な計算を行う必要があります)この情報を上記の式に何らかの形で
  • ポーンフォーメーションに到達することは可能です(たとえば、1つの列に複数のポーンが存在する場合、そのフォーメーションを行うために十分な敵の駒が欠落している必要があります)。
    1. 1つのファイル(列)に6つ以上のポーンを含めることは不可能です(ポーンは最初と最後のランクに存在できないため)
    2. 単一COLで複数の質屋に到達するために作品を行方不明の敵の最小数はB to G 2=1, 3=2, 4=4, 5=6, 6=9 ___ A and H 2=1, 3=3, 4=6, 5=10, 6=15、あなたがAまたはHで5個の駒を見た場合、例えば、他のプレイヤーは15から少なくとも10枚の欠落しなければならないで捕捉
    3. a2とa3に白いポーンが存在する場合、b2に合法的に存在することはできません。このアイデアをさらに拡張して、より多くの可能性をカバーすることができます

キャスリング:

  • キングまたはルークが開始位置にない場合; その側のキャスティング能力は失われます(キングの場合、両方とも失われます)

司教:

  • 移動していないポーンによってトラップされた最初と最後のランク(行)の司教を探します。例えば:
    1. 3つのポーンの後ろに閉じ込められた司教(任意の色)
    2. 捕獲された司教の後ろに 2 非敵のポーン(敵のポーンによって、我々は駒の数をチェックして、しかし場合は、ポーンをunderpromotingことで、その位置に到達することができないので、extra_piecesこの場合には可能であるかどうか、我々が決定することができます)

非ジャンパー:

  • (Fisher's Chess960を検証したい場合はこれを避けてください)キングとルークの間にジャンパーではない敵の駒があり、移動せずにポーンがまだある場合; これらの敵の駒が合法的にそこに侵入できたかどうかを確認してください。また、自問してください:その位置を生成するために移動する必要があった王またはルークですか?(はいの場合、キャスティング能力がこれを反映していることを確認する必要があります)
  • 8個のポーンすべてがまだ開始位置にある場合、すべての非ジャンパーは初期ランクを離れてはなりません(また、非ジャンパーの敵の駒は合法的に入ることはできません)、他の同様のアイデアがあります。 -ポーンは一度移動しましたが、ルークはポーンフォーメーションなどに閉じ込められたままです。

ハーフ/フルムーブ時計:

  • エンパッサントスクエアの場合、ハーフムーブクロック 0に等しくなければなりません
  • HalfMoves <= ((FullMoves-1)*2)+(if BlackToMove 1 else 0)、+ 1または+0は移動する側に依存します
  • HalfMovesでなければならないx >= 0とFullMovesx >= 1

その他:

  • FENに必要なすべてのパーツが含まれていることを確認してください(アクティブカラー、キャスティング機能、パッサンスクエアなど)。

注:作成する必要はありません「の選手が16点の以上の作品持つべきではない」ポイントので、チェックを「せいぜい8つのポーンは」 + 「余分な推進の作品を防ぐには」 + "正確に一つの王、すでにこの点をカバーする必要がありますが

注2:これらのルールは、通常のチェスの開始位置から生じる位置を検証することを目的としています。一部のルールは、Chess960(配置Nº518から開始した場合を除く)の一部の位置を無効にし、パズルを生成します。


1
また、ポーン構造を確認することもできます。たとえば、白いポーンがa2、a3、およびb2に存在することはありません。ポーンがa3とb2の両方に存在する方法はありません。
アカヴァル

それは、FENのポジションは最初のポジションからしか達成できないということですか?パズルの位置をFENで表したい場合はどうなりますか?時々、実際のゲームでは到達できない方法で作成されます
...-tbischel

@tbischel私はからこれらのルールを作り、通常の(チェス960または他の生成位置を意図していない)チェスの視点、おかげで私はそれを明確にするために、このどこかを指している可能性があります
ajax333221

通常のチェスでも、これらのチェックのすべてを実行したくない場合があります。FENとして違法な地位を表すことができないプログラムになります。しかし、それらは実際に起こります-違法な動きは、ゲームの後にしか気付かない場合があります。そのようなゲームの図などを表示することは不可能でしょうか?
-RemcoGerlich

1
@ ajax333221:このページでは白が上の5つの以上のポーンを取得する法的なゲーム与えaたファイルを。

9
\s*([rnbqkpRNBQKP1-8]+\/){7}([rnbqkpRNBQKP1-8]+)\s[bw-]\s(([a-hkqA-HKQ]{1,4})|(-))\s(([a-h][36])|(-))\s\d+\s\d+\s*

FEN文字列が実際に有効であることを確認するために使用する正規表現を次に示します。法的/違法なポジションのテストは行いませんが、良い出発点です。


私はアクティブな色が必須であり(あなたが許可している-)、ハーフ/フルクロックが時々オプションだと思うと思います。また、私はa-hキャスティング能力に関する部分を理解していなかったので、書き直した/^\s*([rnbqkpRNBQKP1-8]+\/){7}([rnbqkpRNBQKP1-8]+)\s[bw]\s(-|K?Q?k?q?)\s(-|[a-h][36])/
ajax333221

「プロモーションランクにポーンなし」テストを次のように開始できることに注意しました([rnbqkRNBQK1-8]+\/)([rnbqkpRNBQKP1-8]+\/){6}([rnbqkRNBQK1-8]+) ....
-ajax333221

また、クロックの場合、これは(0|[1-9][0-9]*)\s([1-9][0-9]*)、動きに先行ゼロがなく、完全な動きが0にならない、または0から開始できないため、良いかもしれません(コードクレジット)
ajax333221

4

その他については、FEN文字列を検証するStockfishエンジンの単純な関数があります。

bool Position::is_valid_fen(const std::string &fen) {
   std::istringstream iss(fen);
   std::string board, side, castleRights, ep;

   if (!iss) return false;

   iss >> board;

   if (!iss) return false;

   iss >> side;

   if (!iss) {
      castleRights = "-";
      ep = "-";
   } else {
      iss >> castleRights;
      if (iss)
         iss >> ep;
      else
         ep = "-";
   }

   // Let's check that all components of the supposed FEN are OK.
   if (side != "w" && side != "b") return false;
   if (castleRights != "-" && castleRights != "K" && castleRights != "Kk"
       && castleRights != "Kkq" && castleRights != "Kq" && castleRights !="KQ"
       && castleRights != "KQk" && castleRights != "KQq" && castleRights != "KQkq"
       && castleRights != "k" && castleRights != "q" && castleRights != "kq"
       && castleRights != "Q" && castleRights != "Qk" && castleRights != "Qq"
       && castleRights != "Qkq")
      return false;
   if (ep != "-") {
      if (ep.length() != 2) return false;
      if (!(ep[0] >= 'a' && ep[0] <= 'h')) return false;
      if (!((side == "w" && ep[1] == '6') || (side == "b" && ep[1] == '3')))
         return false;
   }

   // The tricky part: The board.
   // Seven slashes?
   if (std::count(board.begin(), board.end(), '/') != 7) return false;
   // Only legal characters?
   for (int i = 0; i < board.length(); i++)
      if (!(board[i] == '/' || (board[i] >= '1' && board[i] <= '8')
            || piece_type_is_ok(piece_type_from_char(board[i]))))
         return false;
   // Exactly one king per side?
   if (std::count(board.begin(), board.end(), 'K') != 1) return false;
   if (std::count(board.begin(), board.end(), 'k') != 1) return false;
   // Other piece counts reasonable?
   size_t wp = std::count(board.begin(), board.end(), 'P'),
      bp = std::count(board.begin(), board.end(), 'p'),
      wn = std::count(board.begin(), board.end(), 'N'),
      bn = std::count(board.begin(), board.end(), 'n'),
      wb = std::count(board.begin(), board.end(), 'B'),
      bb = std::count(board.begin(), board.end(), 'b'),
      wr = std::count(board.begin(), board.end(), 'R'),
      br = std::count(board.begin(), board.end(), 'r'),
      wq = std::count(board.begin(), board.end(), 'Q'),
      bq = std::count(board.begin(), board.end(), 'q');
   if (wp > 8 || bp > 8 || wn > 10 || bn > 10 || wb > 10 || bb > 10
       || wr > 10 || br > 10 || wq > 9 || bq > 10
       || wp + wn + wb + wr + wq > 15 || bp + bn + bb + br + bq > 15)
      return false;

   // OK, looks close enough to a legal position. Let's try to parse
   // the FEN and see!
   Position p;
   p.from_fen(board + " " + side + " " + castleRights + " " + ep);
   return p.is_ok(true);
}

1
実際の検証はすべてで行われているようposition.is_okay()です。ここのコードは、いくつかの基本的なチェックを行って、正しくフォーマットされていることと、実際の検証を行う価値があること(つまり、明らかに違法ではないこと)を確認しています。
地下

3

すべてのボードの状態(位置とも呼ばれる)でリバースリーガルムーブをチェックできる機能がある場合、簡単なバックトラッキングアルゴリズムがあります:

function is_legal_state(state,move)

   //Terminate if a starting state was found. This immediately implies there
   //was a legal game that generated this state, in fact the backtracking
   //can tell you precisely such a game       
   if (state in starting board state)
     return true

   //Apply some move to get to a new state, state is a persistent object
   apply_reverse_move(state,move)

   //Generate all legal "reverse" moves, that is, moves that could have
   //been performed to get to the current state from another position,
   //provided the previous position was valid. You do not have to check the
   //validness of the previous state, you just have to make sure the
   //transitioning move was valid
   legalmoves = enumerate_all_reverse_moves( state )

   for local_move in legalmoves:
     return is_legal_state(state,local_move)

   //Reverse the move that was previously applied so backtracking can
   //work properly 
   reverse_reverse_move(state,move)

   return false

1

FEN仕様には、表現された位置が初期配列から到達可能でなければならないということはありません。与えられた位置が初期配列から到達可能であることを証明することは未解決の問題です。

有効なFEN文字列では、半分の移動回数は通行人のターゲットスクエアと一致する必要があります。ターゲットの正方形が存在する場合、半移動カウントはゼロでなければなりません。半分の移動回数も完全な移動回数と一致している必要があります。たとえば、10の半分の移動数は3の完全な移動数と互換性がありません。


1

パーティーに遅れて来る。

ポジションが合法かどうかを完全に検証することはできませんが、なぜ検証が重要なのでしょうか?位置がたまたま開始位置(いわゆる「ゲームアレイ」)から派生したかどうかに関係なく、チェスをプレイできます。分析する非常に興味深い立場があるかもしれませんが、それはたまたま違法であることが起こります。

だから私はちょうどチェックします:

  • 両側にそれぞれ1人の王がいますか?
  • 1位または8位にポーンはありませんか?
  • 移動する側は、すでにチェックを行っていませんか?

それが3つのYESなら、この図からフォワードチェスをプレイできます。そして、この短い条件リストでさえ、緩めることができるかもしれません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.