เครื่องกำเนิดตำแหน่งหมากรุก 960


11

บริบท

Chess960 (หรือหมากรุกสุ่มฟิชเชอร์) เป็นเกมหมากรุกที่คิดค้นและให้การสนับสนุนโดยอดีตแชมป์หมากรุกโลกบ๊อบบี้ฟิสเชอร์ประกาศเมื่อวันที่ 19 มิถุนายน 2539 ในบัวโนสไอเรสอาร์เจนตินา มันใช้บอร์ดเดียวกันและชิ้นส่วนเป็นหมากรุกมาตรฐาน แม้กระนั้นตำแหน่งเริ่มต้นของชิ้นส่วนในอันดับบ้านของผู้เล่นจะถูกสุ่ม

กฎระเบียบ

  • เบี้ยสีขาววางอยู่ในอันดับที่สองเช่นเดียวกับในหมากรุกมาตรฐาน
  • ชิ้นส่วนสีขาวที่เหลือทั้งหมดจะถูกวางแบบสุ่มในอันดับแรก
  • บิชอปจะต้องวางบนสี่เหลี่ยมสีตรงกันข้าม
  • จะต้องวางพระราชาบนสี่เหลี่ยมระหว่างเสา
  • ชิ้นส่วนของสีดำถูกวางอย่างเท่าเทียมกันและตรงข้ามกับชิ้นส่วนของสีขาว

จาก: http://en.wikipedia.org/wiki/Chess960

สำหรับทุกคนที่ต้องการโพสต์คำตอบ ...

คุณต้องสร้างตัวสร้างตำแหน่งหมากรุก 960 ซึ่งสามารถสร้างหนึ่งใน 960 ตำแหน่งตามกฎที่อธิบายไว้ข้างต้นโดยสุ่ม (ต้องสามารถส่งออก 960, ฮาร์ดโค้ดหนึ่งตำแหน่งไม่ได้รับการยอมรับ!) และคุณต้อง เอาท์พุทอันดับสีขาวหนึ่งชิ้น

ตัวอย่างผลลัพธ์:

rkrbnnbq

ที่อยู่:

  • กษัตริย์
  • ราชินี Q
  • b อธิการ
  • ไม่มีอัศวิน
  • r rook

นี่จะเป็นโค้ดกอล์ฟและไทเบรกเกอร์จะเป็นอัพวีท


เมื่อคุณบอกว่ามันต้องมีความสามารถในการส่งออกใด ๆ ของตำแหน่ง 960 พวกเขาจะต้องสวมใส่?
Peter Taylor

ที่น่าสนใจฉันไม่ได้คิดอย่างนั้นจริงๆ ... ฉันหมายความว่ามันควรจะเป็นอย่างนั้นจริง ๆ ฉันคิดว่า ... คำตอบที่ได้นั้นมีคุณภาพนี้ ... ใช่ไหม?
jsedano

สองซึ่งเขียนในภาษาที่มี builtins ที่สุ่มทำอย่างสม่ำเสมอ; GolfScript สองอันนั้นใกล้กัน แต่ไม่เหมือนกัน
Peter Taylor

ฉันจะบอกว่าใกล้ดีพอ
jsedano

คำถามนี้เป็นแรงบันดาลใจให้ฉันถามcodegolf.stackexchange.com/questions/12322/ …
123444555621

คำตอบ:


6

GolfScript ( 49 48 ตัวอักษรหรือ 47 สำหรับเอาต์พุตตัวพิมพ์ใหญ่)

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

สิ่งนี้ใช้เทคนิคมาตรฐานของการอนุญาตแบบสุ่มจนกว่าเราจะผ่านเกณฑ์ ซึ่งแตกต่างจากโซลูชัน GolfScript ของ w0lf ทั้งคู่ทำการตรวจสอบสตริงดังนั้นจึงมีแนวโน้มที่จะทำงานวนซ้ำได้มากกว่าเดิม

การใช้ตัวพิมพ์ใหญ่ช่วยให้ประหยัดหนึ่งอักขระ:

'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
จัดการ

@ การจัดการที่ดีขอบคุณ!
Paul Prestidge

