Генератор положения Chess960

11

контекст

Chess960 (или Случайные шахматы Фишера) - вариант шахмат, изобретенный и защищаемый бывшим чемпионом мира по шахматам Бобби Фишером, который был публично объявлен 19 июня 1996 года в Буэнос-Айресе, Аргентина. Он использует ту же доску и фигуры, что и стандартные шахматы; однако начальная позиция фигур в домашних рядах игроков рандомизирована

правила

  • Белые пешки ставятся на второе место, как в стандартных шахматах.
  • Все оставшиеся белые фигуры рандомизированы на первое место
  • Епископы должны быть размещены на квадратах противоположного цвета
  • Король должен быть размещен на поле между ладьями.
  • Фигуры черных равны и противоположны фигурам белых.

От: http://en.wikipedia.org/wiki/Chess960

Для всех людей, которые хотели бы опубликовать ответы ...

Вы должны сделать генератор позиций Chess960, способный случайным образом генерировать одну из 960 позиций в соответствии с правилами, описанными выше (он должен быть способен выводить любую из 960, жесткое кодирование одной позиции не допускается!), и вам нужно только Выведите белый ранг одной штуки.

Пример вывода:

rkrbnnbq

где:

  • К Кинг
  • королева
  • епископ
  • русский рыцарь
  • ладья

Это будет кодекс гольфа, а противоборство будет положительным.

jsedano
источник
Когда вы говорите, что он должен быть способен выводить любую из 960 позиций, они должны быть равновероятными?
Питер Тейлор
Интересно, я на самом деле не думал об этом ... Я имею в виду, в идеале это должно быть, я думаю ... Ответы до сих пор предлагают это качество, верно?
Jsedano
Два, которые написаны на языках, которые имеют встроенные, которые тасуются равномерно, делают; два GolfScript близки, но не совсем одинаковы.
Питер Тейлор
Я бы сказал, что близко достаточно хорошо
jsedano
Этот вопрос вдохновил меня спросить codegolf.stackexchange.com/questions/12322/...
user123444555621

Ответы:

6

GolfScript ( 49 48 символов или 47 для вывода в верхнем регистре)

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

При этом используется стандартная техника случайной перестановки, пока мы не встретим критерии. В отличие от решения wScript для GolfScript, оно выполняет обе проверки строки, поэтому, скорее всего, будет проходить цикл больше раз.

Использование верхнего регистра позволяет сохранить один символ:

'BBNNRRKQ'{{;9rand}$.'B'/1=,1$'R'/1=75?)!|1&}do
Питер Тейлор
источник
8

Ruby 1.9, 67 65 знаков

Ах, старая техника "продолжай рандомизировать, пока не создашь что-то правильное" ...

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

(В Ruby 2.0 %w(r r n n b b q k)может быть 'rrnnbbqk'.chars)

Пол Престиж
источник
1
В 1.9.3 вы можете сэкономить ~со стоимостью предупреждения, если оно доступно. pastebin.com/nuE9zWSw
manatwork
@ Manatwork это здорово, спасибо!
Пол Престиж
2
Техника «продолжай рандомизировать до тех пор, пока не получишь что-то правильное» все еще намного быстрее, чем метод «перемешай список возможностей, отфильтруй и возьми в первую очередь», который, как правило, создают чисто функциональные языки, такие как APL :-)
Джон Дворжак
1
@Daniero, это определенно то, что $_переменная. Это работает, потому что у ruby ​​есть несколько аккуратных методов, таких как Kernel # chop, которые работают как эквивалентный метод String # chop, но с $_их приемником. Это экономит много времени, когда (например) вы пишете цикл чтения / обработки / записи, используя ruby -nили ruby -p.
Пол Престиж
2
@GigaWatt нет. Первое совпадение, если между двумя буквами B есть четное число символов. Последний соответствует только если B'S на концах.
Джон Дворжак
8

GolfScript 60 49

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

(сокращено до 49 символов благодаря замечательным советам Питера Тейлора)

Онлайн тест здесь .

Объяснение кода:

;'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
источник
1
Ваш метод проверки наличия четного числа букв между символами bs кажется очень длинным. Как насчет .'b'/1=,2%?
Питер Тейлор
И вы можете избежать отбрасывания неудачных попыток, вытаскивая 'qbbnnxxx'из цикла и перетасовывая ту же строку.
Питер Тейлор
@PeterTaylor Спасибо за отличные советы. Что касается вопроса «считать между« б »», я чувствовал, что должен быть более короткий путь, но я просто не мог его найти.
Кристиан Лупаску
4

J, 56 знаков

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

это занимает несколько секунд на моей машине из-за неэффективного алгоритма. Некоторая скорость может быть достигнута путем добавления ~.(удаления дубликатов) раньше 'kqbbnnrr'.

объяснение:

  • ?~!8имеет дело со 8!случайными элементами из0 ... 8!
  • 'kqbbnnrr'A.~использует их в качестве индексов анаграммы в строке kqbbnnrr.
  • (#~'...'&rxeq"1)' фильтрует их по регулярному выражению в кавычках.
  • {. означает «взять первый элемент»
Джон дворак
источник
4

K, 69

(-8?)/[{~*(*/~~':{m=_m:x%2}@&x="b")&(&x="k")within&"r"=x};"rrbbnnkq"]
tmartin
источник
3

Питон, 105 символов

В основном техника Хрона, за исключением элегантного материала Ruby.

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

Спасибо Питеру Тейлору за сокращение регулярного выражения.

daniero
источник
not s('b(..)*b',a)похоже на многословный способ сказать s('b.(..)*b',a). Кроме того, sampleможет быть один символ короче shuffle, но это требует дополнительного аргумента.
Питер Тейлор
Ты прав насчет регулярного выражения, Питер. Благодаря! хотя Shuffleвозвращается None, так что это нехорошо :(
Даниеро
1
Скучал по лесу за деревьями. Вам не нужно два регулярных выражения, потому что вы проверяете одну и ту же строку и orэквивалентно чередованию регулярных выражений ( |). Сохраняет 13 символов.
Питер Тейлор
@PeterTaylor Хороший улов! Спасибо.
Даниеро