Chess960位置生成器


11

语境

Chess960(或Fischer Random Chess)是前世界象棋冠军Bobby Fischer发明和倡导的国际象棋变体,于1996年6月19日在阿根廷布宜诺斯艾利斯公开宣布。它采用与标准国际象棋相同的棋盘和棋子;但是,这些棋子在棋手本位上的起始位置是随机的

规则

  • 与标准国际象棋一样,白色棋子排在第二位
  • 所有剩余的白色棋子随机放置在第一等级
  • 主教必须放在相反颜色的正方形上
  • 国王必须放在车厢之间的正方形上。
  • 黑棋子的棋子与白棋子的棋子相同且相对。

来自:http : //en.wikipedia.org/wiki/Chess960

对于所有想发布答案的人...

您必须制作一个Chess960位置生成器,它能够按照上述规则随机生成960个位置中的一个(它必须能够输出960中的任何一个,不接受对一个位置进行硬编码!),并且您只需要输出白色等级一张。

输出示例:

rkrbnnbq

哪里:

  • 国王
  • 女王
  • b主教
  • n骑士
  • 鲁克

这将是代码高尔夫,而决胜局将是投票。


当您说它必须能够输出960个位置中的任何一个时,它们是否必须相等?
彼得·泰勒

有趣的是,我还没有真正想到这一点...我的意思是,理想情况下,我认为...到目前为止的答案提供了这种质量,...对吗?
jsedano 2013年

两者是用内建的语言统一编写的语言编写的;这两个GolfScript脚本很接近,但不太统一。
彼得·泰勒2013年

我会说接近就足够了
jsedano 2013年

Answers:


6

GolfScript(49个48个字符,大写输出为47个字符)

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

这使用随机排列的标准技术,直到我们满足标准为止。与w0lf的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 2013年

@manatwork太好了,谢谢!
Paul Prestidge

2
“纯随机化直到生成有效的东西”技术仍然比“洗牌可能性列表,过滤并优先使用”技术要快得多,纯技术(例如APL)往往会产生这种技术:-)
John Dvorak

1
@Daniero绝对是$_变量。之所以起作用,是因为ruby具有一些整洁的方法,例如Kernel#chop,它们的工作方式与等效的String#chop方法相同,但$_作为接收者使用。例如,当您使用ruby -n或编写读取/处理/写入循环时,这可以节省大量时间ruby -p
Paul Prestidge

2
@GigaWatt号 如果在两个B之间有偶数个字符,则前者匹配。后者仅在B'S位于末尾时才匹配。
John Dvorak 2013年

8

高尔夫脚本60 49

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

(由于Peter Taylor的出色技巧,缩短到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

1
您检查bs 之间是否有偶数个字母的方法似乎很长。怎么.'b'/1=,2%
彼得·泰勒2013年

您可以通过'qbbnnxxx'退出循环并重新排列同一字符串来避免丢弃失败的尝试。
彼得·泰勒2013年

@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)' 用正则表达式过滤引号。
  • {. 表示“采用第一个要素”

4

K,69

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

3

Python,105个字符

基本上是chron的技术,减去优雅的Ruby东西。

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)似乎是个long不休的说法s('b.(..)*b',a)。另外,它sample可能比短一个字符shuffle,但它需要一个额外的参数。
彼得·泰勒

彼得,您对正则表达式是正确的。谢谢!虽然Shuffle返回None,所以它不是很好:(
daniero

1
为树木错过了森林。您不需要两个正则表达式,因为您要检查相同的字符串,or并且等效于正则表达式交替(|)。节省13个字符。
彼得·泰勒

@PeterTaylor好抓住!谢谢。
daniero
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.