Bir FEN pozisyonunun yasal olduğunu nasıl bilebilirim?


19

Bir noktada FEN pozisyonunu doğrulamam gereken kişisel bir proje yapıyorum, kral olup olmadığını kontrol etmek ve ekstra satır veya sütun olmadığından emin olmak gibi bazı temel kontrollerle başladım ve bu tür bir şeyler.

Fakat bir FEN'in yasal olduğundan emin olmak için başka hangi kontrolleri yapmalıyım?

Yanıtlar:


18

İşte ortak konumların% 99,99'unu + doğrulaması gereken iyi organize edilmiş bir liste:

Yazı tahtası:

  • Tam olarak 8 kömür var
  • Boş karelerin ve parçaların toplamı her bir sıralama için 8'e eklenir
  • Boş kareler için arka arkaya numara yok

Kings:

  • Tam olarak bir w_king ve bir b_king olup olmadığına bakın
  • Kralların birbirinden 1 kare ayrıldığından emin olun

Çekler:

  • Aktif olmayan renk kontrol edilmiyor
  • Aktif renk 3 kereden daha az kontrol edilir (üçlü kontrol mümkün değildir); 2 durumunda asla piyon + (piyon, piskopos, şövalye), piskopos + fil, şövalye + şövalye değildir

Piyonlar:

  • Her renkten en fazla 8 piyon yoktur
  • İlk veya son rütbede (sıra) yanlış başlangıç ​​pozisyonunda oldukları veya terfi ettirmeleri gereken piyonlar yoktur.
  • Geçiş karesi olması durumunda; yasal olarak yaratılıp yaratılmadığına bakın (örneğin, x3ya da x6rütbede olmalı, önünde bir piyon (doğru renkten) olmalı ve en geçen kare ve arkasındaki boş)
  • Eksik piyonlardan (örneğin extra_pieces = Math.max(0, num_queens-1) + Math.max(0, num_rooks-2)...ve sonra extra_pieces <= (8-num_pawns)) daha fazla terfi ettirilmiş parçaların olmasını önleyin , ayrıca piskoposlar için özel hesaplamalar yapmalısınız, Aynı kare renkten iki (veya daha fazla) piskoposunuz varsa, bunlar sadece piyon promosyonu ile oluşturulabilir ve bu bilgiyi bir şekilde yukarıdaki formüle
  • Piyon oluşumuna ulaşmak mümkündür (örneğin, tek bir kolda birden fazla piyon olması durumunda, bu formasyonu yapmak için eksik düşman parçası olmalıdır), işte bazı yararlı kurallar:
    1. tek bir dosyada (sütun) 6'dan fazla piyon olması imkansızdır (çünkü piyonlar ilk ve son rütbelerde mevcut olamaz)
    2. tek bir kolda birden fazla piyona ulaşmak için minimum eksik düşman parçası sayısı, 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örneğin A veya H'de 5 piyon görüyorsanız, diğer oyuncu 15 adet es geçilebilir parçasından en az 10 adet eksik olmalıdır
    3. a2 ve a3'te beyaz piyonlar varsa, b2'de yasal olarak bir piyon olamaz ve bu fikir daha fazla olasılığı kapsayacak şekilde genişletilebilir.

rok:

  • Kral veya kaleler başlangıç ​​pozisyonlarında değilse; o tarafın rıhtım yeteneği kaybolur (kral durumunda, her ikisi de kaybolur)

piskoposlar:

  • Hareket etmeyen piyonlar tarafından hapsolmuş ilk ve son rütbelerde (sıralar) piskoposları arayın, örneğin:
    1. 3 piyonun arkasında kalan bir fil (herhangi bir renk)
    2. 2 düşman piyonunun arkasına sıkışmış bir piskopos (piyonların altını çizerek bu pozisyona ulaşabileceğimiz için düşman piyonları tarafından değil, ancak piyon sayısını kontrol edersek ve bu durumun mümkün olup olmadığını belirleyebilirsek)extra_pieces

Sigara jumper:

  • (Balıkçının satrancını doğrulamak istiyorsanız bundan kaçının960) Kral ve kale arasında jumper olmayan düşman parçaları varsa ve hareket etmeden hala bazı piyonlar varsa; bu düşman parçalarının yasal olarak oraya girip girmediğini kontrol edin. Ayrıca, kendinize sorun: Kralın veya kalenin bu pozisyonu oluşturmak için hareket etmesi gerekiyordu? (evet ise, döküm yeteneklerinin bunu yansıttığından emin olmamız gerekir)
  • Eğer 8 piyonun hepsi hala başlangıç ​​pozisyonundaysa, tüm jumper olmayanlar ilk rütbelerini terk etmemelidir (ayrıca jumper olmayan düşman parçaları yasal olarak giremez), beyaz h gibi - piyon bir kez hareket ettiğinde, kaleler piyon formasyonunun içinde hapsolmalıdır.

Yarım / Tam hareketli Saatler:

  • Enine kare durumunda, yarım hareket saati 0'a eşit olmalıdır
  • HalfMoves <= ((FullMoves-1)*2)+(if BlackToMove 1 else 0), +1 veya +0 taşınacak tarafa bağlıdır
  • HalfMoves olmalı x >= 0ve FullMovesx >= 1

Diğer:

  • FEN'in gereken tüm parçaları içerdiğinden emin olun (örn. Aktif renk, döküm yeteneği, enine kare vb.)

