Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
12
Task/Generate-Chess960-starting-position/00DESCRIPTION
Normal file
12
Task/Generate-Chess960-starting-position/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
'''[[wp:Chess960|Chess960]]''' is a variant of chess created by world champion [[wp:Bobby Fisher|Bobby Fisher]]. Unlike other variants of the game, Chess960 does not require a different material, but instead relies on a random initial position, with a few constraints:
|
||||
|
||||
* as in the standard chess game, all eight white pawns must be placed on the second rank.
|
||||
* White pieces must stand on the first rank as in the standard game, in random column order but with the two following constraints:
|
||||
** the bishops must be placed on opposite color squares (i.e. they must be an odd number of spaces apart or there must be an even number of spaces between them)
|
||||
** the King must be between two rooks (with any number of other pieces between them all)
|
||||
* Black pawns and pieces must be placed respectively on the seventh and eighth ranks, mirroring the white pawns and pieces, just as in the standard game. (That is, their positions are not independently randomized.)
|
||||
|
||||
With those constraints there are 960 possible starting positions, thus the name of the variant.
|
||||
|
||||
;Task:
|
||||
The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed with [[wp:Chess symbols in Unicode|Chess symbols in Unicode: ♔♕♖♗♘]] or with the letters '''K'''ing '''Q'''ueen '''R'''ook '''B'''ishop k'''N'''ight.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
Loop, 5
|
||||
Out .= Chess960() "`n"
|
||||
MsgBox, % RTrim(Out, "`n")
|
||||
|
||||
Chess960() {
|
||||
P := {}
|
||||
P[K := Rand(2, 7)] := Chr(0x2654) ; King
|
||||
P[Rand(1, K - 1)] := Chr(0x2656) ; Rook 1
|
||||
P[Rand(K + 1, 8)] := Chr(0x2656) ; Rook 2
|
||||
Loop, 8
|
||||
Remaining .= P[A_Index] ? "" : A_Index "`n"
|
||||
Sort, Remaining, Random N
|
||||
P[Bishop1 := SubStr(Remaining, 1, 1)] := Chr(0x2657) ; Bishop 1
|
||||
Remaining := SubStr(Remaining, 3)
|
||||
Loop, Parse, Remaining, `n
|
||||
if (Mod(Bishop1 - A_LoopField, 2))
|
||||
Odd .= A_LoopField "`n"
|
||||
else
|
||||
Even .= A_LoopField "`n"
|
||||
X := StrSplit(Odd Even, "`n")
|
||||
P[X.1] := Chr(0x2657) ; Bishop 2
|
||||
P[X.2] := Chr(0x2655) ; Queen
|
||||
P[X.3] := Chr(0x2658) ; Knight 1
|
||||
P[X.4] := Chr(0x2658) ; Knight 2
|
||||
for Key, Val in P
|
||||
Out .= Val
|
||||
return Out
|
||||
}
|
||||
|
||||
Rand(Min, Max) {
|
||||
Random, n, Min, Max
|
||||
return n
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
using namespace std;
|
||||
class chess960
|
||||
{
|
||||
public:
|
||||
void generate( int c )
|
||||
{
|
||||
for( int x = 0; x < c; x++ )
|
||||
cout << startPos() << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
string startPos()
|
||||
{
|
||||
char p[8]; memset( p, 0, 8 );
|
||||
int b1, b2; bool q;
|
||||
|
||||
// bishops
|
||||
while( 1 )
|
||||
{
|
||||
b1 = rand() % 8; b2 = rand() % 8;
|
||||
if( !( b1 & 1 ) && b2 & 1 ) break;
|
||||
}
|
||||
p[b1] = 'B'; p[b2] = 'B';
|
||||
|
||||
// queen, knight, knight
|
||||
q = false;
|
||||
for( int x = 0; x < 3; x++ )
|
||||
{
|
||||
do
|
||||
{ b1 = rand() % 8; }
|
||||
while( p[b1] );
|
||||
if( !q )
|
||||
{ p[b1] = 'Q'; q = true; }
|
||||
else p[b1] = 'N';
|
||||
}
|
||||
|
||||
// rook king rook
|
||||
q = false;
|
||||
for( int x = 0; x < 3; x++ )
|
||||
{
|
||||
int a = 0;
|
||||
for( ; a < 8; a++ )
|
||||
if( !p[a] ) break;
|
||||
|
||||
if( !q )
|
||||
{ p[a] = 'R'; q = true; }
|
||||
else
|
||||
{ p[a] = 'K'; q = false; }
|
||||
}
|
||||
|
||||
string s;
|
||||
for( int x = 0; x < 8; x++ )
|
||||
s.append( 1, p[x] );
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
srand( time( NULL ) );
|
||||
chess960 c;
|
||||
c.generate( 10 );
|
||||
cout << "\n\n";
|
||||
return system( "pause" );
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
void main() {
|
||||
import std.stdio, std.range, std.algorithm, std.string, permutations2;
|
||||
|
||||
const pieces = "KQRrBbNN";
|
||||
alias I = indexOf;
|
||||
auto starts = pieces.dup.permutations.filter!(p =>
|
||||
I(p, 'B') % 2 != I(p, 'b') % 2 && // Bishop constraint.
|
||||
// King constraint.
|
||||
((I(p, 'r') < I(p, 'K') && I(p, 'K') < I(p, 'R')) ||
|
||||
(I(p, 'R') < I(p, 'K') && I(p, 'K') < I(p, 'r'))))
|
||||
.map!toUpper.array.sort().uniq;
|
||||
writeln(starts.walkLength, "\n", starts.front);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
void main() {
|
||||
import std.stdio, std.regex, std.range, std.algorithm, permutations2;
|
||||
|
||||
immutable pieces = "KQRRBBNN";
|
||||
immutable bish = r"B(|..|....|......)B";
|
||||
immutable king = r"R.*K.*R";
|
||||
auto starts3 = permutations(pieces.dup)
|
||||
.filter!(p => p.match(bish) && p.match(king))
|
||||
.array.sort().uniq;
|
||||
writeln(starts3.walkLength, "\n", starts3.front);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
void main() {
|
||||
import std.stdio, std.random, std.array, std.range;
|
||||
|
||||
// Subsequent order unchanged by insertions.
|
||||
auto start = "RKR".dup;
|
||||
foreach (immutable piece; "QNN")
|
||||
start.insertInPlace(uniform(0, start.length), piece);
|
||||
|
||||
immutable bishpos = uniform(0, start.length);
|
||||
start.insertInPlace(bishpos, 'B');
|
||||
start.insertInPlace(iota(bishpos % 2, start.length, 2)[uniform(0,$)], 'B');
|
||||
start.writeln;
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
type symbols struct{ k, q, r, b, n rune }
|
||||
|
||||
var A = symbols{'K', 'Q', 'R', 'B', 'N'}
|
||||
var W = symbols{'♔', '♕', '♖', '♗', '♘'}
|
||||
var B = symbols{'♚', '♛', '♜', '♝', '♞'}
|
||||
|
||||
var krn = []string{
|
||||
"nnrkr", "nrnkr", "nrknr", "nrkrn",
|
||||
"rnnkr", "rnknr", "rnkrn",
|
||||
"rknnr", "rknrn",
|
||||
"rkrnn"}
|
||||
|
||||
func (sym symbols) chess960(id int) string {
|
||||
var pos [8]rune
|
||||
q, r := id/4, id%4
|
||||
pos[r*2+1] = sym.b
|
||||
q, r = q/4, q%4
|
||||
pos[r*2] = sym.b
|
||||
q, r = q/6, q%6
|
||||
for i := 0; ; i++ {
|
||||
if pos[i] != 0 {
|
||||
continue
|
||||
}
|
||||
if r == 0 {
|
||||
pos[i] = sym.q
|
||||
break
|
||||
}
|
||||
r--
|
||||
}
|
||||
i := 0
|
||||
for _, f := range krn[q] {
|
||||
for pos[i] != 0 {
|
||||
i++
|
||||
}
|
||||
switch f {
|
||||
case 'k':
|
||||
pos[i] = sym.k
|
||||
case 'r':
|
||||
pos[i] = sym.r
|
||||
case 'n':
|
||||
pos[i] = sym.n
|
||||
}
|
||||
}
|
||||
return string(pos[:])
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(" ID Start position")
|
||||
for _, id := range []int{0, 518, 959} {
|
||||
fmt.Printf("%3d %s\n", id, A.chess960(id))
|
||||
}
|
||||
fmt.Println("\nRandom")
|
||||
for i := 0; i < 5; i++ {
|
||||
fmt.Println(W.chess960(rand.Intn(960)))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import Data.List
|
||||
import qualified Data.Set as Set
|
||||
|
||||
data Piece = K | Q | R | B | N deriving (Eq, Ord, Show)
|
||||
|
||||
isChess960 :: [Piece] -> Bool
|
||||
isChess960 rank =
|
||||
(odd . sum $ findIndices (== B) rank) && king > rookA && king < rookB
|
||||
where
|
||||
Just king = findIndex (== K) rank
|
||||
[rookA, rookB] = findIndices (== R) rank
|
||||
|
||||
main :: IO ()
|
||||
main = mapM_ (putStrLn . concatMap show) . Set.toList . Set.fromList
|
||||
. filter isChess960 $ permutations [R,N,B,Q,K,B,N,R]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
row0=: u: 9812+2}.5|i.10
|
||||
king=: u:9812
|
||||
rook=: u:9814
|
||||
bish=: u:9815
|
||||
pos=: I.@e.
|
||||
bishok=: 1=2+/ .| pos&bish
|
||||
rookok=: pos&rook -: (<./,>./)@pos&(rook,king)
|
||||
ok=: bishok*rookok
|
||||
perm=: A.&i.~ !
|
||||
valid=: (#~ ok"1) ~.row0{"1~perm 8
|
||||
gen=: valid {~ ? bind 960
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
gen''
|
||||
♘♗♖♔♗♕♖♘
|
||||
gen''
|
||||
♗♘♘♗♖♔♖♕
|
||||
gen''
|
||||
♖♗♔♘♘♕♗♖
|
||||
gen''
|
||||
♖♔♕♗♗♘♖♘
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Chess960{
|
||||
private static List<Character> pieces = Arrays.asList('R','B','N','Q','K','N','B','R');
|
||||
|
||||
public static List<Character> generateFirstRank(){
|
||||
do{
|
||||
Collections.shuffle(pieces);
|
||||
}while(!check(pieces.toString().replaceAll("[^\\p{Upper}]", ""))); //List.toString adds some human stuff, remove that
|
||||
|
||||
return pieces;
|
||||
}
|
||||
|
||||
private static boolean check(String rank){
|
||||
if(!rank.matches(".*R.*K.*R.*")) return false; //king between rooks
|
||||
if(!rank.matches(".*B(..|....|......|)B.*")) return false; //all possible ways bishops can be placed
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
for(int i = 0; i < 10; i++){
|
||||
System.out.println(generateFirstRank());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
class Chess960 {
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
Generate(10);
|
||||
}
|
||||
|
||||
function : Generate(c : Int) ~ Nil {
|
||||
for(x := 0; x < c; x += 1;) {
|
||||
StartPos()->PrintLine();
|
||||
};
|
||||
}
|
||||
|
||||
function : StartPos() ~ String {
|
||||
p := Char->New[8];
|
||||
|
||||
# bishops
|
||||
b1 : Int; b2 : Int;
|
||||
while(true) {
|
||||
b1 := GetPosition(); b2 := GetPosition();
|
||||
|
||||
b1c := b1 and 1; b2c := b2 and 1;
|
||||
c := b1c = 0 & b2c <> 0;
|
||||
if(c) {
|
||||
break;
|
||||
};
|
||||
};
|
||||
p[b1] := 0x2657; p[b2] := 0x2657;
|
||||
|
||||
# queen, knight, knight
|
||||
q := false;
|
||||
for(x := 0; x < 3; x += 1;) {
|
||||
do {
|
||||
b1 := GetPosition();
|
||||
} while( p[b1] <> '\0');
|
||||
|
||||
if(<>q) {
|
||||
p[b1] := 0x2655; q := true;
|
||||
}
|
||||
else {
|
||||
p[b1] := 0x2658;
|
||||
};
|
||||
};
|
||||
|
||||
# rook king rook
|
||||
q := false;
|
||||
for(x := 0; x < 3; x += 1;) {
|
||||
a := 0;
|
||||
while(a < 8) {
|
||||
if(p[a] = '\0') {
|
||||
break;
|
||||
};
|
||||
a += 1;
|
||||
};
|
||||
|
||||
if(<>q) {
|
||||
p[a] := 0x2656; q := true;
|
||||
}
|
||||
else {
|
||||
p[a] := 0x2654; q := false;
|
||||
};
|
||||
};
|
||||
|
||||
s := "";
|
||||
for(x := 0; x < 8; x += 1;) { s->Append(p[x]); };
|
||||
return s;
|
||||
}
|
||||
|
||||
function : GetPosition() ~ Int {
|
||||
return (Float->Random() * 1000)->As(Int) % 8;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
repeat until m/ '♗' [..]* '♗' / { $_ = < ♖ ♖ ♖ ♕ ♗ ♗ ♘ ♘ >.pick(*).join }
|
||||
s:2nd['♖'] = '♔';
|
||||
say .comb;
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
constant chess960 =
|
||||
map *.subst(:nth(2), /'♜'/, '♚'),
|
||||
grep rx/ '♝' [..]* '♝' /,
|
||||
< ♛ ♜ ♜ ♜ ♝ ♝ ♞ ♞ >.pick(*).join xx *;
|
||||
|
||||
.say for chess960[^10];
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
constant chess960 = eager
|
||||
.subst(:nth(2), /'♜'/, '♚')
|
||||
if / '♝' [..]* '♝' /
|
||||
for < ♛ ♜ ♜ ♜ ♝ ♝ ♞ ♞ >.permutations».join.uniq;
|
||||
|
||||
.say for chess960;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
sub insert(@a,$p,$e) { @a[^$p], $e, @a[$p..*] }
|
||||
|
||||
constant chess960 = eager gather for 0..3 -> $q {
|
||||
my @q = insert <♜ ♚ ♜>, $q, '♛';
|
||||
for 0 .. @q -> $n1 {
|
||||
my @n1 = insert @q, $n1, '♞';
|
||||
for $n1 ^.. @n1 -> $n2 {
|
||||
my @n2 = insert @n1, $n2, '♞';
|
||||
for 0 .. @n2 -> $b1 {
|
||||
my @b1 = insert @n2, $b1, '♝';
|
||||
for $b1+1, $b1+3 ...^ * > @b1 -> $b2 {
|
||||
my @b2 = insert @b1, $b2, '♝';
|
||||
take @b2.join;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CHECK { note "done compiling" }
|
||||
note +chess960;
|
||||
say chess960.pick;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
sub rnd($) { int(rand(shift)) }
|
||||
|
||||
sub empties { grep !$_[0][$_], 0 .. 7 }
|
||||
|
||||
sub chess960 {
|
||||
my @s = (undef) x 8;
|
||||
@s[2*rnd(4), 1 + 2*rnd(4)] = qw/B B/;
|
||||
|
||||
for (qw/Q N N/) {
|
||||
my @idx = empties \@s;
|
||||
$s[$idx[rnd(@idx)]] = $_;
|
||||
}
|
||||
|
||||
@s[empties \@s] = qw/R K R/;
|
||||
@s
|
||||
}
|
||||
print "@{[chess960]}\n" for 0 .. 10;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
(load "@lib/simul.l")
|
||||
|
||||
(seed (in "/dev/urandom" (rd 8)))
|
||||
|
||||
(loop
|
||||
(match
|
||||
'(@A B @B B @C)
|
||||
(shuffle '(Q B B N N 0 0 0)) )
|
||||
(NIL (bit? 1 (length @B))) )
|
||||
|
||||
(let Rkr '(R K R)
|
||||
(for I (append @A '(B) @B '(B) @C)
|
||||
(prin (if (=0 I) (pop 'Rkr) I)) )
|
||||
(prinl) )
|
||||
|
||||
(bye)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
>>> from itertools import permutations
|
||||
>>> pieces = 'KQRrBbNN'
|
||||
>>> starts = {''.join(p).upper() for p in permutations(pieces)
|
||||
if p.index('B') % 2 != p.index('b') % 2 # Bishop constraint
|
||||
and ( p.index('r') < p.index('K') < p.index('R') # King constraint
|
||||
or p.index('R') < p.index('K') < p.index('r') ) }
|
||||
>>> len(starts)
|
||||
960
|
||||
>>> starts.pop()
|
||||
'QNBRNKRB'
|
||||
>>>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
>>> import re
|
||||
>>> pieces = 'KQRRBBNN'
|
||||
>>> bish = re.compile(r'B(|..|....|......)B').search
|
||||
>>> king = re.compile(r'R.*K.*R').search
|
||||
>>> starts3 = {p for p in (''.join(q) for q in permutations(pieces))
|
||||
if bish(p) and king(p)}
|
||||
>>> len(starts3)
|
||||
960
|
||||
>>> starts3.pop()
|
||||
'QRNKBNRB'
|
||||
>>>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
from random import choice
|
||||
|
||||
def random960():
|
||||
start = ['R', 'K', 'R'] # Subsequent order unchanged by insertions.
|
||||
#
|
||||
for piece in ['Q', 'N', 'N']:
|
||||
start.insert(choice(range(len(start)+1)), piece)
|
||||
#
|
||||
bishpos = choice(range(len(start)+1))
|
||||
start.insert(bishpos, 'B')
|
||||
start.insert(choice(range(bishpos + 1, len(start) + 1, 2)), 'B')
|
||||
return start
|
||||
return ''.join(start).upper()
|
||||
|
||||
print(random960())
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
from random import choice
|
||||
|
||||
def generate960():
|
||||
start = ('R', 'K', 'R') # Subsequent order unchanged by insertions.
|
||||
|
||||
# Insert QNN in all combinations of places
|
||||
starts = {start}
|
||||
for piece in ['Q', 'N', 'N']:
|
||||
starts2 = set()
|
||||
for s in starts:
|
||||
for pos in range(len(s)+1):
|
||||
s2 = list(s)
|
||||
s2.insert(pos, piece)
|
||||
starts2.add(tuple(s2))
|
||||
starts = starts2
|
||||
|
||||
# For each of the previous starting positions insert the bishops in their 16 positions
|
||||
starts2 = set()
|
||||
for s in starts:
|
||||
for bishpos in range(len(s)+1):
|
||||
s2 = list(s)
|
||||
s2.insert(bishpos, 'B')
|
||||
for bishpos2 in range(bishpos+1, len(s)+2, 2):
|
||||
s3 = s2[::]
|
||||
s3.insert(bishpos2, 'B')
|
||||
starts2.add(tuple(s3))
|
||||
|
||||
return list(starts2)
|
||||
|
||||
gen = generate960()
|
||||
print(''.join(choice(gen)))
|
||||
1
Task/Generate-Chess960-starting-position/README
Normal file
1
Task/Generate-Chess960-starting-position/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Generate_Chess960_starting_position
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*REXX pgm generates a random starting position for the Chess960 game.*/
|
||||
parse arg seed . /*allow for (RAND) repeatability.*/
|
||||
if seed\=='' then call random ,,seed /*if SEED specified, use the seed*/
|
||||
@.=. /*define the (empty) first rank. */
|
||||
r1=random(1,8) /*generate the first rook, rank 1*/
|
||||
@.r1='R' /*place the first rook on rank1.*/
|
||||
do until r2\==r1 & r2\==r1-1 & r2\==r1+1
|
||||
r2=random(1,8) /*find placement for the 2nd rook*/
|
||||
end /*forever*/
|
||||
@.r2='r' /*place the second rook on rank 1*/
|
||||
_=random(min(r1, r2)+1, max(r1, r2)-1) /*find a random possition of king*/
|
||||
@._='K' /*place king between the 2 rooks.*/
|
||||
do _=0 ; b1=random(1,8); if @.b1\==. then iterate; c=b1//2
|
||||
do forever; b2=random(1,8) /* c=color of bishop ►──────┘ */
|
||||
if @.b2\==. | b2==b1 | b2//2==c then iterate /*bad position*/
|
||||
leave _ /*found position for the 2 clergy*/
|
||||
end /*forever*/ /* [↑] find a place: 1st bishop.*/
|
||||
end /* _ */ /* [↑] " " " 2nd " */
|
||||
@.b1='B' /*place the 1st bishop on rank1*/
|
||||
@.b2='b' /* " " 2nd " " " */
|
||||
/*place the two knights on rank 1*/
|
||||
do until @._='N'; _=random(1,8); if @._\==. then iterate; @._='N'; end
|
||||
do until @.!='n'; !=random(1,8); if @.!\==. then iterate; @.!='n'; end
|
||||
_= /*only the queen is left to place*/
|
||||
do i=1 for 8; _=_ || @.i; end /*construct output: first rank. */
|
||||
say translate(translate(_, 'q', .)) /*stick a fork in it, we're done.*/
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*REXX pgm generates all random starting positions for the Chess960 game*/
|
||||
parse arg seed . /*allow for (RAND) repeatability.*/
|
||||
if seed\=='' then call random ,,seed /*if SEED specified, use the seed*/
|
||||
x.=0; #=0
|
||||
|
||||
do t=1 /*═══════════════════════════════════════════════════════════════*/
|
||||
if t//1000==0 then say right(t,9) 'random generations: ' # " unique starting positions."
|
||||
@.=. /*define the (empty) first rank. */
|
||||
r1=random(1,8) /*generate the first rook, rank 1*/
|
||||
@.r1='R' /*place the first rook on rank1.*/
|
||||
do until r2\==r1 & r2\==r1-1 & r2\==r1+1
|
||||
r2=random(1,8) /*find placement for the 2nd rook*/
|
||||
end /*forever*/
|
||||
@.r2='r' /*place the second rook on rank 1*/
|
||||
_=random(min(r1, r2)+1, max(r1, r2)-1) /*find a random possition of king*/
|
||||
@._='K' /*place king between the 2 rooks.*/
|
||||
do _=0 ; b1=random(1,8); if @.b1\==. then iterate; c=b1//2
|
||||
do forever; b2=random(1,8) /* c=color of bishop ►──────┘ */
|
||||
if @.b2\==. | b2==b1 | b2//2==c then iterate /*bad position*/
|
||||
leave _ /*found position for the 2 clergy*/
|
||||
end /*forever*/ /* [↑] find a place: 1st bishop.*/
|
||||
end /* _ */ /* [↑] " " " 2nd " */
|
||||
@.b1='B' /*place the 1st bishop on rank1*/
|
||||
@.b2='b' /* " " 2nd " " " */
|
||||
/*place the two knights on rank 1*/
|
||||
do until @._='N'; _=random(1,8); if @._\==. then iterate; @._='N'; end
|
||||
do until @.!='n'; !=random(1,8); if @.!\==. then iterate; @.!='n'; end
|
||||
_= /*only the queen is left to place*/
|
||||
do i=1 for 8; _=_ || @.i; end /*construct output: first rank. */
|
||||
upper _ /*uppercase all the chess pieces.*/
|
||||
if x._ then iterate /*was this position found before?*/
|
||||
x._=1 /*define this position as found. */
|
||||
#=#+1 /*bump the unique positions found*/
|
||||
if #==960 then leave
|
||||
end /*t ══════════════════════════════════════════════════════════════*/
|
||||
|
||||
say # 'unique starting positions found after ' t "generations."
|
||||
/*stick a fork in it, we're done.*/
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#lang racket
|
||||
(define white (match-lambda ['P #\♙] ['R #\♖] ['B #\♗] ['N #\♘] ['Q #\♕] ['K #\♔]))
|
||||
(define black (match-lambda ['P #\♟] ['R #\♜] ['B #\♝] ['N #\♞] ['Q #\♛] ['K #\♚]))
|
||||
|
||||
(define (piece->unicode piece colour)
|
||||
(match colour ('w white) ('b black)) piece)
|
||||
|
||||
(define (find/set!-random-slot vec val k (f values))
|
||||
(define r (f (random k)))
|
||||
(cond
|
||||
[(vector-ref vec r)
|
||||
(find/set!-random-slot vec val k f)]
|
||||
[else
|
||||
(vector-set! vec r val)
|
||||
r]))
|
||||
|
||||
(define (chess960-start-position)
|
||||
(define v (make-vector 8 #f))
|
||||
;; Kings and Rooks
|
||||
(let ((k (find/set!-random-slot v (white 'K) 6 add1)))
|
||||
(find/set!-random-slot v (white 'R) k)
|
||||
(find/set!-random-slot v (white 'R) (- 7 k) (curry + k 1)))
|
||||
;; Bishops -- so far only three squares allocated, so there is at least one of each colour left
|
||||
(find/set!-random-slot v (white 'B) 4 (curry * 2))
|
||||
(find/set!-random-slot v (white 'B) 4 (compose add1 (curry * 2)))
|
||||
;; Everyone else
|
||||
(find/set!-random-slot v (white 'Q) 8)
|
||||
(find/set!-random-slot v (white 'N) 8)
|
||||
(find/set!-random-slot v (white 'N) 8)
|
||||
(list->string (vector->list v)))
|
||||
|
||||
(chess960-start-position)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
pieces = %i(♔ ♕ ♘ ♘ ♗ ♗ ♖ ♖)
|
||||
regexes = [/♗(..)*♗/, /♖.*♔.*♖/]
|
||||
row = pieces.shuffle.join until regexes.all?{|re| re.match(row)}
|
||||
puts row
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
row = [:♖, :♔, :♖]
|
||||
[:♕, :♘, :♘].each{|piece| row.insert(rand(row.size+1), piece)}
|
||||
[[0, 2, 4, 6].sample, [1, 3, 5, 7].sample].sort.each{|pos| row.insert(pos, :♗)}
|
||||
|
||||
puts row
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
KRN = %w(NNRKR NRNKR NRKNR NRKRN RNNKR RNKNR RNKRN RKNNR RKNRN RKRNN)
|
||||
|
||||
def chess960(id=rand(960))
|
||||
pos = Array.new(8)
|
||||
q, r = id.divmod(4)
|
||||
pos[r * 2 + 1] = "B"
|
||||
q, r = q.divmod(4)
|
||||
pos[r * 2] = "B"
|
||||
q, r = q.divmod(6)
|
||||
pos[pos.each_index.reject{|i| pos[i]}[r]] = "Q"
|
||||
krn = KRN[q].each_char
|
||||
pos.each_index {|i| pos[i] ||= krn.next}
|
||||
pos.join
|
||||
end
|
||||
|
||||
puts "Generate Start Position from id number"
|
||||
[0,518,959].each do |id|
|
||||
puts "%3d : %s" % [id, chess960(id)]
|
||||
end
|
||||
|
||||
puts "\nGenerate random Start Position"
|
||||
5.times {puts chess960}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
$ include "seed7_05.s7i";
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
var string: start is "RKR";
|
||||
var char: piece is ' ';
|
||||
var integer: pos is 0;
|
||||
begin
|
||||
for piece range "QNN" do
|
||||
pos := rand(1, succ(length(start)));
|
||||
start := start[.. pred(pos)] & str(piece) & start[pos ..];
|
||||
end for;
|
||||
pos := rand(1, succ(length(start)));
|
||||
start := start[.. pred(pos)] & "B" & start[pos ..];
|
||||
pos := succ(pos) + 2 * rand(0, (length(start) - pos) div 2);
|
||||
start := start[.. pred(pos)] & "B" & start[pos ..];
|
||||
writeln(start);
|
||||
end func;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package require struct::list
|
||||
|
||||
proc chess960 {} {
|
||||
while true {
|
||||
set pos [join [struct::list shuffle {N N B B R R Q K}] ""]
|
||||
if {[regexp {R.*K.*R} $pos] && [regexp {B(..)*B} $pos]} {
|
||||
return $pos
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# A simple renderer
|
||||
proc chessRender {position} {
|
||||
string map {P ♙ N ♘ B ♗ R ♖ Q ♕ K ♔} $position
|
||||
}
|
||||
|
||||
# Output multiple times just to show scope of positions
|
||||
foreach - {1 2 3 4 5} {puts [chessRender [chess960]]}
|
||||
Loading…
Add table
Add a link
Reference in a new issue