The goal of this code-golf problem is to create a working Fischer-random chess starting position generator. What is Fischer-random chess exactly?

Chess960 (or Fischer Random Chess) is a variant of chess invented and advocated by former World Chess Champion Bobby Fischer, publicly announced on June 19, 1996 in Buenos Aires, Argentina. It employs the same board and pieces as standard chess; however, the starting position of the pieces on the players' home ranks is randomized.

Only very basic chess knowledge is required for this problem.

We will only be considering one side of the board, and only the first rank -- that is, the row that contains all of the important pieces rather than the pawns. In lowercase standard algebraic notation for a standard game of chess this would be represented as `rnbkqbnr`, where:

Notation Meaning
`k` King
`q` Queen
`r` Rook
`b` Bishop
`n` Knight

The only requirements of the problem are:

• The bishops must be placed on opposite-color squares
• The king must be placed on a square between the rooks

Example outputs:

``````rkrbnnbq
rbnqknbr
rbbkrnnq
``````

There are 960 different possible arrangements for the starting position of one side.

# Solution

I did this problem in `Ruby` and managed to get my solution down to `133` bytes, see if you can beat it:

``````def f;a='rrbbnnkq';loop{return a if/.*r.*k.*r/=~a&&(0...a.size).find_all{|i|a[i,1]==?b}.inject(:+).odd?;a=a.chars.shuffle*''};end;p f

# INSTRUCTIONS
# Run the program from command line with `ruby file_name.rb`
``````

I tried an alternative solution based on representing the position as an array rather than a string but this added two more bytes, making it a `135` byte solution. Nevertheless, it was an interesting approach:

``````def f;a=%w(r r b b n n k q);loop{return a*''if a.size.times.select{|i|a[i]==?b}.inject(:+).odd?&&/.*r.*k.*r/=~a*'';a=a.shuffle};end;p f

# INSTRUCTIONS
# Run the program from command line with `ruby file_name.rb`
``````

# Testing

To test whether your solution actually gives correct results, you'll want to do something along the lines of:

``````def fischer
return String.new
end

positions = []
100_000.times do
positions << fischer
end

# INSTRUCTIONS
# This is how I've done it, but you can do it your own way:
# - Create an empty array
# - Use a loop to call the fischer-random generation method a large number of times (100,000+)
# - Add the result to the array
# - Find the number of unique elements in the array, it should be 960.

p positions.uniq.length
#=> 960
``````