Làm thế nào để biết khi nào một vị trí FEN là hợp pháp?


19

Tôi đang thực hiện một dự án cá nhân, tại một thời điểm tôi cần xác thực vị trí FEN, tôi bắt đầu với một số kiểm tra cơ bản, chẳng hạn như kiểm tra nếu có các vị vua và đảm bảo không có bất kỳ hàng hoặc cột bổ sung nào, và loại đó nhiều thứ.

Nhưng những kiểm tra nào khác tôi nên làm để hoàn toàn chắc chắn rằng một FEN là hợp pháp?

Câu trả lời:


18

Dưới đây là danh sách được tổ chức tốt sẽ xác nhận 99,99% + vị trí phổ biến:

Bảng:

  • Có chính xác 8 cols
  • Tổng các ô vuông và mảnh trống thêm vào 8 cho mỗi cấp bậc (hàng)
  • Không có số liên tiếp cho các ô vuông trống

Các vị vua:

  • Xem nếu có chính xác một w_king và một b_king
  • Hãy chắc chắn rằng các vị vua được cách nhau 1 ô vuông

Séc:

  • Màu không hoạt động không được kiểm tra
  • Màu hoạt động được kiểm tra ít hơn 3 lần (không thể kiểm tra ba lần); trong trường hợp 2 mà không bao giờ là cầm đồ + (cầm đồ, giám mục, hiệp sĩ), giám mục + giám mục, hiệp sĩ + hiệp sĩ

Chân:

  • Không có hơn 8 con tốt từ mỗi màu
  • Không có bất kỳ con tốt nào trong thứ hạng đầu tiên hoặc cuối cùng (hàng) vì chúng ở vị trí bắt đầu sai hoặc chúng nên được thăng chức.
  • Trong trường hợp en thụ động vuông; xem nếu nó được tạo ra một cách hợp pháp (ví dụ: nó phải ở trên x3hoặc x6xếp hạng, phải có một con tốt (từ màu chính xác) ở phía trước của nó, và hình vuông en passant và cái phía sau nó trống rỗng)
  • Ngăn chặn việc có nhiều phần được quảng bá hơn những con tốt bị mất tích (ví dụ extra_pieces = Math.max(0, num_queens-1) + Math.max(0, num_rooks-2)...và sau đó extra_pieces <= (8-num_pawns)), bạn cũng nên thực hiện các phép tính đặc biệt cho các giám mục, Nếu bạn có hai (hoặc nhiều) giám mục từ cùng một hình vuông, chúng chỉ có thể được tạo thông qua quảng cáo cầm đồ và bạn nên bao gồm thông tin này cho công thức trên bằng cách nào đó
  • Đội hình cầm đồ có thể đạt được (ví dụ trong trường hợp có nhiều con tốt trong một col, phải có đủ quân địch để tạo thành đội hình đó), đây là một số quy tắc hữu ích:
    1. không thể có nhiều hơn 6 con tốt trong một tệp (cột) (vì các con tốt không thể tồn tại trong hàng đầu tiên và cuối cùng)
    2. số lượng quân cờ bị mất tối thiểu để đạt được nhiều con tốt trong một 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, chẳng hạn, nếu bạn thấy 5 con tốt trong A hoặc H, người chơi khác phải bị thiếu ít nhất 10 mảnh trong số 15 quân cờ bị bắt của mình
    3. nếu có những con tốt trắng trong a2 và a3, thì không thể có một con hợp pháp trong b2 và ý tưởng này có thể được mở rộng hơn nữa để bao quát nhiều khả năng hơn

Castling:

  • Nếu nhà vua hoặc tân binh không ở vị trí bắt đầu của họ; khả năng ném đá cho bên đó bị mất (trong trường hợp của vua, cả hai đều bị mất)

