Generatore di posizione Chess960


11

Contesto

Chess960 (o Fischer Random Chess) è una variante di scacchi inventata e sostenuta dall'ex campione del mondo di scacchi Bobby Fischer, annunciato pubblicamente il 19 giugno 1996 a Buenos Aires, in Argentina. Impiega la stessa tavola e gli stessi pezzi degli scacchi standard; tuttavia, la posizione iniziale dei pezzi nelle classifiche dei giocatori è casuale

Regole

  • Le pedine bianche sono posizionate al secondo rango come negli scacchi standard
  • Tutti i pezzi bianchi rimanenti vengono posizionati casualmente sul primo rango
  • I vescovi devono essere posti su quadrati di colore opposto
  • Il re deve essere posizionato su una piazza tra le torri.
  • I pezzi di Black sono posti uguali e opposti ai pezzi di White.

Da: http://en.wikipedia.org/wiki/Chess960

Per tutte le persone che vorrebbero pubblicare risposte ...

devi creare un generatore di posizioni Chess960, in grado di generare casualmente una delle 960 posizioni seguendo le regole sopra descritte (deve essere in grado di produrre una delle 960, non è accettata la codifica di una posizione!), e devi solo uscita del rango bianco di un pezzo.

Esempio di output:

rkrbnnbq

dove:

  • k re
  • q regina
  • b vescovo
  • n cavaliere
  • r torre

Questo sarà il golf del codice, e il pareggio sarà il voto.


Quando dici che deve essere in grado di emettere una qualsiasi delle 960 posizioni, devono essere equiprobabili?
Peter Taylor,

Interessante, non ci ho davvero pensato ... Voglio dire idealmente dovrebbe essere, penso ... Le risposte finora offrono questa qualità, ... giusto?
jsedano,

I due che sono scritti in lingue che hanno builtin che mescolano uniformemente; i due GolfScript sono vicini ma non del tutto uniformi.
Peter Taylor,

Direi che vicino è abbastanza buono
jsedano,

Questa domanda mi ha ispirato a chiedere a codegolf.stackexchange.com/questions/12322/…
user123444555621 il

Risposte:


6

GolfScript ( 49 48 caratteri o 47 per output maiuscolo)

'bbnnrrkq'{{;9rand}$.'b'/1=,1$'r'/1='k'?)!|1&}do

Questo utilizza la tecnica standard di permutazione casuale fino a quando non soddisfiamo i criteri. A differenza della soluzione GolfScript di w0lf, entrambi i controlli sulla stringa vengono eseguiti, quindi è probabile che eseguano il ciclo più volte.

L'uso di maiuscole consente di salvare un carattere:

'BBNNRRKQ'{{;9rand}$.'B'/1=,1$'R'/1=75?)!|1&}do

8

Ruby 1.9, 67 65 caratteri

Ah, la vecchia tecnica "continua a randomizzare fino a quando non generi qualcosa di valido" ...

$_=%w(r r n n b b q k).shuffle*''until/r.*k.*r/&&/b(..)*b/
$><<$_

(In Ruby 2.0, %w(r r n n b b q k)potrebbe essere 'rrnnbbqk'.chars)


1
In 1.9.3 puoi risparmiare il ~costo di un avviso, se disponibile. pastebin.com/nuE9zWSw
manatwork

@manatwork è fantastico, grazie!
Paul Prestidge,

2
la tecnica "continua a randomizzare fino a quando non generi qualcosa di valido" è ancora molto più veloce della tecnica "rimescola l'elenco di possibilità, filtra e prendi prima" che i linguaggi puramente funzionali come APL tendono a produrre :-)
John Dvorak,

1
@Daniero questa è sicuramente la $_variabile. Funziona perché ruby ​​ha alcuni metodi accurati come Kernel # chop che funzionano come il metodo String # chop equivalente ma con $_come ricevitore. Ciò consente di risparmiare molto tempo quando (ad esempio) si sta scrivendo un ciclo di lettura / elaborazione / scrittura utilizzando ruby -no ruby -p.
Paul Prestidge,

2
@GigaWatt no. Il primo corrisponde se c'è un numero pari di personaggi tra due B. Quest'ultimo corrisponde solo se i B'S sono alle estremità.
John Dvorak,

8

GolfScript 60 49

;'qbbnnxxx'{{9rand*}$.'b'/1=,2%}do'x'/'rkr'1/]zip

(ridotto a 49 caratteri grazie ai grandi consigli di Peter Taylor)

Test online qui .

Una spiegazione del codice:

;'qbbnnxxx'         # push the string 'qbbnnxxx' on the clean stack
{

    {9rand*}$       # shuffle the string

    .'b'/1=,2%      # count the number of places between the 'b's
                    # (including the 'b's themselves)
                    # if this count is even, the bishops are on
                    # squares of different colors, so place a 0
                    # on the stack to make the do loop stop

}do                 # repeat the procedure above until a 
                    # good string is encountered

'x'/                # split the string where the 'x's are

'rkr'1/]zip         # and put 'r', 'k' and then 'r' again
                    # where the 'x's used to be

1
Il tuo metodo per verificare che ci sia un numero pari di lettere tra le bs sembra molto lungo. Che ne dici .'b'/1=,2%?
Peter Taylor,

E puoi evitare di scartare i tentativi falliti estraendo 'qbbnnxxx'il loop e rimescolando la stessa stringa.
Peter Taylor,

@PeterTaylor Grazie per gli ottimi consigli. Per il problema del "conteggio tra 'b' 'ho sentito che ci doveva essere un modo più breve, ma non riuscivo a trovarlo.
Cristian Lupascu,

4

J, 56 caratteri

{.(#~'(?=.*b(..)*b).*r.*k.*r.*'&rxeq"1)'kqbbnnrr'A.~?~!8

ci vogliono diversi secondi sulla mia macchina a causa dell'algoritmo inefficiente. Un po 'di velocità può essere ottenuta aggiungendo ~.(rimuovi duplicati) prima 'kqbbnnrr'.

spiegazione:

  • ?~!8tratta 8!elementi casuali da0 ... 8!
  • 'kqbbnnrr'A.~li usa come indici anagramma alla stringa kqbbnnrr.
  • (#~'...'&rxeq"1)' li filtra per regex tra virgolette.
  • {. significa "prendi il primo elemento"

4

K, 69

(-8?)/[{~*(*/~~':{m=_m:x%2}@&x="b")&(&x="k")within&"r"=x};"rrbbnnkq"]

3

Python, 105 caratteri

Fondamentalmente la tecnica di Chron, meno l'elegante roba Ruby.

import re,random
a='rrbbnnkq'
while re.search('b.(..)*b|r[^k]*r',a):a=''.join(random.sample(a,8))
print a

Grazie a Peter Taylor per l'accorciamento della regex.


not s('b(..)*b',a)sembra un modo prolisso di dire s('b.(..)*b',a). Inoltre, samplepuò essere un personaggio più corto di shuffle, ma richiede un argomento in più.
Peter Taylor,

Hai ragione sulla regex, Peter. Grazie! Shuffleritorna Noneperò, quindi non va bene :(
daniero il

1
Mancava la foresta per gli alberi. Non hai bisogno di due regex, perché stai controllando la stessa stringa ed orequivale a regex alternation ( |). Salva 13 caratteri.
Peter Taylor,

@PeterTaylor Buona cattura! Grazie.
daniero,
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.