Як дізнатися, коли позиція FEN є законною?


19

Я роблю особистий проект, коли в один момент мені потрібно перевірити позицію FEN, я почав з деяких основних перевірок, таких як перевірка наявності королів і переконайтеся, що немає зайвих рядків чи стовпців, і подібного роду речі.

Але які ще перевірки потрібно зробити, щоб повністю переконатися, що FEN є законним?

Відповіді:


18

Ось добре організований список, який повинен підтвердити 99,99% + загальних позицій:

Рада:

  • Там рівно 8 кол
  • Сума порожніх квадратів і шматочків додається до 8 для кожного рангу (ряду)
  • Немає послідовних чисел для порожніх квадратів

Королі:

  • Подивіться, чи є рівно один w_king та один b_king
  • Переконайтеся, що королі відокремлені 1 квадрат один від одного

Перевірки:

  • Неактивний колір не перевіряється
  • Активний колір перевіряється менше 3 разів (потрійна перевірка неможлива); у випадку 2, що це ніколи пішак + (пішак, єпископ, лицар), єпископ + єпископ, лицар + лицар

Пішаки:

  • З кожного кольору не більше 8 пішаків
  • Немає пішаків першого чи останнього рангу (ряду), оскільки вони перебувають у неправильному стартовому положенні, або вони повинні були просуватися.
  • У випадку прохідної площі; подивіться, чи був він створений на законних підставах (наприклад, він повинен бути на x3чи x6ранговому рівні, перед ним повинен бути пішак (з правильного кольору), а прохідний квадрат і той, що знаходиться за ним, порожні)
  • Не дозволяйте мати більше рекламних фігур, ніж відсутні пішаки (наприклад, extra_pieces = Math.max(0, num_queens-1) + Math.max(0, num_rooks-2)...і тоді extra_pieces <= (8-num_pawns)), також вам слід зробити спеціальні розрахунки для єпископів. Якщо у вас є два (або більше) єпископів одного квадратного кольору, їх можна створити лише за допомогою просування пішаків, і вам слід включити ця інформація до формули вище якось
  • Формування пішаків можна досягти (наприклад, у випадку кількох пішаків в одному колі, для її формування має бути достатньо кількості ворожих фігур), ось кілька корисних правил:
    1. не можна мати більше 6 пішаків в одному файлі (стовпці) (оскільки пішаки не можуть існувати в першому та останньому рядах)
    2. мінімальна кількість ворожих відсутніх фігур, щоб досягти декількох пішаків в одному колі 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, наприклад, якщо ви бачите 5 пішаків A або H, інший гравець повинен бракувати не менше 10 штук з його 15 захоплюючих штук
    3. якщо в а2 та а3 є білі пішаки, юридично їх не може бути в b2, і цю ідею можна додатково розширити, щоб охопити більше можливостей

Закладки:

  • Якщо король чи граки не перебувають у вихідному положенні; здатність закидання для цієї сторони втрачається (у випадку короля обоє втрачаються)

Єпископи:

  • Шукайте єпископів у першому та останньому рядах (рядах), захоплених пішаками, які не рухалися, наприклад:
    1. єпископ (будь-якого кольору), захоплений за 3 пішаки
    2. єпископ в пастку за 2 без ворожих пішаків (НЕ ворожих пішаків , тому що ми можемо досягти цієї позиції шляхом underpromoting пішаки, однак , якщо ми перевіряємо кількість пішаків і extra_piecesми могли б визначити , є чи цей випадок можливий чи ні)

Не стрибки:

  • (Уникайте цього, якщо ви хочете перевірити шахи Фішера960) Якщо між королем та граком є шматки ворога, які не стрибають, і ще є пешки, не рухаючись; перевірте, чи могли ці ворожі частини законно потрапити туди. Крім того, запитайте себе: чи потрібен був король чи грак для переміщення, щоб створити цю посаду? (якщо так, нам потрібно переконатися, що здатності акторської майстерності відображають це)
  • Якщо всі 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
Ви також можете перевірити структуру пішака, наприклад, білі пішаки ніколи не можуть бути на а2, а3 та b2; жодного способу пішак не може бути як на a3, так і на b2.
— Акавал

Це означає, що позиції FEN повинні бути досягнуті лише з початкової позиції? Що робити, якщо я хотів, щоб позиції головоломки були представлені FEN? Іноді вони створюються таким чином, що неможливо досягти в реальній грі ...
— tbischel

@tbischel Я викладаю ці правила з звичайної шахової точки зору (не призначена для Chess960 або інших сформованих позицій), дякую, що я можу вказати це десь, щоб було зрозуміліше
— ajax333221

Навіть для звичайних шахів ви, можливо, не захочете робити всі ці перевірки. Ви отримуєте програму, яка не може представляти нелегальну позицію як FEN. Але вони трапляються на практиці - незаконні ходи іноді помічаються лише після гри. Чи не може бути неможливо показати діаграми таких ігор тощо?
— RemcoGerlich

1
@ Ajax333221: Ця сторінка дає юридичні гри , в яких білі отримують більше 5 пішаки на aфайл.

10
\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])/
— закидання

Я щойно зазначив, що ми можемо зробити тест "без пішаків у просуванні промоції" з чогось, що починається на кшталт([rnbqkRNBQK1-8]+\/)([rnbqkpRNBQKP1-8]+\/){6}([rnbqkRNBQK1-8]+) ....
— ajax333221

також для годинника це може бути добре, (0|[1-9][0-9]*)\s([1-9][0-9]*)оскільки в ходах не може бути провідних нулів, а повний хід не може бути або починати з 0, (код кредиту)
— ajax333221

5

Для інших існує проста функція в двигуні Stockfish, яка підтверджує струну 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
Схоже, все фактичне підтвердження зроблено в position.is_okay(). Код тут просто робить кілька основних перевірок, щоб переконатися, що він відформатований правильно, і що варто зробити реальну перевірку (тобто не очевидно незаконну).
— підземниймонорельс

4

Ось простий алгоритм зворотного відстеження, за умови, що у вас є функція, яка може перевіряти зворотні легальні ходи у кожному стані плати (також відомий як позиція):

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 половинний хід руху повинен відповідати прохідному цільовому квадрату; якщо присутній цільовий квадрат, то кількість половинного ходу має бути дорівнює нулю. половина підрахунку переміщення також повинна відповідати повного номера переміщення; наприклад, кількість половинних переміщень у десятку несумісна з повним номером ходу три.


1

Приходьте на вечірку пізно.

Неможливо на 100% перевірити, чи є позиція законною, але чому має бути валідація? Ми можемо грати в шахи, незалежно від того, чи є позиція, що виходить із вихідної позиції (так званий «ігровий масив»). Аналіз може бути дуже цікавим, але просто трапляється, що це незаконно.

Тому я би перевірив:

  • Чи є рівно 1 король з кожного боку?
  • Немає пішаків першого чи восьмого рангу?
  • Чи сторона, яка рухається, вже не дає чека?

Якщо це три ТАК, то ми можемо грати в шахи вперед на цій схемі. І навіть цей короткий список умов ми можемо ослабити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.