Valutazione del punteggio basato su una stringa FEN di scacchi


17

Sfida

Forsyth – Edwards Notation (FEN) è una notazione standard per descrivere una particolare posizione sulla scacchiera di una partita a scacchi. La tua sfida è valutare il punteggio usando la stringa FEN. Questo è un esempio di stringa FEN:

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

Usando questa stringa, puoi calcolare il punteggio del materiale per ciascun colore con la seguente tabella dei punteggi:

  • p / P = Pegno = 1 punto
  • n / N = Cavaliere = 3 punti
  • b / B = Bishop = 3 punti
  • r / R = Torre = 5 punti
  • q / Q = Regina = 9 punti
  • k / K = Re, questi non hanno punti perché ogni posizione legale contiene un re per ogni parte

I pezzi bianchi sono designati usando lettere maiuscole ("PNBRQK") mentre i pezzi neri usano lettere minuscole ("pnbrqk"). I quadrati vuoti vengono annotati usando le cifre da 1 a 8 (il numero di quadrati vuoti) e "/" separa i ranghi.

Dalla stringa FEN di esempio, possiamo calcolare i punteggi dei materiali per ciascun lato:

Per il nero:

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

Tutti i pezzi neri rimasti: p + p + p + p + r, questo è un totale di 9

Per il bianco:

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

Tutti i pezzi bianchi rimasti: P + R + P + N + P + P + P, per un totale di 13

Il punteggio finale viene determinato con la seguente formula: Punteggio bianco - Punteggio nero = Punteggio finale , quindi per l'esempio il punteggio finale sarebbe: 13-9 = 4

Esempio :

Ingresso:

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

Produzione:

4

Tutte le regole si applicano qui, la soluzione con il minor numero di byte vittorie.


Come pubblicare

# Language Name, N bytes

 [code]

 [explaination, etc.]

3
Quindi la posizione attuale non ha importanza? Conti solo lettere nella stringa?
xnor

4
Nitpick: non è una stringa FEN completa. Inoltre, kr1NQQQQ / 2rNQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / 3NQQQQ / K2NQQQQ sta vincendo per il bianco, con il nero per spostarsi? : P
Maniglia della porta

@xnor Sì, penso che se anche la valutazione è basata strategicamente, diventerà troppo complicata. Puoi anche presumere che tutti gli input siano posizioni legali, quindi non preoccuparti.
Adnan,

@Doorknob, sì, il punteggio è solo materiale basato per semplificare le cose
Adnan,

Risposte:


3

CJam, 28 27 26 byte

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

Provalo online nell'interprete CJam .

Come funziona

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 byte

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

