Chess960 pozisyon üreteci


11

bağlam

Chess960 (veya Fischer Rastgele Satranç) 19 Haziran 1996'da Arjantin, Buenos Aires'te kamuya açıklanan eski Dünya Satranç Şampiyonu Bobby Fischer tarafından icat edilen ve savunulan bir satranç çeşididir. Standart satranç ile aynı tahta ve parçaları kullanır; ancak, oyuncuların ev sıralamasında taşların başlangıç ​​pozisyonları rastgele seçilir

kurallar

  • Beyaz piyonlar standart satrançtaki gibi ikinci sıraya yerleştirilir
  • Kalan tüm beyaz parçalar rasgele birinci sıraya yerleştirilir
  • Piskoposlar karşıt renk karelere yerleştirilmelidir
  • Kral kaleler arasında bir kareye yerleştirilmelidir.
  • Siyah'ın parçaları Beyaz'ın parçalarına eşit ve karşıt olarak yerleştirilir.

Gönderen: http://en.wikipedia.org/wiki/Chess960

Cevap göndermek isteyen herkes için ...

yukarıda açıklanan kuralları takip ederek 960 pozisyondan birini rastgele üretebilen bir Chess960 pozisyon jeneratörü yapmalısınız (960'tan herhangi birini çıktılayabilmelidir, bir pozisyonu kodlamak kabul edilmez!) ve sadece beyaz rütbe bir adet çıktı.

Örnek çıktı:

rkrbnnbq

nerede:

  • k kral
  • q kraliçe
  • b fil
  • n şövalye
  • r kale

Bu kod golf olacak ve kravat kırıcı upvotes olacak.


960 pozisyonundan herhangi birini verebilmesi gerektiğini söylediğinizde, eşlenebilir olması gerekir mi?
Peter Taylor

İlginç, bunu gerçekten düşünmedim ... İdeal olarak olması gereken, sanırım ... Şimdiye kadar verilen cevaplar bu kaliteyi sunuyor, değil mi?
jsedano

Düzgün karıştırılmış yapılara sahip dillerde yazılmış olan ikisi; iki GolfScript biri birbirine yakındır ancak tam olarak aynı değildir.
Peter Taylor

Yakın olduğunu yeterince iyi söyleyebilirim
jsedano

Yanıtlar:


6

GolfScript ( 49 48 karakter veya büyük harf çıktı için 47)

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

Bu, kriterleri karşılayana kadar rastgele izin verme standart tekniğini kullanır. W0lf'in GolfScript çözümünün aksine, bu her iki dizeyi de denetler, bu nedenle döngüde daha fazla çalışma olasılığı vardır.

Büyük harf kullanmak, bir karakter kaydetmeyi sağlar:

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

8

Yakut 1.9, 67 65 karakter

Ah, eski "siz geçerli bir şey üretinceye kadar randomize etmeye devam edin" tekniği ...

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

(Ruby 2.0'da %w(r r n n b b q k)olabilir 'rrnnbbqk'.chars)


1
1.9.3 sürümünde, varsa, ~bir uyarı maliyetiyle yedekleyebilirsiniz . pastebin.com/nuE9zWSw
manatwork

@manatwork bu harika, teşekkürler!
Paul Prestidge

2
APL gibi tamamen işlevsel dillerin üretme eğiliminde olduğu "geçerli bir şey üretene kadar randomize olmaya devam et" tekniği hala "olasılıklar listesini karıştır, filtrele ve önce al" tekniğinden çok daha hızlı :-)
John Dvorak

1
@Daniero kesinlikle $_değişken budur. Ruby'nin eşdeğer String # chop yöntemi gibi ancak $_alıcısı olarak çalışan Kernel # chop gibi düzgün yöntemleri olduğu için çalışır . (Örneğin) ruby -nveya kullanarak bir okuma / işlem / yazma döngüsü yazdığınızda bu çok zaman kazandırır ruby -p.
Paul Prestidge

2
@GigaWatt no. İlk iki B arasında çift sayıda karakter varsa eşleşir. İkincisi sadece B'ler uçlarındaysa eşleşir.
John Dvorak

8

GolfScript 60 49

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

(Peter Taylor'ın harika ipuçları sayesinde 49 karaktere kısaltıldı)

Çevrimiçi test burada .

Kodun açıklaması:

;'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
bS arasında çift sayıda harf olup olmadığını kontrol etme yönteminiz çok uzun görünüyor. Nasıl .'b'/1=,2%?
Peter Taylor

Ayrıca 'qbbnnxxx'döngüden dışarı çekip aynı dizeyi yeniden karıştırarak başarısız girişimleri atmaktan kaçınabilirsiniz .
Peter Taylor

@PeterTaylor Harika ipuçları için teşekkür ederiz. "B'ler arasındaki sayım" sorunu için daha kısa bir yol olması gerektiğini hissettim, ama bulamadım.
Cristian Lupascu

4

J, 56 karakter

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

verimsiz algoritma nedeniyle makinemde birkaç saniye sürüyor. Daha ~.önce ekleyerek (kopyaları kaldır) biraz hız elde edilebilir 'kqbbnnrr'.

açıklama:

  • ?~!8fırsatları 8!rasgele elemanları0 ... 8!
  • 'kqbbnnrr'A.~bunları dizeye anagram dizinleri olarak kullanır kqbbnnrr.
  • (#~'...'&rxeq"1)' bunları normal ifadeye göre tırnak içine alır.
  • {. "ilk elemanı al" anlamına gelir

4

K, 69

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

3

Python, 105 karakter

Temelde chron tekniği, eksi zarif Ruby şeyler.

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

Regex'in kısalması için Peter Taylor'a teşekkürler.


not s('b(..)*b',a)uzun soluklu bir söylem yolu gibi görünüyor s('b.(..)*b',a). Ayrıca, samplebir karakterden daha kısa olabilir shuffle, ancak ekstra bir argüman gerektirir.
Peter Taylor

Normal ifade konusunda haklısın Peter. Teşekkürler! Yine de Shuffledöner None, bu yüzden iyi değil :(
daniero

1
Ormanlar için ormanı özledim. İki regex'e ihtiyacınız yoktur, çünkü aynı dizeyi kontrol edersiniz ve orregex alternation ( |) işlevine eşdeğerdir . 13 karakter kaydeder.
Peter Taylor

@PeterTaylor İyi yakalayın! Teşekkürler.
daniero
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.