Giám mục:

  • Tìm kiếm các giám mục trong hàng ngũ đầu tiên và cuối cùng (hàng) bị mắc kẹt bởi những con tốt không di chuyển, ví dụ:
    1. một giám mục (bất kỳ màu nào) bị mắc kẹt đằng sau 3 con tốt
    2. một giám mục bị mắc kẹt đằng sau 2 con tốt không phải kẻ thù (không phải là con tốt của kẻ thù bởi vì chúng ta có thể đạt được vị trí đó bằng cách đánh giá thấp những con tốt, tuy nhiên nếu chúng ta kiểm tra số lượng con tốt và extra_pieceschúng ta có thể xác định xem trường hợp này có khả thi hay không)

Người không nhảy:

  • (Tránh điều này nếu bạn muốn xác nhận Chess960 của Fisher) Nếu có quân địch không nhảy vào giữa vua và rook và vẫn còn một số con tốt mà không di chuyển; kiểm tra xem những quân địch có thể xâm nhập hợp pháp vào đó không. Ngoài ra, hãy tự hỏi: vua hoặc tân binh cần phải di chuyển để tạo ra vị trí đó? (nếu có, chúng ta cần đảm bảo rằng các khả năng của castling phản ánh điều này)
  • Nếu tất cả 8 con tốt vẫn ở vị trí bắt đầu, tất cả những người không nhảy không được rời khỏi cấp bậc ban đầu của họ (cũng không phải là quân địch không nhảy được, có thể có những ý tưởng tương tự khác, như nếu h trắng -pawn di chuyển một lần, các tân binh vẫn nên bị mắc kẹt trong đội hình cầm đồ, v.v.

Đồng hồ di chuyển một nửa / đầy đủ:

  • Trong trường hợp hình vuông en passant, đồng hồ di chuyển một nửa phải bằng 0
  • HalfMoves <= ((FullMoves-1)*2)+(if BlackToMove 1 else 0), +1 hoặc +0 tùy thuộc vào bên di chuyển
  • HalfMoves phải là x >= 0và FullMovesx >= 1

Khác:

  • Đảm bảo FEN chứa tất cả các phần cần thiết (ví dụ: màu hoạt động, khả năng đúc, hình vuông thụ động, v.v.)

Lưu ý: không cần thiết phải kiểm tra 'người chơi không nên có nhiều hơn 16 quân bài' vì các điểm 'không quá 8 pawns' + 'ngăn chặn các phần được quảng bá thêm' + 'chính xác là một vị vua' đã bao gồm điểm này

Lưu ý2: các quy tắc này nhằm xác thực các vị trí phát sinh từ vị trí bắt đầu của cờ vua thông thường, một số quy tắc sẽ làm mất hiệu lực một số vị trí từ Chess960 (ngoại trừ nếu bắt đầu từ sắp xếp Nº518) và tạo các câu đố để tránh chúng có được trình xác nhận chức năng.


1
Bạn cũng có thể kiểm tra cấu trúc cầm đồ, ví dụ những con tốt trắng không bao giờ có thể ở trên a2, a3 và b2; không có cách nào một con tốt có thể trên cả a3 và b2.
Akavall

Có phải để nói rằng các vị trí FEN chỉ nên đạt được từ vị trí ban đầu? Điều gì xảy ra nếu tôi muốn có các vị trí câu đố được đại diện bởi một FEN? Đôi khi chúng được tạo ra theo cách không thể tiếp cận trong một trò chơi thực tế ...
tbischel

@tbischel Tôi thực hiện các quy tắc này từ phối cảnh cờ thông thường (không dành cho Chess960 hoặc các vị trí được tạo khác), cảm ơn tôi có thể chỉ ra điều này ở đâu đó để làm cho nó rõ ràng hơn
ajax333221

Ngay cả đối với cờ vua bình thường, bạn có thể không muốn thực hiện tất cả các kiểm tra này. Bạn kết thúc với một chương trình không thể đại diện cho một vị trí bất hợp pháp là FEN. Nhưng chúng thực sự xảy ra trong thực tế - di chuyển bất hợp pháp đôi khi chỉ được chú ý sau trận đấu. Không thể hiển thị sơ đồ từ các trò chơi như vậy, v.v.
RemcoGerlich

1
@ ajax333221: Trang này cung cấp cho trò chơi hợp pháp, trong đó màu trắng được hơn 5 con cờ trên atập tin.

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

Đây là một biểu thức chính quy mà tôi sử dụng để đảm bảo rằng chuỗi FEN thực sự hợp lệ. Nó không thực hiện bất kỳ thử nghiệm nào cho vị trí hợp pháp / bất hợp pháp, nhưng đó là điểm khởi đầu tốt.


Tôi nghĩ rằng màu hoạt động là bắt buộc (bạn đang cho phép -) và đồng hồ một nửa / đầy đủ đôi khi tôi nghĩ là tùy chọn. Ngoài ra tôi không hiểu a-hphần nào về khả năng đúc, tôi đã viết lại nó cho/^\s*([rnbqkpRNBQKP1-8]+\/){7}([rnbqkpRNBQKP1-8]+)\s[bw]\s(-|K?Q?k?q?)\s(-|[a-h][36])/
ajax333221

Tôi chỉ lưu ý rằng chúng tôi có thể thực hiện bài kiểm tra "không có con tốt trong hàng ngũ thăng hạng" với thứ gì đó bắt đầu như([rnbqkRNBQK1-8]+\/)([rnbqkpRNBQKP1-8]+\/){6}([rnbqkRNBQK1-8]+) ....
ajax333221

Ngoài ra, đối với đồng hồ, điều này có thể tốt (0|[1-9][0-9]*)\s([1-9][0-9]*)vì di chuyển không có số 0 đứng đầu và di chuyển hoàn toàn không thể hoặc bắt đầu bằng 0, (mã tín dụng)
ajax333221

4

Đối với những người khác, có một chức năng đơn giản trong công cụ Stockfish, xác nhận chuỗi FEN.

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
Có vẻ như tất cả các xác nhận thực tế được thực hiện trong position.is_okay(). Mã ở đây chỉ thực hiện một vài kiểm tra cơ bản để đảm bảo rằng nó được định dạng chính xác và nó đáng để thực hiện xác nhận thực (nghĩa là không rõ ràng là bất hợp pháp).
undergroundmonorail

3

Đây là một thuật toán quay lui đơn giản, với điều kiện bạn có một chức năng có thể kiểm tra các động thái pháp lý đảo ngược ở mọi trạng thái bảng (còn được gọi là vị trí):

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

Không có gì trong đặc tả FEN nói rằng vị trí được đại diện phải có thể truy cập được từ mảng ban đầu. Chứng minh rằng một vị trí nhất định có thể truy cập từ mảng ban đầu là một vấn đề chưa được giải quyết.

Trong chuỗi FEN hợp lệ, số lần di chuyển một nửa phải phù hợp với ô vuông mục tiêu thụ động; nếu một hình vuông mục tiêu có mặt, thì số lần di chuyển phải bằng không. số lần di chuyển một nửa cũng phải phù hợp với số lần di chuyển đầy đủ; ví dụ: một nửa số lần di chuyển là mười không tương thích với số lần di chuyển đầy đủ là ba.


1

Đến dự tiệc muộn.

Không thể xác thực 100% liệu một vị trí có hợp pháp hay không, nhưng tại sao việc xác thực lại quan trọng? Chúng ta có thể chơi cờ cho dù vị trí đó có xuất phát từ vị trí bắt đầu hay không (được gọi là mảng trò chơi mảng). Có thể có một vị trí rất thú vị để phân tích nhưng nó chỉ xảy ra rằng đó là bất hợp pháp.

Vì vậy, tôi sẽ kiểm tra chỉ:

  • Có chính xác 1 vua từ mỗi bên?
  • Không có con tốt trên thứ hạng đầu tiên hoặc thứ tám?
  • Là bên để di chuyển không đưa ra kiểm tra?

Nếu đó là ba CÓ thì chúng ta có thể chơi cờ chuyển tiếp từ sơ đồ này. Và thậm chí danh sách ngắn các điều kiện này chúng ta có thể có thể nới lỏng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.