Générateur de position Chess960

11

Le contexte

Chess960 (ou Fischer Random Chess) est une variante des échecs inventée et préconisée par l'ancien champion du monde d'échecs Bobby Fischer, annoncée publiquement le 19 juin 1996 à Buenos Aires, Argentine. Il utilise la même planche et les mêmes pièces que les échecs standard; cependant, la position de départ des pièces sur les rangs à domicile des joueurs est aléatoire

Règles

  • Les pions blancs sont placés au deuxième rang comme dans les échecs standard
  • Toutes les pièces blanches restantes sont placées au hasard au premier rang
  • Les évêques doivent être placés sur des carrés de couleur opposée
  • Le roi doit être placé sur une case entre les tours.
  • Les pièces noires sont placées de manière égale et opposée aux pièces blanches.

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

Pour toutes les personnes qui souhaitent poster des réponses ...

vous devez créer un générateur de positions Chess960, capable de générer aléatoirement l'une des 960 positions en suivant les règles décrites ci-dessus (il doit être capable de produire n'importe laquelle des 960, le codage en dur d'une position n'est pas accepté!), et vous n'avez qu'à produire les pièces blanches de rang un.

Exemple de sortie:

rkrbnnbq

où:

  • k king
  • q reine
  • évêque
  • chevalier
  • r tour

Ce sera le golf de code, et le bris d'égalité sera les votes positifs.

jsedano
la source
Lorsque vous dites qu'il doit être capable de produire n'importe laquelle des 960 positions, doivent-elles être équiprobables?
Peter Taylor
Intéressant, je n'y ai pas vraiment pensé ... Je veux dire idéalement ça devrait être, je pense ... Les réponses jusqu'à présent offrent cette qualité, ... non?
jsedano
Les deux qui sont écrits dans des langues qui ont des blocs qui mélangent uniformément font; les deux GolfScript sont proches mais pas tout à fait uniformes.
Peter Taylor
Je dirais que fermer est assez bon
jsedano
Cette question m'a inspiré à poser codegolf.stackexchange.com/questions/12322/…
user123444555621

Réponses:

6

GolfScript ( 49 48 caractères ou 47 pour la sortie en majuscules)

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

Cela utilise la technique standard de permutation aléatoire jusqu'à ce que nous remplissions les critères. Contrairement à la solution GolfScript de w0lf, cela vérifie la chaîne, il est donc probable qu'elle passe plusieurs fois dans la boucle.

L'utilisation de majuscules permet d'enregistrer un caractère:

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

Ruby 1.9, 67 65 caractères

Ah, l'ancienne technique de "continuer à randomiser jusqu'à ce que vous génériez quelque chose de valide" ...

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

(Dans Ruby 2.0, %w(r r n n b b q k)pourrait être 'rrnnbbqk'.chars)

Paul Prestidge
la source
1
Dans 1.9.3, vous pouvez épargner le ~avec le coût d'un avertissement, lorsqu'il est disponible. pastebin.com/nuE9zWSw
manatwork
@manatwork c'est super, merci!
Paul Prestidge
2
la technique "continuer à randomiser jusqu'à ce que vous génériez quelque chose de valide" est encore beaucoup plus rapide que la technique "mélanger la liste des possibilités, filtrer et prendre en premier" que les langages purement fonctionnels comme APL ont tendance à produire :-)
John Dvorak
1
@Daniero, c'est certainement la $_variable. Cela fonctionne parce que ruby ​​a des méthodes soignées telles que Kernel # chop qui fonctionnent comme la méthode équivalente String # chop mais avec $_comme récepteur. Cela vous fait gagner beaucoup de temps lorsque (par exemple) vous écrivez une boucle de lecture / traitement / écriture à l'aide de ruby -nou ruby -p.
Paul Prestidge
2
@GigaWatt no. L'ancien correspond s'il y a un nombre pair de caractères entre deux B environ. Ce dernier ne correspond que si les B'S sont aux extrémités.
John Dvorak
8

GolfScript 60 49

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

(raccourci à 49 caractères grâce aux bons conseils de Peter Taylor)

Test en ligne ici .

Une explication du code:

;'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
la source
1
Votre méthode pour vérifier qu'il y a un nombre pair de lettres entre les bs semble très longue. Et alors .'b'/1=,2%?
Peter Taylor
Et vous pouvez éviter de rejeter les tentatives infructueuses en tirant 'qbbnnxxx'sur la boucle et en remaniant la même chaîne.
Peter Taylor
@PeterTaylor Merci pour les bons conseils. Pour le problème du «compte entre les b», j'estimais qu'il devrait y avoir un moyen plus court, mais je ne pouvais tout simplement pas le trouver.
Cristian Lupascu
4

J, 56 caractères

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

cela prend plusieurs secondes sur ma machine en raison de l'algorithme inefficace. Une certaine vitesse peut être gagnée en ajoutant ~.(supprimez les doublons) avant 'kqbbnnrr'.

explication:

  • ?~!8traite 8!des éléments aléatoires de0 ... 8!
  • 'kqbbnnrr'A.~les utilise comme index anagrammes de la chaîne kqbbnnrr.
  • (#~'...'&rxeq"1)' les filtre par l'expression régulière entre guillemets.
  • {. signifie "prendre le premier élément"
John Dvorak
la source
4

K, 69

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

Python, 105 caractères

Fondamentalement, la technique de chron, moins l'élégante substance Ruby.

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

Merci à Peter Taylor pour le raccourcissement de l'expression régulière.

daniero
la source
not s('b(..)*b',a)semble être une façon de dire de longue haleine s('b.(..)*b',a). En outre, samplepeut être un caractère plus court que shuffle, mais il nécessite un argument supplémentaire.
Peter Taylor
Vous avez raison au sujet de l'expression rationnelle, Peter. Merci! Shuffleretourne Nonecependant, donc ce n'est pas bon :(
daniero
1
Manqué la forêt pour les arbres. Vous n'avez pas besoin de deux expressions régulières, car vous vérifiez la même chaîne et oréquivaut à l'alternance regex ( |). Enregistre 13 caractères.
Peter Taylor
@PeterTaylor Bonne prise! Merci.
daniero