Generate random chess position: Difference between revisions
m (fix typo) |
(Perl 6 solution) |
||
Line 10: | Line 10: | ||
No requirement is made regarding the probability distribution of your method, but your program should be able to span a reasonably representative sample of all possible positions. For instance, programs that would always generate positions with say five pieces on the board, or with kings on a corner, would not be considered truly random. |
No requirement is made regarding the probability distribution of your method, but your program should be able to span a reasonably representative sample of all possible positions. For instance, programs that would always generate positions with say five pieces on the board, or with kings on a corner, would not be considered truly random. |
||
=={{header|Perl 6}}== |
|||
<lang perl6>sub pick-FEN { |
|||
# First we chose how many pieces to place |
|||
my $n = (2..32).pick; |
|||
# Then we pick $n squares |
|||
my @n = (^64).pick($n); |
|||
# We try to find suitable king positions on non-adjacent squares. |
|||
# If we could not find any, we return recursively |
|||
return pick-FEN() unless |
|||
my @kings[2] = first -> [$a, $b] { $a !== $b && abs($a div 8 - $b div 8) | abs($a mod 8 - $b mod 8) > 1 }, (@n X @n); |
|||
# We make a list of pieces we can pick (apart from the kings) |
|||
my @pieces = <p P n N b B r R q Q>; |
|||
# We make a list of two king symbols to pick randomly a black or white king |
|||
my @k = <K k>.pick(*); |
|||
return (gather for ^64 -> $sq { |
|||
if $sq == @kings.any { take @k.shift } |
|||
elsif $sq == @n.any { |
|||
my $row = 7 - $sq div 8; |
|||
take |
|||
$row == 7 ?? @pieces.grep(none('P')).pick !! |
|||
$row == 0 ?? @pieces.grep(none('p')).pick !! |
|||
@pieces.pick; |
|||
} |
|||
else { take 'ø' } |
|||
}).rotor(8)».join».subst(/ø+/,{ .chars }, :g).join('/') ~ ' w - - 0 1'; |
|||
} |
|||
say pick-FEN();</lang> |
|||
{{out}} |
|||
<pre>q2n1n2/1Qpk3Q/1r3bP1/1b1b4/2pRBR2/4P1bN/2R3K1/N1r2rPB w - - 0 1</pre> |
Revision as of 12:13, 11 December 2015
The purpose of this task is to generate a random chess position in FEN format. The position does not have to be realistic or even balanced, but it must comply to the following rules:
- there is one and only one king of each color (one black king and one white king);
- the kings must not be placed on adjacent squares;
- there can not be any pawn in the promotion square (no white pawn in the eighth rank, and no black pawn in the first rank);
- including the kings, up to 32 pieces of either color can be placed. There is no requirement for material balance between sides; The picking of pieces does not have to comply to a regular chess set : there can be five knights, twenty rooks, whatever... as long as the total number of pieces do not exceed thirty-two.
- it is white's turn, it is assumed that both sides have lost castling rights and that there is no possibility for en passant (the FEN should thus end in w - - 0 1);
No requirement is made regarding the probability distribution of your method, but your program should be able to span a reasonably representative sample of all possible positions. For instance, programs that would always generate positions with say five pieces on the board, or with kings on a corner, would not be considered truly random.
Perl 6
<lang perl6>sub pick-FEN {
# First we chose how many pieces to place my $n = (2..32).pick;
# Then we pick $n squares my @n = (^64).pick($n);
# We try to find suitable king positions on non-adjacent squares. # If we could not find any, we return recursively return pick-FEN() unless my @kings[2] = first -> [$a, $b] { $a !== $b && abs($a div 8 - $b div 8) | abs($a mod 8 - $b mod 8) > 1 }, (@n X @n);
# We make a list of pieces we can pick (apart from the kings)
my @pieces =
; # We make a list of two king symbols to pick randomly a black or white king my @k = <K k>.pick(*); return (gather for ^64 -> $sq { if $sq == @kings.any { take @k.shift } elsif $sq == @n.any { my $row = 7 - $sq div 8; take $row == 7 ?? @pieces.grep(none('P')).pick !! $row == 0 ?? @pieces.grep(none('p')).pick !! @pieces.pick; } else { take 'ø' } }).rotor(8)».join».subst(/ø+/,{ .chars }, :g).join('/') ~ ' w - - 0 1'; } say pick-FEN();</lang>
- Output:
q2n1n2/1Qpk3Q/1r3bP1/1b1b4/2pRBR2/4P1bN/2R3K1/N1r2rPB w - - 0 1