Chess960位置発生器


11

環境

Chess960(またはFischer Random Chess)は、アルゼンチンのブエノスアイレスで1996年6月19日に公に発表された元世界チェスチャンピオンのBobby Fischerによって発明され提唱されたチェスの変形です。標準のチェスと同じボードとピースを使用しています。ただし、プレイヤーのホームランクの駒の開始位置はランダム化されます

ルール

  • 標準のチェスのように、白いポーンは2番目のランクに配置されます
  • 残りのすべての白いピースは、最初のランクにランダムに配置されます
  • ビショップは反対色の正方形に配置する必要があります
  • 王はルークの間の広場に置かれなければなりません。
  • 黒のピースは白のピースと等しく反対に配置されます。

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

回答を投稿したいすべての人々のために...

上記のルールに従って960ポジションのいずれかをランダムに生成できるChess960ポジションジェネレーターを作成する必要があります(960のいずれかを出力できる必要があり、1ポジションをハードコーディングすることは受け入れられません!)白ランク1個を出力します。

出力例:

rkrbnnbq

どこ:

  • kキング
  • qクイーン
  • bビショップ
  • nナイト
  • ルーク

これはコードゴルフになり、タイブレーカーが賛成票になります。


960のポジションのいずれかを出力できる必要があると言うとき、それらは同等の確率である必要がありますか?
ピーターテイラー

興味深いことに、私はそれを本当に考えていませんでした...私は理想的にはそうあるべきだと思います...これまでの答えはこの品質を提供します...そうですか?
jsedano

シャッフルするビルトインを含む言語で書かれた2つは、2つのGolfScriptのものは近いですが、完全に均一ではありません。
ピーターテイラー

私は近いが良い十分であると言うだろう
jsedano

この質問は尋ねるために私にインスピレーションを与えcodegolf.stackexchange.com/questions/12322/...
user123444555621を

回答:


6

GolfScript(49 48文字、または大文字出力の場合は47文字)

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

これは、基準を満たすまでランダムに並べ替える標準的な手法を使用します。w0lfのGolfScriptソリューションとは異なり、これは文字列の両方のチェックを行うため、ループをより多く実行する可能性があります。

大文字を使用すると、1文字を保存できます。

'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のような純粋に関数型言語が生成する傾向がある「可能性のリストをシャッフルし、フィルターをかけて最初に取得する」手法よりもはるかに高速です:
John Dvorak

1
@Danieroそれは間違いなく$_変数です。rubyにはKernel#chopなどの適切なメソッドがあり、同等のString#chopメソッドと同じように機能し$_ますが、レシーバーとして機能するためです。(たとえば)ruby -nまたはを使用して読み取り/プロセス/書き込みループを作成している場合、これにより多くの時間を節約できますruby -p
ポール・プレスティッジ

2
@GigaWattいいえ 前者は、2つの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

1
の間に偶数個の文字があることを確認する方法bは非常に長いようです。どう.'b'/1=,2%
ピーターテイラー

そして'qbbnnxxx'、ループから抜け出し、同じ文字列を入れ替えることにより、失敗した試行の破棄を回避できます。
ピーターテイラー

@PeterTaylorすばらしいヒントをありがとう。「 'b's between count」問題については、もっと短い方法があるはずだと感じましたが、それを見つけることができませんでした。
クリスチャンルパスク

4

J、56文字

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

効率の悪いアルゴリズムのため、私のマシンでは数秒かかります。の~.前に(重複を削除する)を追加すると、ある程度の速度が得られ'kqbbnnrr'ます。

説明:

  • ?~!88!からランダムな要素を扱う0 ... 8!
  • 'kqbbnnrr'A.~文字列のアナグラムインデックスとして使用しますkqbbnnrr
  • (#~'...'&rxeq"1)' 引用符で囲んだ正規表現でフィルターします。
  • {. 「最初の要素を取る」という意味


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)長い言い方のようですs('b.(..)*b',a)。また、sampleは1文字より短い場合shuffleがありますが、追加の引数が必要です。
ピーターテイラー

あなたは正規表現について正しいです、ピーター。ありがとう!しかしShuffle戻りNoneますので、それは良くないです:(
daniero

1
木のために森を逃した。同じ文字列をチェックしており、or正規表現の代替(|)と同等であるため、2つの正規表現は必要ありません。13文字節約します。
ピーターテイラー

@PeterTaylor良いキャッチ!ありがとう。
ダニエロ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.