Оценка счета на основе шахматной строки FEN

17

Вызов

Нотация Форсайта – Эдвардса (FEN) - это стандартная нотация для описания конкретной позиции на доске в шахматной игре. Ваша задача - оценить результат, используя строку FEN. Это пример строки FEN:

5k2/ppp5/4P3/3R3p/6P1/1K2Nr2/PP3P2/8

Используя эту строку, вы можете рассчитать оценку материала для каждого цвета по следующей таблице:

  • п / п = пешка = 1 очко
  • н / ш = рыцарь = 3 очка
  • б / б = слон = 3 балла
  • R / R = Ладья = 5 очков
  • q / Q = Queen = 9 очков
  • k / K = король, у них нет никаких очков, потому что каждая легальная позиция содержит короля для каждой стороны

Белые фигуры обозначаются заглавными буквами («PNBRQK»), а черные - строчными («pnbrqk»). Пустые квадраты отмечаются цифрами от 1 до 8 (количество пустых квадратов), а "/" разделяет ранги.

Из примерной строки FEN мы можем рассчитать оценки материала для каждой стороны:

Для черного:

5 k 2 / ppp 5 / 4P3 / 3R3 p / 6P1 / 1K2N r 2 / PP3P2 / 8

Все черные фигуры остались: p + p + p + p + r, всего 9

Для белых:

5k2 / ppp5 / 4 P 3/3 R 3p / 6 P 1/1 K 2 N r2 / PP 3 P 2/8

Все белые фигуры остались: P + R + P + N + P + P + P, всего 13

Окончательная оценка определяется по следующей формуле: Белая оценка - черная оценка = итоговая оценка , поэтому для примера итоговая оценка будет: 13 - 9 = 4

Пример :

Входные данные:

5k2/ppp5/4P3/3R3p/6P1/1K2Nr2/PP3P2/8

Выход:

4

Здесь применяются все правила выигрывает решение с наименьшим количеством байтов.


Как разместить

# Language Name, N bytes

 [code]

 [explaination, etc.]
Аднан
источник
3
Таким образом, фактическая позиция не имеет значения? Вы просто считаете буквы в строке?
xnor
4
Nitpick: Это не полная строка FEN. Кроме того, kr1NQQQQ / 2rNQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / K2NQQQQ выигрывает для белых, когда черные ходят ? : P
дверная ручка
@xnor Да, я думаю, что если оценка будет также стратегической, она будет слишком сложной. Вы также можете предположить, что все входные данные являются законными позициями, так что не беспокойтесь об этом.
Аднан
@ Doorknob, да, счет только материал, основанный на упрощении вещей
Adnan

Ответы:

3

CJam, 28 27 26 байтов