Not: yapmak gerek yoktur 'oyuncuları 16'dan fazla parça var olmamalıdır' noktaları nedeniyle çek 'en fazla 8 piyon' + 'ekstra terfi parçaları önlemek' + 'tam olarak bir kral' zaten bu noktayı kapsamalıdır

Not 2: Bu kurallar, normal satranç başlangıç pozisyonundan kaynaklanan validate pozisyonları amaçlanmıştır, bazı kuralları bazı pozisyonları geçersiz kılar Chess960 (aranjman Nº518 başlatıldı eğer istisna) ve oluşturulan bulmaca böylece işlevsel bir doğrulayıcı almak için onlardan uzak dur.


1
Piyon yapısını da kontrol edebilirsiniz, örneğin beyaz piyonlar asla a2, a3 ve b2'de olamazdı; piyonun hem a3 hem de b2'de bulunmasının bir yolu yoktur.
Akavall

Demek ki FEN pozisyonlarına sadece başlangıç ​​pozisyonundan ulaşılabilir mi? Bir FEN tarafından temsil edilen bulmaca pozisyonları olmasını istersem ne olur? Bazen gerçek bir oyunda ulaşılması imkansız bir şekilde yaratılır ...
tbischel

@tbischel Bu kuralları normal satranç perspektifinden yapıyorum (Chess960 veya diğer üretilen pozisyonlar için tasarlanmamıştır), teşekkürler bunu daha net hale getirmek için bir yere işaret edebilirim
ajax333221

Normal satranç için bile, tüm bu kontrolleri yapmak istemeyebilirsiniz. Sonuç olarak FEN olarak yasa dışı bir konumu temsil edemeyen bir program elde edersiniz. Ancak pratikte olurlar - yasadışı hamleler bazen sadece oyundan sonra fark edilir. Bu tür oyunlardan diyagramlar göstermek mümkün değil mi?
RemcoGerlich

1
@ ajax333221: Bu sayfa beyaz üzerine 5'ten fazla piyon aldığı yasal oyunlar verir adosyaya.

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

İşte bir FEN dizesinin gerçekten geçerli olduğundan emin olmak için kullandığım normal bir ifade. Yasal / yasadışı bir pozisyon için herhangi bir test yapmaz, ancak iyi bir başlangıç ​​noktasıdır.


Aktif renk bir zorunluluktur (izin veriyorsunuz -) ve yarım / tam saatler bazen isteğe bağlı olduğunu düşünüyorum. Ayrıca a-h, /^\s*([rnbqkpRNBQKP1-8]+\/){7}([rnbqkpRNBQKP1-8]+)\s[bw]\s(-|K?Q?k?q?)\s(-|[a-h][36])/
döküm

Ben sadece "promosyon saflarında hiçbir piyon" testi gibi bir şey ile ([rnbqkRNBQK1-8]+\/)([rnbqkpRNBQKP1-8]+\/){6}([rnbqkRNBQK1-8]+) ....
başlayabilirsiniz

Ayrıca saatler için bu iyi olabilir (0|[1-9][0-9]*)\s([1-9][0-9]*)çünkü hamleler önde gelen sıfırlara sahip olamaz ve tam hamle olamaz veya 0 ile başlayamaz (kod kredisi)
ajax333221

5

Diğerleri için, Stockish motorunda FEN Dizesini doğrulayan basit bir işlev vardır.

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
Tüm gerçek doğrulama yapıldı gibi görünüyor position.is_okay(). Buradaki kod, doğru biçimlendirildiğinden ve gerçek doğrulamayı yapmaya değer olduğundan emin olmak için birkaç temel kontrol yapar (yani açıkça yasadışı değildir ).
undergroundmonorail

4

Her tahta durumunda (konum olarak da bilinir) ters yasal hareketleri kontrol edebilen bir işleve sahip olmanız şartıyla basit bir geri izleme algoritması:

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 spesifikasyonunda, temsil edilen pozisyonun ilk diziden erişilebilir olması gerektiğini söyleyen hiçbir şey yoktur. Belirli bir konuma ilk diziden erişilebildiğini kanıtlamak çözülmemiş bir sorundur.

Geçerli bir FEN dizgisinde, yarı hareket sayımı en fazla hedef kare ile uyumlu olmalıdır; bir hedef kare varsa, yarım hareket sayısı sıfır olmalıdır. yarım hamle sayısı da tam hamle numarası ile uyumlu olmalıdır; örneğin, on hamle sayısı üç tam hamle sayısı ile uyumsuzdur.


1

Partiye geç geliyor.

Bir pozisyonun yasal olup olmadığını% 100 doğrulamak mümkün değildir, ancak doğrulama neden önemlidir? Başlangıç ​​pozisyonundan türetilmiş olsun ya da olmasın satranç oynayabiliriz (“oyun dizisi” olarak adlandırılır). Analiz etmek için çok ilginç bir pozisyon olabilir ama sadece yasadışı olduğu anlaşılıyor.

Bu yüzden sadece kontrol ediyorum:

  • Her iki tarafta tam olarak 1 kral var mı?
  • Birinci veya sekizinci sırada hiç piyon yok mu?
  • Hareket edecek taraf çek vermiyor mu?

Eğer bu üç EVET ise, bu diyagramdan ileriye doğru satranç oynayabiliriz. Ve bu kısa koşullar listesi bile gevşeyebiliriz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.