Generator posisi Chess960

11

Konteks

Chess960 (atau Fischer Random Chess) adalah varian catur yang diciptakan dan dianjurkan oleh mantan Juara Catur Dunia Bobby Fischer, diumumkan secara publik pada 19 Juni 1996 di Buenos Aires, Argentina. Ini mempekerjakan papan dan potongan yang sama seperti catur standar; Namun, posisi awal dari potongan-potongan pada peringkat rumah pemain secara acak

Aturan

  • Bidak putih ditempatkan di peringkat kedua seperti dalam catur standar
  • Semua potongan putih yang tersisa ditempatkan secara acak di peringkat pertama
  • Para uskup harus ditempatkan di bujur sangkar berwarna berlawanan
  • Raja harus ditempatkan di sebuah kotak di antara benteng.
  • Potongan Black ditempatkan sama dan berlawanan dengan White.

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

Untuk semua orang yang ingin memposting jawaban ...

Anda harus membuat generator posisi Chess960, yang mampu menghasilkan satu dari 960 posisi secara acak mengikuti aturan yang dijelaskan di atas (harus mampu mengeluarkan salah satu dari 960, hardcoding satu posisi tidak diterima!), dan Anda hanya perlu output peringkat putih satu potong.

Contoh output:

rkrbnnbq

dimana:

  • k raja
  • q ratu
  • b uskup
  • dan ksatria
  • rook

Ini akan menjadi kode golf, dan pemutus dasi akan menjadi upvotes.

jsedano
sumber
Ketika Anda mengatakan bahwa itu harus mampu menghasilkan salah satu dari posisi 960, apakah mereka harus dapat dilengkapi?
Peter Taylor
Menarik, saya belum benar-benar memikirkan itu ... Maksud saya idealnya seharusnya, saya pikir ... Jawabannya sejauh ini menawarkan kualitas ini, ... kan?
jsedano
Dua yang ditulis dalam bahasa yang memiliki builtin yang shuffle secara seragam lakukan; dua yang GolfScript dekat tetapi tidak cukup seragam.
Peter Taylor
Saya akan mengatakan bahwa penutupan cukup baik
jsedano
Pertanyaan ini mengilhami saya untuk bertanya codegolf.stackexchange.com/questions/12322/…
user123444555621

Jawaban:

6

GolfScript ( 49 48 karakter, atau 47 untuk output huruf besar)

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

Ini menggunakan teknik standar permutasi secara acak sampai kita memenuhi kriteria. Tidak seperti solusi GolfScript w0lf, ini tidak memeriksa string, sehingga cenderung berjalan melalui loop lebih sering.

Menggunakan huruf besar memungkinkan menyimpan satu karakter:

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

Ruby 1.9, 67 65 karakter

Ah, teknik "terus acak sampai Anda menghasilkan sesuatu yang valid" ...

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

(Di Ruby 2.0, %w(r r n n b b q k)bisa jadi 'rrnnbbqk'.chars)

Paul Prestidge
sumber
1
Di 1.9.3 Anda dapat menghemat ~dengan biaya peringatan, jika tersedia. pastebin.com/nuE9zWSw
manatwork
@manatwork itu bagus, terima kasih!
Paul Prestidge
2
teknik "terus acak sampai Anda menghasilkan sesuatu yang valid" masih jauh lebih cepat daripada teknik "acak daftar kemungkinan, saring dan ambil dulu" teknik yang cenderung dihasilkan bahasa murni seperti APL :-)
John Dvorak,
1
@ Dariero, itu yang menjadi $_variabelnya. Ia bekerja karena ruby ​​memiliki beberapa metode rapi seperti Kernel # chop yang berfungsi seperti metode String # chop yang setara tetapi dengan $_sebagai penerima. Ini menghemat banyak waktu ketika (misalnya) Anda menulis loop baca / proses / tulis menggunakan ruby -natau ruby -p.
Paul Prestidge
2
@GigaWatt no. Mantan cocok jika ada jumlah genap antara dua B. Yang terakhir hanya cocok jika B'S berada di ujung.
John Dvorak
8

GolfScript 60 49

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

(dipersingkat menjadi 49 karakter berkat kiat hebat Peter Taylor)

Tes online di sini .

Penjelasan kode:

;'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
sumber
1
Metode Anda untuk memeriksa bahwa ada sejumlah huruf di antara huruf bs tampaknya sangat panjang. Bagaimana dengan .'b'/1=,2%?
Peter Taylor
Dan Anda dapat menghindari upaya gagal dengan menarik 'qbbnnxxx'keluar dari loop dan perombakan string yang sama.
Peter Taylor
@PeterTaylor Terima kasih atas tipsnya. Untuk masalah "hitung antara 'b', saya merasa harus ada jalan yang lebih pendek, tetapi saya tidak bisa menemukannya.
Cristian Lupascu
4

J, 56 karakter

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

dibutuhkan beberapa detik pada mesin saya karena algoritma yang tidak efisien. Beberapa kecepatan mungkin diperoleh dengan menambahkan ~.(menghapus duplikat) sebelumnya 'kqbbnnrr'.

penjelasan:

  • ?~!8penawaran 8!elemen acak dari0 ... 8!
  • 'kqbbnnrr'A.~menggunakannya sebagai indeks anagram ke string kqbbnnrr.
  • (#~'...'&rxeq"1)' menyaringnya dengan regex dalam tanda kutip.
  • {. berarti "ambil elemen pertama"
John Dvorak
sumber
4

K, 69

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

Python, 105 karakter

Pada dasarnya teknik chron, minus barang-barang Ruby yang elegan.

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

Terima kasih kepada Peter Taylor untuk mempersingkat regex.

daniero
sumber
not s('b(..)*b',a)sepertinya cara bertele-tele s('b.(..)*b',a). Juga, samplemungkin satu karakter lebih pendek dari shuffle, tetapi memerlukan argumen tambahan.
Peter Taylor
Anda benar tentang regex, Peter. Terima kasih! Shufflekembali Nonemeskipun, jadi itu tidak baik :(
daniero
1
Merindukan hutan untuk pohon-pohon. Anda tidak perlu dua orregex , karena Anda memeriksa string yang sama dan setara dengan regex alternation ( |). Menghemat 13 karakter.
Peter Taylor
@PeterTaylor Tangkapan yang bagus! Terima kasih.
daniero