0l{i32mdD%[5ZZX9]=\3%(*+}/

Попробуйте онлайн в интерпретаторе CJam .

Как это устроено

0l         e# Push a 0 (accumulator) and a line from STDIN.
{          e# For each character of that line:
  i32md    e#   Divide its code point by 32; push quotient and residue.
           e#   This serves two purposes:
           e#     1. The quotient will let us distinguish between uppercase
           e#        letters, lowercase letters and non-letters.
           e#     2. The residue will be the same for uppercase and lowercase
           e#        variants of the same letter.
  D%       e#   Take the residue modulo 13.
           e#   This maps R,N,B,P,Q -> 5,1,2,3,4
  [5ZZX9]= e#   Select the element at that index (5 ≡ 0) from [5 3 3 1 9].
  \        e#   Swap the quotient on top of the stack.
           e#   1 is digit or slash, 1 is uppercase, 2 is lowercase.
  3%(      e#   Take the quotient modulo 3 and subtract 1 from the result.
           e#   This maps 1,2,3 -> 0,1,-1.
  *+       e#   Multiply the generated integers.
  +        e#   Add the product to the accumulator.
}/         e#
Деннис
источник
5

> <> , 64 57 56 53 байта

"QRBNP"013359v
$0p4}:{:v?=1l<p4+' '{-
g4v?(0:i<+
n~<;

(-7 байтов с некоторым вдохновением от ответа @ El'endiaStarman, -3 байта благодаря @randomra)

объяснение

Программа использует кодовое поле в качестве справочной таблицы. Положения / получения вне допустимого диапазона не работают с онлайн-переводчиком, поэтому это работает только с официальным интерпретатором Python.

Первая строка сдвигает кусочки, а затем значения кусочков. Это также выдвигает начальный 0, чтобы сбросить сумму для третьей строки.

Затем вторая строка помещает соответствующее положительное или отрицательное значение в соответствующую ячейку элемента, например -1, помещается в ('p', 4)и 1размещается ('P', 4). Длина стека проверяется, чтобы убедиться, что цикл выполняется 5 раз.

После завершения цикла стек состоит из нашего единственного нуля из первой строки. Для каждого символа мы выполняем поиск соответствующей ячейки в таблице и добавляем ее к нашему итогу. По умолчанию значения неинициализированных ячеек равны 0, что идеально подходит для наших целей.

Последняя строка просто печатает результат.

Sp3000
источник
4

Рубин, 88 символов

->s{s.chars.map{|c|({P:1,N:3,B:3,R:5,Q:9}[:"#{c.upcase}"]||0)*(c.ord<90?1:-1)}.inject:+}

Это неловко и безобразно, и, возможно, есть лучший способ, ну да ладно.

{foo: 'bar'}Синтаксис Ruby на самом деле просто сахар {:foo => 'bar'}- это раздражает гольф, потому что это означает, что мне нужно преобразовать ключ в символ, прежде чем использовать его для доступа к элементу хеша ( :"#{x}"на один символ короче, чем x.to_sym).

Дверная ручка
источник
4

Пип, 39 байт

Я возьму свой короткий ход впереди, прежде чем придут ответы CJam и Pyth ...

$+Y(95<=>A_)*013359@{"KPNBRQ"@?UCa|0}Ma

Принимает строку FEN в качестве аргумента командной строки. Вот объяснение для слегка нелегкой версии:

$+({(95<=>Aa)*013359@("KPNBRQ"@?UCa|0)}Ma)

   {                                  }Ma   Map this function to each character in input:
                                UCa          Uppercase version of character
                      "KPNBRQ"@?             Its index in this string, nil if not present
                                   |0        Logical or with 0 (to turn nil into 0)
              013359@(               )       Index into this number to get piece's score
          Aa                                 ASCII value of character
     95<=>                                   1 if less than 95, -1 if greater than 95
    (       )*                               Multiply by the score
$+(                                      )  Sum all scores and autoprint result
DLosc
источник
4

Perl, 44 байта

#!perl -p
$\+=lc=~y/pnbrq/13359/r*(a cmp$_)for/\D/g}{

Считая Шебанг как единое, ввод берется из стандартного ввода.


Образец использования

$ echo 5k2/ppp5/4P3/3R3p/6P1/1K2Nr2/PP3P2/8 | perl fen-score.pl
4

объяснение

Части транслитерируются с соответствующими значениями. Если часть написана заглавными буквами (то есть меньше, чем a), ее значение добавляется к сумме, если не вычитается.

Примо
источник
3

JavaScript ES7, 79 байт, 124 131

s=>(i=0,[for(q of s)i+={P:1,N:3,B:3,R:5,Q:9,p:-1,n:-3,b:-3,r:-5,q:-9}[q]||0],i)

Короче, как я могу получить. Использует причудливое понимание массива, чтобы перебрать строку.

объяснение

s=>(     // Define function with an argument

    i=0, // this var will store the score

    [for(q of s)   // Loops through input
      i+=          // Adds to score by...

         {P:1,...,   // Defines value of each letter
          p:-1,...}  // Negative value instead, which will subtract
         || 0        // Otherwise add 0

    ], i           // Return score
Downgoat
источник
3

Минколанг 0,9 , 72 65 64 60 44 42 41 байт

13359"QRBNP"m5[d3~c~$r48*+0p0p]$I[o0q+]N.

Попробуй это здесь.

Большое спасибо Sp3000 за указание на гораздо более эффективный способ сделать это!

объяснение

13359"QRBNP"mвыталкивают баллы и соответствующие им символы, а затем чередуют их, так что стек выглядит следующим образом : [1,80,3,78,3,66,5,82,9,81]. Затем 5[d3~c~$r48*+0p0p]ставит оценку каждого символа, как строчные, так и прописные, в свое место в кодовом пространстве. Наконец, $I[o0q+]N.циклически перебирает входные данные до тех пор, пока они не станут пустыми, суммируя результаты по мере продвижения.

Эльендия Старман
источник
2

Уроборос , 82

Уроборос - это esolang, который я разработал на этой неделе. Время взять это на спин!

i.1+!57*(\m1(M\1).96>.@32*-.80=\.78=3*\.66=3*\.82=5*\81=9*++++\2*1\-*+
)L!4*(4Sn1(

Каждая строка команд 1 с одним символом представляет змею Уробороса, где выполнение продолжается от головы (начало) к хвосту (конец) и возвращается к голове. (И )команды позволяют съесть часть хвоста или извергнуть его, изменяя таким образом , что команды получают казнены. Если указатель инструкции когда-либо проглочен, змея умирает (прекращает выполнение). Программа Уроборос состоит из одной или нескольких змей, выполняющихся параллельно. У каждой змеи есть свой стек, а также есть общий стек.

1 Единственное исключение, которое отличает Уроборос от многих 2D-языков: многозначные числа могут быть записаны просто, без необходимости выполнять математику или сначала нажимать 0.

Змея 1

Первая змея читает символ ( i) и проверяет, является ли он -1 / EOF ( .1+!). Если так, он съедает большую часть своего хвоста, вплоть до M( 57*().

Затем змея меняет код символа с счетчиком, который находится над ним в стеке ( \), перемещает счет в общий стек ( m) и глотает другой символ ( 1(). Если он уже проглотил кучу, это означает, что он глотает, (что IP в настоящее время включен и умирает. В противном случае выполнение продолжается, перемещая счет обратно в стек змеи 1, обменивая его на код символа и отрыгивая символ, который был ранее проглочен ( M\1)).

Затем мы используем математические и стековые операции, чтобы сгенерировать соответствующий счет для персонажа. .96>проверяет, строчные они или нет; последующее 32*-преобразуется в верхний регистр. Затем длинный отрезок от .80=до 81=9*++++карт P-> 1, N-> 3и т. Д. Наконец, \2*1\-*сводит на нет счет, если буква была строчной, и +добавляет его в подсчет. Затем змея зацикливается и читает другого персонажа.

Змея 2

Вторая змея начинается с операции регургитации ( )), которая ничего не делает в первый раз (так как ничего еще не было проглочено, а также, поскольку выдает пустой стек 0). Затем он помещает длину общего стека в свой собственный стек и логически отрицает ( L!). Это дает, 1если стек пуст, в 0противном случае. Змея умножается на 4 и съедает столько символов ( 4*().

Если общий стек был пуст, это означает, что змея теперь заканчивается перед S. Он толкает 4и возвращается к тому ), где он извергает только что проглоченных персонажей и начинает заново.

Однако, если в общем стеке было значение, никакие символы не проглатываются, и выполнение продолжается. Змея переключается на общий стек и выводит число там ( Sn); затем он глотает свой последний символ и умирает ( 1().

синхронизация

Две змеи должны быть тщательно синхронизированы, чтобы в общем стеке никогда не было значения, когда змея 2 выполняет свою проверку, пока не будет достигнут конец ввода. Snake 1 кратко помещает значение в общий стек при каждом проходе его цикла. Таким образом, многожильный 2 в Lкоманде никогда не должна выполняться между mи Mкомандами в змее 1. К счастью, змей выстраивается очень хорошо. Важно отметить, что длина цикла «змея-1» (70 инструкций) кратна циклу «змея-2» (7 инструкций), поэтому эти два никогда не выйдут из синхронизации:

i.1+!57*(\m1(M\1).96>.@32*-.80=\.78=3*\.66=3*\.82=5*\81=9*++++\2*1\-*+
)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5)L!5*(5
          |__|
       Danger zone

Если бы числа не сработали так идеально, я бы добавил одну или обе змеи с пробелами, чтобы они выровнялись по мере необходимости.

Все это очень хорошо, но я хочу увидеть это в действии!

Вот вышеупомянутая программа с помощью фрагмента стека. Даже при 1000 операциях в секунду требуется около 10 секунд, чтобы выплюнуть ответ для выборочного ввода - но это действительно так!

DLosc
источник
2

JavaScript ES6, 71

Как анонимная функция

n=>[...n].map(x=>t+=~(y='q   rnb p PBN R   Q'.search(x))?y-9|1:0,t=0)|t
edc65
источник
2

Perl 5, 71 63 байта

%a=(P,1,N,3,B,3,R,5,Q,9);$\+=$a{$_}||-$a{uc$_}for<>=~/./g;print

Это изменяет $\(разделитель строк print, который начинается с false) для каждого буквенно-цифрового символа в строке, являющейся ключом хеш-функции, %aопределенной в начале. Он увеличивается $\на значение хэша, если буква является ключом как есть; в противном случае он увеличивается на отрицательное значение хэша, если заглавная буква является ключом; в противном случае это ничего не добавляет.

Большое спасибо primo за то, что сэкономил мне восемь байтов (в комментарии к этому ответу).


Я могу сохранить другой байт с другим предложением от primo (спасибо!): Изменить $a{$_}||-$a{uc$_}на $a{$_}-$a{$"^$_}. Но это, скорее, другой ответ, чем мой, я думаю, поэтому я не возьму «кредит» (-1 байт) за него.

msh210
источник
1

Clojure / ClojureScript, 63 символа

#(apply +(map{"P"1"N"3"B"3"R"5"Q"9"p"-1"n"-3"b"-3"r"-5"q"-9}%))

Написанный с использованием ClojureScript REPL, также должен быть действительным Clojure. Попробуй это здесь . Введите его, затем позвоните, используя(*1 "FEN_string_here")

Довольно просто. {"P"1..."q"-9}является литералом структуры данных для отображения «P» в 1, «N» в 3 и т. д., mapпринимает функцию в качестве первого аргумента и структуру данных для обработки в качестве второго - в этом случае она использует функцию, которая структура данных (литерал карты) может выступать в качестве своей собственной функции доступа. Строковый параметр ( %из макроса функции) можно рассматривать как список отдельных символьных строк. Любой персонаж, которого нет на карте, в конечном итоге окажется nilв результирующем списке, который, к +счастью, игнорируется.

MattPutnam
источник
1

Pyth, 25 байт

-Fmsmhy/4@S5%Ck12@Gd_rBz2

демонстрация

При этом используется следующая формула сопоставления для букв pbnrq, если kэто буква:

(4 / (((chr(k) % 12) % 5) + 1) * 2 + 1

Это представлено в Pyth как:

hy/4@S5%Ck12

Сначала программа создает замененную регистром версию ввода, затем в обеих строках фильтрует строчные буквы, затем применяет приведенную выше формулу, затем суммирует и вычитает значения черного из значений белого.

isaacg
источник
1

Питон 3, 93

v=dict(zip('pbnrqPBNRQ',[1,3,3,5,9]*2))
print(sum(v.get(c,0)*(-1)**(c>'Z')for c in input()))
Морган Трепп
источник