Chess960 Positionsgenerator

11

Kontext

Chess960 (oder Fischer Random Chess) ist eine Schachvariante, die vom ehemaligen Schachweltmeister Bobby Fischer erfunden und befürwortet wurde und am 19. Juni 1996 in Buenos Aires, Argentinien, öffentlich angekündigt wurde. Es werden die gleichen Bretter und Figuren wie beim Standardschach verwendet. Die Startposition der Figuren in den Heimrängen der Spieler ist jedoch zufällig

Regeln

  • Weiße Bauern werden wie beim Standardschach auf den zweiten Rang gesetzt
  • Alle verbleibenden weißen Teile werden zufällig auf den ersten Rang gesetzt
  • Die Bischöfe müssen auf Quadrate mit entgegengesetzter Farbe gestellt werden
  • Der König muss auf ein Feld zwischen den Türmen gestellt werden.
  • Die Stücke von Schwarz sind den Stücken von Weiß gleich und entgegengesetzt platziert.

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

Für alle Leute, die Antworten posten möchten ...

Sie müssen einen Chess960-Positionsgenerator erstellen, der in der Lage ist, eine der 960-Positionen nach den oben beschriebenen Regeln zufällig zu generieren (er muss in der Lage sein, eine der 960-Positionen auszugeben, eine Hardcodierung einer Position wird nicht akzeptiert!), und Sie müssen nur Geben Sie die weißen Rang-1-Stücke aus.

Beispielausgabe:

rkrbnnbq

wo:

  • k König
  • q Königin
  • b Bischof
  • n Ritter
  • r Turm

Dies wird Code Golf sein, und der Tie Breaker werden die Upvotes sein.

jsedano
quelle
Wenn Sie sagen, dass es in der Lage sein muss, eine der 960 Positionen auszugeben, müssen sie gleich wahrscheinlich sein?
Peter Taylor
Interessant, daran habe ich nicht wirklich gedacht ... Ich meine, im Idealfall sollte es so sein, denke ich ... Die bisherigen Antworten bieten diese Qualität, ... richtig?
jsedano
Die beiden, die in Sprachen geschrieben sind, die eingebaute Elemente haben, die gleichmäßig mischen; Die beiden GolfScript sind nahe beieinander, aber nicht ganz einheitlich.
Peter Taylor
Ich würde sagen, dass nah gut genug ist
jsedano
Diese Frage inspirierte mich, codegolf.stackexchange.com/questions/12322/…
user123444555621

Antworten:

6

GolfScript ( 49 48 Zeichen oder 47 für die Ausgabe in Großbuchstaben)

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

Dies verwendet die Standardtechnik des zufälligen Permutierens, bis wir die Kriterien erfüllen. Im Gegensatz zur GolfScript-Lösung von w0lf werden hier beide Zeichenfolgen überprüft, sodass die Schleife wahrscheinlich mehrmals durchlaufen wird.

Wenn Sie Großbuchstaben verwenden, können Sie ein Zeichen speichern:

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

Ruby 1.9, 67 65 Zeichen

Ah, die alte Technik "Randomisieren, bis Sie etwas Gültiges generieren" ...

$_=%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)könnte sein 'rrnnbbqk'.chars)

Paul Prestidge
quelle
1
In 1.9.3 können Sie die ~mit den Kosten einer Warnung ersparen, sofern verfügbar. pastebin.com/nuE9zWSw
Manatwork
@manatwork das ist toll, danke!
Paul Prestidge
2
Die Technik "Randomisieren, bis Sie etwas Gültiges generieren" ist immer noch viel schneller als die Technik "Liste der Möglichkeiten mischen, filtern und zuerst nehmen", die rein funktionale Sprachen wie APL tendenziell produzieren :-)
John Dvorak
1
@ Daniero das ist definitiv die $_Variable. Es funktioniert, weil Ruby einige nette Methoden wie Kernel # chop hat, die wie die entsprechende String # chop-Methode funktionieren, aber mit $_als Empfänger. Dies spart viel Zeit, wenn Sie (zum Beispiel) eine Lese- / Prozess- / Schreibschleife mit ruby -noder schreiben ruby -p.
Paul Prestidge
2
@GigaWatt nein. Ersteres stimmt überein, wenn zwischen zwei B eine gerade Anzahl von Zeichen liegt. Letzteres stimmt nur überein, wenn die B'S am Ende sind.
John Dvorak
8

GolfScript 60 49

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

(verkürzt auf 49 Zeichen dank Peter Taylors tollen Tipps)

Online Test hier .

Eine Erklärung des Codes:

;'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
w0lf
quelle
1
Ihre Methode, um zu überprüfen, ob zwischen den bs eine gerade Anzahl von Buchstaben steht, scheint sehr lang zu sein. Wie wäre es .'b'/1=,2%?
Peter Taylor
Sie können vermeiden, dass fehlgeschlagene Versuche verworfen werden, indem Sie 'qbbnnxxx'die Schleife aus der Schleife ziehen und dieselbe Zeichenfolge neu mischen.
Peter Taylor
@ PeterTaylor Danke für die tollen Tipps. Für das Thema "Zählen zwischen 'b'" hatte ich das Gefühl, dass es einen kürzeren Weg geben sollte, aber ich konnte ihn einfach nicht finden.
Cristian Lupascu
4

J, 56 Zeichen

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

Aufgrund des ineffizienten Algorithmus dauert es auf meinem Computer einige Sekunden. Eine gewisse Geschwindigkeit kann durch vorheriges Hinzufügen ~.(Entfernen von Duplikaten) erreicht werden 'kqbbnnrr'.

Erläuterung:

  • ?~!8behandelt 8!zufällige Elemente aus0 ... 8!
  • 'kqbbnnrr'A.~verwendet sie als Anagrammindizes für die Zeichenfolge kqbbnnrr.
  • (#~'...'&rxeq"1)' filtert sie nach dem regulären Ausdruck in Anführungszeichen.
  • {. bedeutet "nimm das erste Element"
John Dvorak
quelle
4

K, 69

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

Python, 105 Zeichen

Grundsätzlich Chron's Technik, abzüglich des eleganten Ruby-Materials.

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

Vielen Dank an Peter Taylor für die Verkürzung der Regex.

daniero
quelle
not s('b(..)*b',a)scheint eine langatmige Art zu sagen s('b.(..)*b',a). Auch samplekann ein Zeichen kürzer als shuffle, aber es erfordert ein zusätzliches Argument.
Peter Taylor
Sie haben Recht mit der Regex, Peter. Vielen Dank! Shufflekehrt Noneaber zurück, also ist es nicht gut :(
daniero
1
Verpasste den Wald vor lauter Bäumen. Sie benötigen keine zwei regulären Ausdrücke, da Sie dieselbe Zeichenfolge überprüfen und der regulären Auswechslung oralternation ( |) entsprechen. Spart 13 Zeichen.
Peter Taylor
@ PeterTaylor Guter Fang! Vielen Dank.
Daniero