2
เทคนิค "สุ่มแบบต่อเนื่องจนกว่าคุณจะสร้างสิ่งที่ถูกต้อง" ยังคงเร็วกว่า "สลับรายการความเป็นไปได้กรองและดำเนินการครั้งแรก" ซึ่งภาษาที่ใช้งานได้อย่างหมดจดเช่น APL มีแนวโน้มที่จะสร้าง :-)
John Dvorak

1
@Daniero นั่นคือสิ่งที่$_ตัวแปรแน่นอน มันใช้งานได้เพราะทับทิมมีวิธีที่เรียบร้อยเช่น Kernel # chop ที่ทำงานเหมือนกับวิธี String # chop ที่เทียบเท่ากัน แต่ใช้$_เป็นตัวรับ นี้ช่วยประหยัดเวลาได้มากเมื่อ (ตัวอย่าง) คุณกำลังเขียนอ่าน / กระบวนการ / ห่วงเขียนใช้หรือruby -n ruby -p
Paul Prestidge

2
@GigaWatt หมายเลข การแข่งขันในอดีตถ้ามีจำนวนตัวละครระหว่างสอง B บาง การแข่งขันหลังเท่านั้นถ้า B'S เป็นที่สิ้นสุด
John Dvorak

8

GolfScript 60 49

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

(ย่อให้เหลือ 49 ตัวอักษรเนื่องจากคำแนะนำที่ดีของ Peter Taylor)

การทดสอบแบบออนไลน์ที่นี่

คำอธิบายของรหัส:

;'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 ดูยาวมาก แล้วไง.'b'/1=,2%ล่ะ
Peter Taylor

และคุณสามารถหลีกเลี่ยงการละทิ้งความพยายามที่ล้มเหลวได้โดยการดึง'qbbnnxxx'ออกจากลูปและปรับสายอักขระเดียวกันใหม่
Peter Taylor

@PeterTaylor ขอบคุณสำหรับคำแนะนำที่ดี สำหรับปัญหา "การนับระหว่าง 'b' ฉันรู้สึกว่าควรมีวิธีที่สั้นกว่า แต่ฉันก็หาไม่เจอ
Cristian Lupascu

4

J, 56 ตัวอักษร

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

ใช้เวลาหลายวินาทีในเครื่องของฉันเนื่องจากอัลกอริทึมที่ไม่มีประสิทธิภาพ ความเร็วบางคนอาจจะได้รับโดยการเพิ่ม~.(ลบรายการที่ซ้ำ) 'kqbbnnrr'ก่อน

คำอธิบาย:

  • ?~!8ข้อเสนอ8!องค์ประกอบแบบสุ่มจาก0 ... 8!
  • 'kqbbnnrr'A.~kqbbnnrrใช้พวกเขาเป็นดัชนีแอนนาแกรมสตริง
  • (#~'...'&rxeq"1)' กรองพวกเขาโดย regex ในเครื่องหมายคำพูด
  • {. หมายถึง "ใช้องค์ประกอบแรก"


3

Python 105 ตัวอักษร

เทคนิคของ chron โดยพื้นฐานลบสิ่งทับทิมที่สง่างาม

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

ขอบคุณ Peter Taylor สำหรับการย่อให้สั้นลง


not s('b(..)*b',a)s('b.(..)*b',a)ดูเหมือนว่าวิธีที่ยืดยาวที่บอก นอกจากนี้sampleอาจเป็นอักขระหนึ่งตัวที่สั้นกว่าshuffleแต่ต้องการอาร์กิวเมนต์เพิ่มเติม
Peter Taylor

คุณถูกต้องเกี่ยวกับ regex ปีเตอร์ ขอบคุณ! แม้ว่าจะShuffleกลับมาNoneแต่ก็ไม่ดี :(
daniero

1
พลาดป่าเพื่อต้นไม้ คุณไม่จำเป็นต้องใช้สอง regexes เพราะคุณกำลังตรวจสอบสตริงเดียวกันและorเทียบเท่ากับการสับเปลี่ยน regex ( |) บันทึก 13 ตัวอักษร
Peter Taylor

@PeterTaylor จับได้ดีมาก! ขอบคุณ
daniero
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.