(-7 byte con qualche ispirazione dalla risposta di @ El'endiaStarman, -3 byte grazie a @randomra)

Spiegazione

Il programma utilizza codebox come tabella di ricerca. I put / get fuori portata non funzionano con l'interprete online, quindi funziona solo con l'interprete Python ufficiale.

La prima riga spinge i pezzi, seguiti dai valori dei pezzi. Spinge anche uno 0 iniziale per dare il via al totale per la terza linea.

La seconda riga inserisce quindi il valore positivo o negativo appropriato nella cella del pezzo corrispondente, ad es. -1Viene posizionato ('p', 4)e 1posizionato('P', 4) . La lunghezza dello stack viene controllata per assicurarsi che il ciclo venga eseguito 5 volte.

Al termine del ciclo, lo stack è costituito dal nostro zero singolo dalla prima riga. Per ogni carattere eseguiamo una ricerca nella cella corrispondente nella tabella e la aggiungiamo al nostro totale. Per impostazione predefinita, i valori di cella non inizializzati sono 0, il che è perfetto per i nostri scopi.

L'ultima riga stampa semplicemente il risultato.


4

Rubino, 88 caratteri

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

Questo è imbarazzante e brutto, e probabilmente c'è un modo migliore, ma vabbè.

La {foo: 'bar'}sintassi di Ruby è in realtà solo zucchero per {:foo => 'bar'}— questo è fastidioso per il golf perché significa che devo convertire la chiave in un simbolo prima di usarla per accedere a un elemento hash ( :"#{x}"è un carattere più corto di x.to_sym).


4

Pip, 39 byte

Prenderò la mia breve svolta in testa prima che arrivino le risposte di CJam e Pyth ...

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

Prende la stringa FEN come argomento della riga di comando. Ecco una spiegazione per una versione leggermente non golfata:

$+({(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

4

Perl, 44 byte

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

Contando lo shebang come uno, l'input è preso dallo stdin.


Esempio di utilizzo

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

Spiegazione

I pezzi vengono traslitterati con i rispettivi valori. Se il pezzo viene capitalizzato (cioè inferiore a a), il suo valore viene aggiunto alla somma, in caso contrario viene sottratto.


3

JavaScript ES7, 79 byte 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)

Più corto che posso ottenere. Utilizza fantasiose comprensioni di array per scorrere la stringa.

Spiegazione

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

3

Minkolang 0.9 , 72 65 64 60 44 42 41 byte

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

Provalo qui.

Mille grazie a Sp3000 per aver segnalato un modo molto più efficiente per farlo!

Spiegazione

13359"QRBNP"mspinge i punteggi e le loro caratteri corrispondenti, poi interfogli loro, quindi gli sguardi di stack come questo: [1,80,3,78,3,66,5,82,9,81]. Quindi 5[d3~c~$r48*+0p0p]posiziona il punteggio di ciascun personaggio, sia in minuscolo che maiuscolo, nella sua posizione nello spazio del codice. Infine, $I[o0q+]N.scorre attraverso l'ingresso fino a quando non è vuoto, sommando i punteggi man mano che procede.


2

CJam, 33 byte

q{"PNBRQ"_el+#13359Ab_Wf*+0+=}%:+

Ecco il modo super-ingenuo di trovare le stringhe. Provalo online .


2

Ouroboros , 82

Ouroboros è un esolang che ho progettato questa settimana. È ora di fare un giro!

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

Ogni riga di comandi a carattere singolo 1 rappresenta un serpente ouroboros, in cui l'esecuzione procede dalla testa (inizio) alla coda (fine) e ritorna alla testa. L' (e )comandi permetterà di mangiare parte della coda o rigurgitare esso, modificando in tal modo quali comandi vengono eseguiti. Se il puntatore dell'istruzione viene ingoiato, il serpente muore (interrompe l'esecuzione). Un programma Ouroboros consiste in uno o più serpenti che si eseguono in parallelo. Ogni serpente ha una pila propria e c'è anche una pila condivisa.

1 Un'eccezione, che distingue Ouroboros da molti linguaggi 2D: i numeri a più cifre possono essere scritti in modo semplice, senza dover fare matematica o premere prima uno 0.

Snake 1

Il primo serpente legge un carattere ( i) e controlla se è -1 / EOF ( .1+!). In tal caso, mangia la maggior parte della coda, fino a M( 57*() incluso .

Il serpente scambia quindi il codice personaggio con il riscontro che si trova sopra di esso sullo stack ( \), sposta il riscontro sullo stack condiviso ( m) e ingoia un altro personaggio ( 1(). Se ha già ingoiato un mucchio, ciò significa che ingoia (l'IP attualmente attivo e muore. Altrimenti, l'esecuzione procede riportando il conteggio nello stack di snake 1, scambiandolo con il codice char e rigurgitando il personaggio che era stato ingoiato ( M\1)).

Quindi utilizziamo operazioni matematiche e di stack per generare il punteggio appropriato per il personaggio. .96>verifica se è minuscolo o no; il successivo viene 32*-convertito in maiuscolo. Quindi il lungo tratto da .80=alle 81=9*++++mappe P-> 1, N-> 3, ecc. Infine, \2*1\-*annulla il punteggio se la lettera era minuscola e+ aggiunge al conteggio corrente. Il serpente quindi gira e legge un altro personaggio.

Snake 2

Il secondo serpente inizia con un'operazione di rigurgito ( )), che non fa nulla per la prima volta (dal momento che non è stato ancora ingoiato nulla, e anche dal momento in cui è scoppiato uno stack vuoto 0). Successivamente, sposta la lunghezza dello stack condiviso nel proprio stack e nega logicamente ( L!). Questo dà 1se lo stack è vuoto, 0altrimenti. Il serpente si moltiplica per 4 e mangia molti personaggi (4*( ).

Se lo stack condiviso era vuoto, ciò significa che il serpente ora termina prima di S. Spinge 4e ritorna al ), dove rigurgita i personaggi che ha appena ingoiato e ricomincia da capo.

Se nello stack condiviso era presente un valore, tuttavia, nessun carattere viene ingoiato e l'esecuzione continua. Il serpente passa allo stack condiviso e genera il numero lì ( Sn); poi ingoia il suo ultimo personaggio e muore ( 1().

Sincronizzazione

I due serpenti devono essere accuratamente sincronizzati in modo che non vi sia mai un valore nello stack condiviso quando snake 2 fa il suo controllo, fino a quando non viene raggiunta la fine dell'input. Snake 1 inserisce brevemente un valore nello stack condiviso su ogni passaggio attraverso il suo loop. Pertanto, il Lcomando di snake 2 non deve mai essere eseguito tra i comandi me Min snake 1. Fortunatamente, i serpenti si allineano molto bene. Fondamentalmente, la lunghezza del loop di snake 1 (70 istruzioni) è un multiplo del loop di snake 2 (7 istruzioni), quindi i due non usciranno mai di sincronizzazione:

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

Se i numeri non avessero funzionato così perfettamente, avrei riempito uno o entrambi i serpenti con spazi per allinearli secondo necessità.

Tutto questo va molto bene, ma voglio vederlo in azione!

Ecco il programma sopra tramite Stack Snippet. Anche su 1000 operazioni al secondo, ci vogliono circa 10 secondi per sputare la risposta per l'input del campione - ma ci arriva!


2

JavaScript ES6, 71

Come una funzione anonima

n=>[...n].map(x=>t+=~(y='q   rnb p PBN R   Q'.search(x))?y-9|1:0,t=0)|t

2

Perl 5, 71 63 byte

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

Questo modifica $\(il separatore di riga per print, che inizia falso) per ogni alfanumerico nella stringa che è una chiave dell'hash %adefinito all'inizio. Aumenta $\del valore dell'hash se la lettera è una chiave così com'è; in caso contrario, incrementa in negativo il valore dell'hash se la lettera maiuscola è una chiave; altrimenti non aggiunge nulla.

Mille grazie a primo per avermi salvato otto byte (in un commento su questa risposta).


Posso salvare un altro byte con un altro suggerimento di primo (grazie!): Passare $a{$_}||-$a{uc$_}a $a{$_}-$a{$"^$_}. Ma questa è una risposta piuttosto diversa dalla mia, penso, quindi non prenderò il "credito" (di -1 byte).


1

Clojure / ClojureScript, 63 caratteri

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

Scritto usando un REPL ClojureScript, dovrebbe essere valido anche Clojure. Provalo qui . Inseriscilo, quindi chiamalo utilizzando(*1 "FEN_string_here")

Abbastanza diretto. {"P"1..."q"-9}è una struttura di dati letterale per una mappa da "P" a 1, "N" a 3, ecc. mapaccetta la funzione come primo argomento e la struttura di dati da elaborare come seconda - in questo caso, utilizza la funzione che una struttura di dati (letterale della mappa) può fungere da propria funzione di accesso. Il parametro stringa ( %dalla macro funzione) può essere trattato come un elenco di singole stringhe di caratteri. Qualsiasi personaggio non presente nella mappa finirà come nilnell'elenco risultante, che +ignora felicemente.


1

Pyth, 25 byte

-Fmsmhy/4@S5%Ck12@Gd_rBz2

Dimostrazione

Questo utilizza la seguente formula di mappatura per le lettere pbnrq, se kè la lettera:

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

Questo è rappresentato in Pyth come:

hy/4@S5%Ck12

Innanzitutto, il programma crea la versione di input maiuscole e minuscole, quindi su entrambi i filtri di stringhe le lettere minuscole, quindi applica la formula sopra, quindi somma e sottrae i valori del nero dai valori del bianco.


1

Python 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()))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.