38 lines
1.5 KiB
Text
38 lines
1.5 KiB
Text
fcn pickFEN{
|
|
# First we chose how many pieces to place: 2 to 32
|
|
n := (0).random(2,33);
|
|
|
|
# Then we pick $n squares: first n of shuffle (0,1,2,3...63)
|
|
n = [0..63].walk().shuffle()[0,n];
|
|
|
|
# We try to find suitable king positions on non-adjacent squares.
|
|
# If we could not find any, we return recursively
|
|
kings := Walker.cproduct(n,n).filter1(fcn([(a,b)]){ // Cartesian product
|
|
a!=b and (a/8 - b/8).abs() or (a%8 - b%8).abs()>1
|
|
}); # (a,b) on success, False on fail
|
|
if(not kings) return(pickFEN()); // tail recursion
|
|
|
|
# We make a list of pieces we can pick (apart from the kings)
|
|
pieces,pnp,pnP := "p P n N b B r R q Q".split(" "), pieces-"p", pieces-"P";
|
|
|
|
# We make a list of two king symbols to pick randomly a black or white king
|
|
k := "K k".split(" ").shuffle();
|
|
|
|
[0..63].apply('wrap(sq){ # look at each square
|
|
if(kings.holds(sq)) k.pop();
|
|
else if(n.holds(sq)){
|
|
row,n,n2 := 7 - sq/8, (0).random(pieces.len()), (0).random(pnp.len());
|
|
if( row == 7) pnP[n2] // no white pawn in the promotion square
|
|
else if(row == 0) pnp[n2] // no black pawn in the promotion square
|
|
else pieces[n] // otherwise, any ole random piece
|
|
}
|
|
else "#" // empty square
|
|
})
|
|
.pump(List,T(Void.Read,7),"".append,subst) // chunkize into groups of 8 chars (1 row)
|
|
.concat("/") + " w - - 0 1"
|
|
}
|
|
fcn subst(str){ // replace "#" with count of #s
|
|
re :=RegExp("#+");
|
|
while(re.search(str,1)){ n,m:=re.matched[0]; str=String(str[0,n],m,str[n+m,*]) }
|
|
str
|
|
}
|