Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Generate-random-chess-position/00-META.yaml
Normal file
2
Task/Generate-random-chess-position/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Generate_random_chess_position
|
||||
17
Task/Generate-random-chess-position/00-TASK.txt
Normal file
17
Task/Generate-random-chess-position/00-TASK.txt
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
;Task:
|
||||
Generate a random chess position in [[wp:Forsyth–Edwards Notation|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's assumed that both sides have lost castling rights and that there is no possibility for ''en passant'' (the FEN should thus end in <tt>w - - 0 1</tt>).
|
||||
|
||||
|
||||
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.
|
||||
<br><br>
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
V board = [[‘ ’] * 8] * 8
|
||||
V piece_list = [‘R’, ‘N’, ‘B’, ‘Q’, ‘P’]
|
||||
|
||||
F place_kings(&brd)
|
||||
L
|
||||
V (rank_white, file_white, rank_black, file_black) = (random:(0 .. 7), random:(0 .. 7), random:(0 .. 7), random:(0 .. 7))
|
||||
V diff_list = [abs(rank_white - rank_black), abs(file_white - file_black)]
|
||||
I sum(diff_list) > 2 | Set(diff_list) == Set([0, 2])
|
||||
(brd[rank_white][file_white], brd[rank_black][file_black]) = (Char(‘K’), Char(‘k’))
|
||||
L.break
|
||||
|
||||
F pawn_on_promotion_square(pc, pr)
|
||||
I pc == ‘P’ & pr == 0
|
||||
R 1B
|
||||
E I pc == ‘p’ & pr == 7
|
||||
R 1B
|
||||
R 0B
|
||||
|
||||
F populate_board(&brd, wp, bp)
|
||||
L(x) 2
|
||||
Int piece_amount
|
||||
[Char] pieces
|
||||
I x == 0
|
||||
piece_amount = wp
|
||||
pieces = :piece_list
|
||||
E
|
||||
piece_amount = bp
|
||||
pieces = :piece_list.map(s -> s.lowercase())
|
||||
L piece_amount != 0
|
||||
V (piece_rank, piece_file) = (random:(0 .. 7), random:(0 .. 7))
|
||||
V piece = random:choice(pieces)
|
||||
I brd[piece_rank][piece_file] == ‘ ’ & pawn_on_promotion_square(piece, piece_rank) == 0B
|
||||
brd[piece_rank][piece_file] = piece
|
||||
piece_amount--
|
||||
|
||||
F fen_from_board(brd)
|
||||
V fen = ‘’
|
||||
L(x) brd
|
||||
V n = 0
|
||||
L(y) x
|
||||
I y == ‘ ’
|
||||
n++
|
||||
E
|
||||
I n != 0
|
||||
fen ‘’= String(n)
|
||||
fen ‘’= y
|
||||
n = 0
|
||||
I n != 0
|
||||
fen ‘’= String(n)
|
||||
fen ‘’= I fen.count(‘/’) < 7 {‘/’} E ‘’
|
||||
fen ‘’= " w - - 0 1\n"
|
||||
R fen
|
||||
|
||||
V (piece_amount_white, piece_amount_black) = (random:(0 .. 15), random:(0 .. 15))
|
||||
place_kings(&board)
|
||||
populate_board(&board, piece_amount_white, piece_amount_black)
|
||||
print(fen_from_board(board))
|
||||
L(x) board
|
||||
print(‘[’x.map(c -> ‘'’c‘'’).join(‘, ’)‘]’)
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
DEFINE BOARDSIZE="64"
|
||||
DEFINE EMPTY="'."
|
||||
|
||||
BYTE FUNC AbsDist(BYTE a,b)
|
||||
IF a>b THEN RETURN (a-b) FI
|
||||
RETURN (b-a)
|
||||
|
||||
BYTE FUNC GetPiece(BYTE ARRAY board BYTE x,y)
|
||||
RETURN (board(x+y*8))
|
||||
|
||||
PROC PutPiece(BYTE ARRAY board BYTE x,y,piece)
|
||||
board(x+y*8)=piece
|
||||
RETURN
|
||||
|
||||
PROC PrintBoard(BYTE ARRAY board)
|
||||
BYTE i,j,c
|
||||
|
||||
FOR j=0 TO 7
|
||||
DO
|
||||
FOR i=0 TO 7
|
||||
DO
|
||||
c=GetPiece(board,i,j)
|
||||
Put(c)
|
||||
OD
|
||||
PutE()
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC Append(CHAR ARRAY s CHAR c)
|
||||
s(0)==+1
|
||||
s(s(0))=c
|
||||
RETURN
|
||||
|
||||
PROC ExportToFen(BYTE ARRAY board CHAR ARRAY fen)
|
||||
CHAR ARRAY s=" w - - 0 1"
|
||||
INT x,y
|
||||
BYTE count,p
|
||||
|
||||
fen(0)=0
|
||||
FOR y=0 TO 7
|
||||
DO
|
||||
x=0
|
||||
WHILE x<8
|
||||
DO
|
||||
count=0
|
||||
WHILE x<8 AND GetPiece(board,x,y)=EMPTY
|
||||
DO
|
||||
x==+1 count==+1
|
||||
OD
|
||||
IF count>0 THEN
|
||||
Append(fen,'0+count)
|
||||
ELSE
|
||||
p=GetPiece(board,x,y)
|
||||
Append(fen,p)
|
||||
x==+1
|
||||
FI
|
||||
OD
|
||||
IF y<7 THEN
|
||||
Append(fen,'/)
|
||||
FI
|
||||
OD
|
||||
|
||||
FOR x=1 TO s(0)
|
||||
DO
|
||||
Append(fen,s(x))
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC PutKings(BYTE ARRAY board)
|
||||
BYTE x1,y1,x2,y2
|
||||
DO
|
||||
x1=Rand(8) y1=Rand(8)
|
||||
x2=Rand(8) y2=Rand(8)
|
||||
IF AbsDist(x1,x2)>1 AND AbsDist(y1,y2)>1 THEN
|
||||
PutPiece(board,x1,y1,'K)
|
||||
PutPiece(board,x2,y2,'k)
|
||||
RETURN
|
||||
FI
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC PutPieces(BYTE ARRAY board CHAR ARRAY pieces)
|
||||
BYTE i,x,y,p
|
||||
|
||||
FOR i=1 TO pieces(0)
|
||||
DO
|
||||
p=pieces(i)
|
||||
DO
|
||||
x=Rand(8)
|
||||
IF p='P OR p='p THEN
|
||||
y=Rand(6)+1
|
||||
ELSE
|
||||
y=Rand(8)
|
||||
FI
|
||||
UNTIL GetPiece(board,x,y)=EMPTY
|
||||
OD
|
||||
PutPiece(board,x,y,p)
|
||||
OD
|
||||
RETURN
|
||||
|
||||
PROC Generate(BYTE ARRAY board CHAR ARRAY pieces)
|
||||
SetBlock(board,BOARDSIZE,EMPTY)
|
||||
PutKings(board)
|
||||
PutPieces(board,pieces)
|
||||
RETURN
|
||||
|
||||
PROC Test(CHAR ARRAY pieces)
|
||||
BYTE ARRAY board(BOARDSIZE)
|
||||
CHAR ARRAY fen(256)
|
||||
|
||||
Generate(board,pieces)
|
||||
PrintBoard(board)
|
||||
ExportToFen(board,fen)
|
||||
PrintE(fen) PutE()
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
Test("PPPPPPPPBBNNQRRppppppppbbnnqrr")
|
||||
Test("PPBNQRppbnqr")
|
||||
RETURN
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
class chessBoard {
|
||||
public:
|
||||
void generateRNDBoard( int brds ) {
|
||||
int a, b, i; char c;
|
||||
for( int cc = 0; cc < brds; cc++ ) {
|
||||
memset( brd, 0, 64 );
|
||||
std::string pieces = "PPPPPPPPNNBBRRQKppppppppnnbbrrqk";
|
||||
random_shuffle( pieces.begin(), pieces.end() );
|
||||
|
||||
while( pieces.length() ) {
|
||||
i = rand() % pieces.length(); c = pieces.at( i );
|
||||
while( true ) {
|
||||
a = rand() % 8; b = rand() % 8;
|
||||
if( brd[a][b] == 0 ) {
|
||||
if( c == 'P' && !b || c == 'p' && b == 7 ||
|
||||
( ( c == 'K' || c == 'k' ) && search( c == 'k' ? 'K' : 'k', a, b ) ) ) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
brd[a][b] = c;
|
||||
pieces = pieces.substr( 0, i ) + pieces.substr( i + 1 );
|
||||
}
|
||||
print();
|
||||
}
|
||||
}
|
||||
private:
|
||||
bool search( char c, int a, int b ) {
|
||||
for( int y = -1; y < 2; y++ ) {
|
||||
for( int x = -1; x < 2; x++ ) {
|
||||
if( !x && !y ) continue;
|
||||
if( a + x > -1 && a + x < 8 && b + y >-1 && b + y < 8 ) {
|
||||
if( brd[a + x][b + y] == c ) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void print() {
|
||||
int e = 0;
|
||||
for( int y = 0; y < 8; y++ ) {
|
||||
for( int x = 0; x < 8; x++ ) {
|
||||
if( brd[x][y] == 0 ) e++;
|
||||
else {
|
||||
if( e > 0 ) { std::cout << e; e = 0; }
|
||||
std::cout << brd[x][y];
|
||||
}
|
||||
}
|
||||
if( e > 0 ) { std::cout << e; e = 0; }
|
||||
if( y < 7 ) std::cout << "/";
|
||||
}
|
||||
std::cout << " w - - 0 1\n\n";
|
||||
|
||||
for( int y = 0; y < 8; y++ ) {
|
||||
for( int x = 0; x < 8; x++ ) {
|
||||
if( brd[x][y] == 0 ) std::cout << ".";
|
||||
else std::cout << brd[x][y];
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
char brd[8][8];
|
||||
};
|
||||
int main( int argc, char* argv[] ) {
|
||||
srand( ( unsigned )time( 0 ) );
|
||||
chessBoard c;
|
||||
c.generateRNDBoard( 2 );
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
typedef int bool;
|
||||
|
||||
char grid[8][8];
|
||||
|
||||
void placeKings() {
|
||||
int r1, r2, c1, c2;
|
||||
for (;;) {
|
||||
r1 = rand() % 8;
|
||||
c1 = rand() % 8;
|
||||
r2 = rand() % 8;
|
||||
c2 = rand() % 8;
|
||||
if (r1 != r2 && abs(r1 - r2) > 1 && abs(c1 - c2) > 1) {
|
||||
grid[r1][c1] = 'K';
|
||||
grid[r2][c2] = 'k';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void placePieces(const char *pieces, bool isPawn) {
|
||||
int n, r, c;
|
||||
int numToPlace = rand() % strlen(pieces);
|
||||
for (n = 0; n < numToPlace; ++n) {
|
||||
do {
|
||||
r = rand() % 8;
|
||||
c = rand() % 8;
|
||||
}
|
||||
while (grid[r][c] != 0 || (isPawn && (r == 7 || r == 0)));
|
||||
grid[r][c] = pieces[n];
|
||||
}
|
||||
}
|
||||
|
||||
void toFen() {
|
||||
char fen[80], ch;
|
||||
int r, c, countEmpty = 0, index = 0;
|
||||
for (r = 0; r < 8; ++r) {
|
||||
for (c = 0; c < 8; ++c) {
|
||||
ch = grid[r][c];
|
||||
printf("%2c ", ch == 0 ? '.' : ch);
|
||||
if (ch == 0) {
|
||||
countEmpty++;
|
||||
}
|
||||
else {
|
||||
if (countEmpty > 0) {
|
||||
fen[index++] = countEmpty + 48;
|
||||
countEmpty = 0;
|
||||
}
|
||||
fen[index++] = ch;
|
||||
}
|
||||
}
|
||||
if (countEmpty > 0) {
|
||||
fen[index++] = countEmpty + 48;
|
||||
countEmpty = 0;
|
||||
}
|
||||
fen[index++]= '/';
|
||||
printf("\n");
|
||||
}
|
||||
strcpy(fen + index, " w - - 0 1");
|
||||
printf("%s\n", fen);
|
||||
}
|
||||
|
||||
char *createFen() {
|
||||
placeKings();
|
||||
placePieces("PPPPPPPP", TRUE);
|
||||
placePieces("pppppppp", TRUE);
|
||||
placePieces("RNBQBNR", FALSE);
|
||||
placePieces("rnbqbnr", FALSE);
|
||||
toFen();
|
||||
}
|
||||
|
||||
int main() {
|
||||
srand(time(NULL));
|
||||
createFen();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
def hasNK(board, a, b)
|
||||
(-1..1).each do |g|
|
||||
(-1..1).each do |f|
|
||||
aa = a + f; bb = b + g
|
||||
if (0..7).includes?(aa) && (0..7).includes?(bb)
|
||||
p = board[aa + 8 * bb]
|
||||
return true if p == "K" || p == "k"
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
def generateBoard(board, pieces)
|
||||
pieces.each_char do |p|
|
||||
while true
|
||||
a = rand(8); b = rand(8)
|
||||
next if ( (b == 0 || b == 7) && (p == "P" || p == "p") ) ||
|
||||
( (p == "k" || p == "K") && hasNK(board, a, b) )
|
||||
break if board[a + b * 8] == '.'
|
||||
end
|
||||
board[a + b * 8] = p
|
||||
end
|
||||
end
|
||||
|
||||
pieces = "ppppppppkqrrbbnnPPPPPPPPKQRRBBNN"
|
||||
11.times do
|
||||
e = pieces.size - 1
|
||||
while e > 0
|
||||
p = rand(e); t = pieces[e]
|
||||
#pieces[e] = pieces[p]; pieces[p] = t; e -= 1 # in Ruby
|
||||
pieces = pieces.sub(e, pieces[p]) # in Crystal because
|
||||
pieces = pieces.sub(p, t); e -= 1 # strings immutable
|
||||
end
|
||||
end
|
||||
|
||||
# No 'nil' for Crystal arrays; use '.' for blank value
|
||||
board = Array.new(64, '.'); generateBoard(board, pieces)
|
||||
puts
|
||||
e = 0
|
||||
8.times do |j| row_j = j * 8
|
||||
8.times do |i|
|
||||
board[row_j + i ] == '.' ? (e += 1) :
|
||||
( (print(e); e = 0) if e > 0
|
||||
print board[row_j + i] )
|
||||
end
|
||||
(print(e); e = 0) if e > 0
|
||||
print("/") if j < 7
|
||||
end
|
||||
|
||||
print(" w - - 0 1\n")
|
||||
8.times do |j| row_j = j * 8
|
||||
8.times { |i| board[row_j + i] == '.' ? print(".") : print(board[row_j + i]) }
|
||||
puts
|
||||
end
|
||||
|
||||
# Simpler for same output
|
||||
8.times{ |row| puts board[row*8..row*8 + 7].join("") }
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
USING: combinators.short-circuit grouping io kernel math
|
||||
math.parser math.ranges math.vectors prettyprint random
|
||||
sequences sets splitting.monotonic strings ;
|
||||
IN: rosetta-code.random-chess-position
|
||||
|
||||
<PRIVATE
|
||||
|
||||
CONSTANT: pieces "RNBQBNRPPPPPPPPrnbqbnrpppppppp"
|
||||
CONSTANT: empty CHAR: .
|
||||
|
||||
: <empty-board> ( -- seq ) 64 [ empty ] "" replicate-as ;
|
||||
: empty-index ( seq -- n ) empty swap indices random ;
|
||||
: place ( seq elt n -- seq' ) rot [ set-nth ] keep ;
|
||||
|
||||
! return a list of indices that are adjacent to n
|
||||
: adj ( n -- seq )
|
||||
[ 1 - ] [ 1 + ] bi [a,b] { 8 8 8 } [ v- ] 2keep dupd v+
|
||||
append append ;
|
||||
|
||||
: rand-non-adjacent ( m -- n ) 64 <iota> swap adj diff random ;
|
||||
|
||||
: place-kings ( seq -- seq' )
|
||||
CHAR: K over empty-index [ place ] keep [ CHAR: k ] dip
|
||||
rand-non-adjacent place ;
|
||||
|
||||
: non-pawn ( seq elt -- seq' ) over empty-index place ;
|
||||
|
||||
! prevent placing of pawns in ranks 1 and 8
|
||||
: pawn ( seq elt -- seq' )
|
||||
over empty swap indices
|
||||
[ { [ 7 > ] [ 56 < ] } 1&& ] filter random place ;
|
||||
|
||||
: place-piece ( seq -- seq' )
|
||||
pieces random dup "Pp" member? [ pawn ] [ non-pawn ] if ;
|
||||
|
||||
PRIVATE>
|
||||
|
||||
|
||||
: position ( -- seq )
|
||||
<empty-board> place-kings 30 random [ place-piece ] times ;
|
||||
|
||||
: position. ( seq -- )
|
||||
[ 1string ] { } map-as 8 group simple-table. ;
|
||||
|
||||
: position>fen ( seq -- seq' )
|
||||
8 group [
|
||||
[ = ] monotonic-split
|
||||
[ dup first empty = [ length number>string ] when ]
|
||||
map concat
|
||||
] map "/" join "/ w - - 0 1" append ;
|
||||
|
||||
: random-chess-position-demo ( -- )
|
||||
position [ position. ] [ position>fen print ] bi ;
|
||||
|
||||
MAIN: random-chess-position-demo
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
Dim Shared As Byte grid(8, 8), r, c
|
||||
|
||||
Sub placeKings()
|
||||
Dim As Byte r1, r2, c1, c2
|
||||
|
||||
Do
|
||||
r1 = Int(Rnd*8)
|
||||
c1 = Int(Rnd*8)
|
||||
r2 = Int(Rnd*8)
|
||||
c2 = Int(Rnd*8)
|
||||
If (r1 <> r2 And Abs(r1 - r2) > 1 And Abs(c1 - c2) > 1) Then
|
||||
grid(r1, c1) = Asc("K")
|
||||
grid(r2, c2) = Asc("k")
|
||||
Return
|
||||
End If
|
||||
Loop
|
||||
End Sub
|
||||
|
||||
Sub placePieces(pieces As String, isPawn As Byte)
|
||||
Dim numToPlace As Byte = Int(Rnd*(Len(pieces)))
|
||||
|
||||
For n As Byte = 0 To numToPlace-1
|
||||
Do
|
||||
r = Int(Rnd*8)
|
||||
c = Int(Rnd*8)
|
||||
Loop Until(Not(grid(r, c) Or (isPawn And (r = 7 Or r = 0))))
|
||||
grid(r, c) = Asc(Mid(pieces, n, 1))
|
||||
Next n
|
||||
End Sub
|
||||
|
||||
Sub toFen()
|
||||
Dim As Byte ch, countEmpty = 0
|
||||
Dim As String fen
|
||||
|
||||
For r = 0 To 8-1
|
||||
For c = 0 To 8-1
|
||||
ch = grid(r, c)
|
||||
If ch <> 0 Then
|
||||
Print " " & Chr(ch);
|
||||
Else
|
||||
Print " .";
|
||||
End If
|
||||
If ch = 0 Then
|
||||
countEmpty += 1
|
||||
Else
|
||||
If countEmpty > 0 Then
|
||||
fen += Chr(countEmpty + 48)
|
||||
countEmpty = 0
|
||||
End If
|
||||
fen += Chr(ch)
|
||||
End If
|
||||
Next c
|
||||
If countEmpty > 0 Then
|
||||
fen += Chr(countEmpty + 48)
|
||||
countEmpty = 0
|
||||
End If
|
||||
fen += "/"
|
||||
Print
|
||||
Next r
|
||||
fen += " w - - 0 1"
|
||||
Print fen
|
||||
End Sub
|
||||
|
||||
Randomize Timer
|
||||
placeKings()
|
||||
placePieces("PPPPPPPP", True)
|
||||
placePieces("pppppppp", True)
|
||||
placePieces("RNBQBNR", False)
|
||||
placePieces("rnbqbnr", False)
|
||||
toFen()
|
||||
Sleep
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
begin globals
|
||||
short grid(8, 8) // 1-8
|
||||
end globals
|
||||
|
||||
|
||||
local fn PlaceKings
|
||||
short r1, r2, c1, c2
|
||||
|
||||
while (YES)
|
||||
r1 = rnd(8)
|
||||
c1 = rnd(8)
|
||||
r2 = rnd(8)
|
||||
c2 = rnd(8)
|
||||
if ( abs( r1 - r2 ) > 1 or abs( c1 - c2) > 1 )
|
||||
grid(r1, c1) = asc("K")
|
||||
grid(r2, c2) = asc("k")
|
||||
exit fn
|
||||
end if
|
||||
wend
|
||||
end fn
|
||||
|
||||
|
||||
local fn PlacePieces( pieces$ as Str255, isPawn as BOOL )
|
||||
short n, r, c, numToPlace
|
||||
|
||||
numToPlace = rnd( len$(pieces$) )
|
||||
for n = 1 to numToPlace
|
||||
do
|
||||
r = rnd(8)
|
||||
c = rnd(8)
|
||||
if isPawn == YES and mid$( pieces$, n, 1 ) == "p" and r = 8 then exit fn
|
||||
if isPawn == YES and mid$( pieces$, n, 1 ) == "P" and r = 1 then exit fn
|
||||
until not( ( grid(r, c) != 0 ) or ( isPawn and ( r == 8 or r == 1 ) ) )
|
||||
grid(r, c) = asc( mid$( pieces$, n, 1 ) )
|
||||
next
|
||||
end fn
|
||||
|
||||
|
||||
local fn ToFen
|
||||
Str255 fen$
|
||||
short ch, r, c, countEmpty = 0
|
||||
CFStringRef pieceStr
|
||||
|
||||
for r = 1 to 8
|
||||
for c = 1 to 8
|
||||
ch = grid(r, c)
|
||||
|
||||
select (ch)
|
||||
|
||||
case 107 : pieceStr = @" ♚" // Black King
|
||||
case 75 : pieceStr = @" ♔" // White King
|
||||
|
||||
case 112 : pieceStr = @" ♟" // Black Pawn
|
||||
case 80 : pieceStr = @" ♙" // White Pawn
|
||||
|
||||
case 114 : pieceStr = @" ♜" // Black Rook
|
||||
case 82 : pieceStr = @" ♖" // White Rook
|
||||
|
||||
case 110 : pieceStr = @" ♞" // Black Knight
|
||||
case 78 : pieceStr = @" ♘" // White Knight
|
||||
|
||||
case 98 : pieceStr = @" ♝" // Black Bishop
|
||||
case 66 : pieceStr = @" ♗" // White Bishop
|
||||
|
||||
case 113 : pieceStr = @" ♛" // Black Queen
|
||||
case 81 : pieceStr = @" ♕" // White Queen
|
||||
|
||||
end select
|
||||
|
||||
if ( ch )
|
||||
print pieceStr,
|
||||
else
|
||||
print @" .",
|
||||
end if
|
||||
if ( ch == 0 )
|
||||
countEmpty++
|
||||
else
|
||||
if ( countEmpty > 0 )
|
||||
fen$ = fen$ + chr$(countEmpty + 48)
|
||||
countEmpty = 0
|
||||
end if
|
||||
fen$ = fen$ + chr$(ch)
|
||||
end if
|
||||
next
|
||||
if ( countEmpty > 0 )
|
||||
fen$ = fen$ + chr$(countEmpty + 48)
|
||||
countEmpty = 0
|
||||
end if
|
||||
fen$ = fen$ + "/"
|
||||
print
|
||||
next
|
||||
fen$ = fen$ + " w - - 0 1"
|
||||
fen$ = mid$( fen$, 8, len$(fen$) )
|
||||
print
|
||||
text @"Menlo", 14, fn ColorText, fn ColorClear, NSTextAlignmentLeft, 10
|
||||
print fen$
|
||||
end fn
|
||||
|
||||
local fn CreateFen
|
||||
fn PlaceKings
|
||||
fn PlacePieces( "PPPPPPPP", YES )
|
||||
fn PlacePieces( "pppppppp", YES )
|
||||
fn PlacePieces( "RNBQBNR", NO )
|
||||
fn PlacePieces( "rnbqbnr", NO )
|
||||
fn ToFen
|
||||
end fn
|
||||
|
||||
|
||||
randomize
|
||||
|
||||
window 1, @"Random Chess Position", ( 0, 0, 700, 400 )
|
||||
|
||||
text @"Menlo", 32, fn ColorText, fn ColorClear, NSTextAlignmentLeft, 10
|
||||
|
||||
fn CreateFen
|
||||
|
||||
HandleEvents
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var grid [8][8]byte
|
||||
|
||||
func abs(i int) int {
|
||||
if i >= 0 {
|
||||
return i
|
||||
} else {
|
||||
return -i
|
||||
}
|
||||
}
|
||||
|
||||
func createFen() string {
|
||||
placeKings()
|
||||
placePieces("PPPPPPPP", true)
|
||||
placePieces("pppppppp", true)
|
||||
placePieces("RNBQBNR", false)
|
||||
placePieces("rnbqbnr", false)
|
||||
return toFen()
|
||||
}
|
||||
|
||||
func placeKings() {
|
||||
for {
|
||||
r1 := rand.Intn(8)
|
||||
c1 := rand.Intn(8)
|
||||
r2 := rand.Intn(8)
|
||||
c2 := rand.Intn(8)
|
||||
if r1 != r2 && abs(r1-r2) > 1 && abs(c1-c2) > 1 {
|
||||
grid[r1][c1] = 'K'
|
||||
grid[r2][c2] = 'k'
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func placePieces(pieces string, isPawn bool) {
|
||||
numToPlace := rand.Intn(len(pieces))
|
||||
for n := 0; n < numToPlace; n++ {
|
||||
var r, c int
|
||||
for {
|
||||
r = rand.Intn(8)
|
||||
c = rand.Intn(8)
|
||||
if grid[r][c] == '\000' && !(isPawn && (r == 7 || r == 0)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
grid[r][c] = pieces[n]
|
||||
}
|
||||
}
|
||||
|
||||
func toFen() string {
|
||||
var fen strings.Builder
|
||||
countEmpty := 0
|
||||
for r := 0; r < 8; r++ {
|
||||
for c := 0; c < 8; c++ {
|
||||
ch := grid[r][c]
|
||||
if ch == '\000' {
|
||||
ch = '.'
|
||||
}
|
||||
fmt.Printf("%2c ", ch)
|
||||
if ch == '.' {
|
||||
countEmpty++
|
||||
} else {
|
||||
if countEmpty > 0 {
|
||||
fen.WriteString(strconv.Itoa(countEmpty))
|
||||
countEmpty = 0
|
||||
}
|
||||
fen.WriteByte(ch)
|
||||
}
|
||||
}
|
||||
if countEmpty > 0 {
|
||||
fen.WriteString(strconv.Itoa(countEmpty))
|
||||
countEmpty = 0
|
||||
}
|
||||
fen.WriteString("/")
|
||||
fmt.Println()
|
||||
}
|
||||
fen.WriteString(" w - - 0 1")
|
||||
return fen.String()
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
fmt.Println(createFen())
|
||||
}
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
{-# LANGUAGE LambdaCase, TupleSections #-}
|
||||
|
||||
module RandomChess
|
||||
( placeKings
|
||||
, placePawns
|
||||
, placeRemaining
|
||||
, emptyBoard
|
||||
, toFen
|
||||
, ChessBoard
|
||||
, Square (..)
|
||||
, BoardState (..)
|
||||
, getBoard
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Monad.State (State, get, gets, put)
|
||||
import Data.List (find, sortBy)
|
||||
import System.Random (Random, RandomGen, StdGen, random, randomR)
|
||||
|
||||
type Pos = (Char, Int)
|
||||
|
||||
type ChessBoard = [(Square, Pos)]
|
||||
|
||||
data PieceRank = King | Queen | Rook | Bishop | Knight | Pawn
|
||||
deriving (Enum, Bounded, Show, Eq, Ord)
|
||||
data PieceColor = Black | White
|
||||
deriving (Enum, Bounded, Show, Eq, Ord)
|
||||
|
||||
data Square = ChessPiece PieceRank PieceColor | EmptySquare
|
||||
deriving (Eq, Ord)
|
||||
|
||||
type PieceCount = [(Square, Int)]
|
||||
|
||||
data BoardState = BoardState { board :: ChessBoard , generator :: StdGen }
|
||||
|
||||
instance Show Square where
|
||||
show (ChessPiece King Black) = "♚"
|
||||
show (ChessPiece Queen Black) = "♛"
|
||||
show (ChessPiece Rook Black) = "♜"
|
||||
show (ChessPiece Bishop Black) = "♝"
|
||||
show (ChessPiece Knight Black) = "♞"
|
||||
show (ChessPiece Pawn Black) = "♟"
|
||||
show (ChessPiece King White) = "♔"
|
||||
show (ChessPiece Queen White) = "♕"
|
||||
show (ChessPiece Rook White) = "♖"
|
||||
show (ChessPiece Bishop White) = "♗"
|
||||
show (ChessPiece Knight White) = "♘"
|
||||
show (ChessPiece Pawn White) = "♙"
|
||||
show EmptySquare = " "
|
||||
|
||||
instance Random PieceRank where
|
||||
randomR (a, b) g = case randomR (fromEnum a, fromEnum b) g of
|
||||
(x, g'') -> (toEnum x, g'')
|
||||
random = randomR (minBound, maxBound)
|
||||
|
||||
instance Random PieceColor where
|
||||
randomR (a, b) g = case randomR (fromEnum a, fromEnum b) g of
|
||||
(x, g'') -> (toEnum x, g'')
|
||||
random = randomR (minBound, maxBound)
|
||||
|
||||
fullBoard :: PieceCount
|
||||
fullBoard =
|
||||
[ (ChessPiece King Black , 1)
|
||||
, (ChessPiece Queen Black , 1)
|
||||
, (ChessPiece Rook Black , 2)
|
||||
, (ChessPiece Bishop Black, 2)
|
||||
, (ChessPiece Knight Black, 2)
|
||||
, (ChessPiece Pawn Black , 8)
|
||||
, (ChessPiece King White , 1)
|
||||
, (ChessPiece Queen White , 1)
|
||||
, (ChessPiece Rook White , 2)
|
||||
, (ChessPiece Bishop White, 2)
|
||||
, (ChessPiece Knight White, 2)
|
||||
, (ChessPiece Pawn White , 8)
|
||||
, (EmptySquare , 32)
|
||||
]
|
||||
|
||||
emptyBoard :: ChessBoard
|
||||
emptyBoard = fmap (EmptySquare,) . (,) <$> ['a'..'h'] <*> [1..8]
|
||||
|
||||
replaceSquareByPos :: (Square, Pos) -> ChessBoard -> ChessBoard
|
||||
replaceSquareByPos e@(_, p) = fmap (\x -> if p == snd x then e else x)
|
||||
|
||||
isPosOccupied :: Pos -> ChessBoard -> Bool
|
||||
isPosOccupied p = occupied . find (\x -> p == snd x)
|
||||
where
|
||||
occupied (Just (EmptySquare, _)) = False
|
||||
occupied _ = True
|
||||
|
||||
isAdjacent :: Pos -> Pos -> Bool
|
||||
isAdjacent (x1, y1) (x2, y2) =
|
||||
let upOrDown = (pred y1 == y2 || succ y1 == y2)
|
||||
leftOrRight = (pred x1 == x2 || succ x1 == x2)
|
||||
in (x2 == x1 && upOrDown)
|
||||
|| (pred x1 == x2 && upOrDown)
|
||||
|| (succ x1 == x2 && upOrDown)
|
||||
|| (leftOrRight && y1 == y2)
|
||||
|
||||
fen :: Square -> String
|
||||
fen (ChessPiece King Black) = "k"
|
||||
fen (ChessPiece Queen Black) = "q"
|
||||
fen (ChessPiece Rook Black) = "r"
|
||||
fen (ChessPiece Bishop Black) = "b"
|
||||
fen (ChessPiece Knight Black) = "n"
|
||||
fen (ChessPiece Pawn Black) = "p"
|
||||
fen (ChessPiece King White) = "K"
|
||||
fen (ChessPiece Queen White) = "Q"
|
||||
fen (ChessPiece Rook White) = "R"
|
||||
fen (ChessPiece Bishop White) = "B"
|
||||
fen (ChessPiece Knight White) = "N"
|
||||
fen (ChessPiece Pawn White) = "P"
|
||||
|
||||
boardSort :: (Square, Pos) -> (Square, Pos) -> Ordering
|
||||
boardSort (_, (x1, y1)) (_, (x2, y2)) | y1 < y2 = GT
|
||||
| y1 > y2 = LT
|
||||
| y1 == y2 = compare x1 x2
|
||||
|
||||
toFen :: ChessBoard -> String
|
||||
toFen [] = " w - - 0 1" <> []
|
||||
toFen b = scanRow (fst <$> take 8 b) 0
|
||||
where
|
||||
scanRow [] 0 = nextRow
|
||||
scanRow [] n = show n <> nextRow
|
||||
scanRow (EmptySquare:xs) n = scanRow xs (succ n)
|
||||
scanRow (x:xs) 0 = nextPiece x xs
|
||||
scanRow (x:xs) n = show n <> nextPiece x xs
|
||||
nextRow = "/" <> toFen (drop 8 b)
|
||||
nextPiece x xs = fen x <> scanRow xs 0
|
||||
|
||||
-- State functions
|
||||
withStateGen :: (StdGen -> (a, StdGen)) -> State BoardState a
|
||||
withStateGen f = do
|
||||
currentState <- get
|
||||
let gen1 = generator currentState
|
||||
let (x, gen2) = f gen1
|
||||
put (currentState {generator = gen2})
|
||||
pure x
|
||||
|
||||
randomPos :: State BoardState Pos
|
||||
randomPos = do
|
||||
boardState <- gets board
|
||||
chr <- withStateGen (randomR ('a', 'h'))
|
||||
num <- withStateGen (randomR (1, 8))
|
||||
let pos = (chr, num)
|
||||
if isPosOccupied pos boardState then
|
||||
randomPos
|
||||
else
|
||||
pure pos
|
||||
|
||||
randomPiece :: State BoardState Square
|
||||
randomPiece = ChessPiece <$> withStateGen random <*> withStateGen random
|
||||
|
||||
placeKings :: State BoardState ()
|
||||
placeKings = do
|
||||
currentState <- get
|
||||
p1 <- randomPos
|
||||
p2 <- randomPos
|
||||
if p1 `isAdjacent` p2 || p1 == p2
|
||||
then placeKings
|
||||
else do
|
||||
let updatedBoard = replaceSquareByPos (ChessPiece King White, p1) $
|
||||
replaceSquareByPos (ChessPiece King Black, p2) (board currentState)
|
||||
put currentState { board = updatedBoard }
|
||||
|
||||
placePawns :: State BoardState ()
|
||||
placePawns = withStateGen (randomR (1, 16)) >>= go
|
||||
where
|
||||
go :: Int -> State BoardState ()
|
||||
go 0 = pure ()
|
||||
go n = do
|
||||
currentState <- get
|
||||
pos <- randomPos
|
||||
color <- withStateGen random
|
||||
let pawn = ChessPiece Pawn color
|
||||
let currentBoard = board currentState
|
||||
if promoted color == snd pos || isPosOccupied pos currentBoard ||
|
||||
enpassant color == snd pos || firstPos color == snd pos
|
||||
then go n
|
||||
else do
|
||||
put currentState { board = replaceSquareByPos (pawn, pos) currentBoard }
|
||||
go $ pred n
|
||||
promoted White = 8
|
||||
promoted Black = 1
|
||||
enpassant White = 5
|
||||
enpassant Black = 4
|
||||
firstPos White = 1
|
||||
firstPos Black = 8
|
||||
|
||||
placeRemaining :: State BoardState ()
|
||||
placeRemaining =
|
||||
withStateGen (randomR (5, sum $ fmap snd remaining)) >>= go remaining
|
||||
where
|
||||
remaining = filter (\case
|
||||
(ChessPiece King _, _) -> False
|
||||
(ChessPiece Pawn _, _) -> False
|
||||
(EmptySquare, _) -> False
|
||||
_ -> True)
|
||||
fullBoard
|
||||
|
||||
go :: PieceCount -> Int -> State BoardState ()
|
||||
go _ 0 = pure ()
|
||||
go remaining n = do
|
||||
currentState <- get
|
||||
let currentBoard = board currentState
|
||||
position <- randomPos
|
||||
piece <- randomPiece
|
||||
if not (isPermitted piece) || isPosOccupied position currentBoard
|
||||
then go remaining n
|
||||
else do
|
||||
let updatedBoard = replaceSquareByPos (piece, position) currentBoard
|
||||
put currentState { board = updatedBoard }
|
||||
go (consume piece remaining) (pred n)
|
||||
where
|
||||
isPermitted p =
|
||||
case find ((==p) . fst) remaining of
|
||||
Just (_, count) -> count > 0
|
||||
Nothing -> False
|
||||
consume p'' = fmap (\(p, c) -> if p == p'' then (p, pred c) else (p, c))
|
||||
|
||||
getBoard :: State BoardState ChessBoard
|
||||
getBoard = gets (sortBy boardSort . board)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
module Main where
|
||||
|
||||
import Control.Monad.State (evalState)
|
||||
import RandomChess (ChessBoard, emptyBoard, placeKings, getBoard,
|
||||
placePawns, placeRemaining, toFen, BoardState (..))
|
||||
import System.Random (newStdGen)
|
||||
|
||||
draw :: ChessBoard -> IO ()
|
||||
draw b = do
|
||||
showXAxis >> drawLine
|
||||
mapM_ (\b@(p, (x,y)) ->
|
||||
case x of 'h' -> putStr (" | " <> show p <> " | " <> show y <> "\n") >> drawLine
|
||||
'a' -> putStr (show y <> " | " <> show p)
|
||||
_ -> putStr (" | " <> show p)
|
||||
)
|
||||
b
|
||||
showXAxis >> putStrLn "" >> putStrLn (toFen b)
|
||||
|
||||
where
|
||||
drawLine = putStrLn (" " <> replicate 33 '-')
|
||||
showXAxis = do
|
||||
putStr " "
|
||||
mapM_ (\(_, (x, _)) -> putStr $ " " <> [x]) (take 8 b)
|
||||
putStrLn ""
|
||||
|
||||
main :: IO ()
|
||||
main = BoardState emptyBoard <$> newStdGen >>= draw . evalState buildBoard
|
||||
where
|
||||
buildBoard = placeKings >> placePawns >> placeRemaining >> getBoard
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
getlayout=:3 :0
|
||||
whilst. NB. first two positions are non-adjacent kings
|
||||
(0{pos) e. (1{pos)+(,-)1 7 8 9
|
||||
do.
|
||||
pos=: y?64
|
||||
end.
|
||||
)
|
||||
|
||||
randboard=:3 :0
|
||||
n=: ?30 NB. number of non-king pieces on board
|
||||
layout=: getlayout 2+n NB. where they go
|
||||
white=: 0 1,?n#2 NB. which ones are white?
|
||||
pawns=: 0 0,?n#2 NB. where are the pawns?
|
||||
pawns=: pawns * 1- white*layout e.56+i.8
|
||||
pawns=: pawns * 1-(1-white)*layout e.i.8
|
||||
ptyp=: 'pkqbjnPKQBJN'{~(6*white)+1 1,(1-2}.pawns)*2+?n#4
|
||||
8 8$ptyp layout}64#'.'
|
||||
)
|
||||
|
||||
NB. fen compress a line
|
||||
fen1=:3 :0
|
||||
for_n.8-i.8 do.
|
||||
y=. y rplc (#&'.';":) n
|
||||
end.
|
||||
)
|
||||
|
||||
NB. translate 8x8 board to fen notation
|
||||
NB. (just the task specific crippled fen)
|
||||
b2fen=:3 :0
|
||||
(}.;|.<@(('/',fen1)"1) y),' w - - 0 1'
|
||||
)
|
||||
|
||||
randfen=:b2fen@randboard
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
randfen''
|
||||
q6J/1pb1p1p1/1Jq2k2/4p1Pp/1pP5/1K2Bp2/5p2/1P4P1 w - - 0 1
|
||||
randfen''
|
||||
1Q3Q2/1Kn5/1PP5/2P5/2kNq1J1/7J/1P6/8 w - - 0 1
|
||||
randfen''
|
||||
8/8/7K/8/8/8/k7/8 w - - 0 1
|
||||
randfen''
|
||||
p4n2/1Q6/8/8/8/p4k1K/8/P5Qn w - - 0 1
|
||||
randfen''
|
||||
bk1q3J/8/1N4K1/N3P3/3BQ3/j1P3P1/7P/5jq1 w - - 0 1
|
||||
randfen''
|
||||
b1Q1Bb1J/j1N1PpK1/PpB1P1Pp/2pp2PN/3nnk2/3J4/P6P/1N2Qb1J w - - 0 1
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
import static java.lang.Math.abs;
|
||||
import java.util.Random;
|
||||
|
||||
public class Fen {
|
||||
static Random rand = new Random();
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(createFen());
|
||||
}
|
||||
|
||||
static String createFen() {
|
||||
char[][] grid = new char[8][8];
|
||||
|
||||
placeKings(grid);
|
||||
placePieces(grid, "PPPPPPPP", true);
|
||||
placePieces(grid, "pppppppp", true);
|
||||
placePieces(grid, "RNBQBNR", false);
|
||||
placePieces(grid, "rnbqbnr", false);
|
||||
|
||||
return toFen(grid);
|
||||
}
|
||||
|
||||
static void placeKings(char[][] grid) {
|
||||
int r1, c1, r2, c2;
|
||||
while (true) {
|
||||
r1 = rand.nextInt(8);
|
||||
c1 = rand.nextInt(8);
|
||||
r2 = rand.nextInt(8);
|
||||
c2 = rand.nextInt(8);
|
||||
if (r1 != r2 && abs(r1 - r2) > 1 && abs(c1 - c2) > 1)
|
||||
break;
|
||||
}
|
||||
grid[r1][c1] = 'K';
|
||||
grid[r2][c2] = 'k';
|
||||
}
|
||||
|
||||
static void placePieces(char[][] grid, String pieces, boolean isPawn) {
|
||||
int numToPlace = rand.nextInt(pieces.length());
|
||||
for (int n = 0; n < numToPlace; n++) {
|
||||
int r, c;
|
||||
do {
|
||||
r = rand.nextInt(8);
|
||||
c = rand.nextInt(8);
|
||||
|
||||
} while (grid[r][c] != 0 || (isPawn && (r == 7 || r == 0)));
|
||||
|
||||
grid[r][c] = pieces.charAt(n);
|
||||
}
|
||||
}
|
||||
|
||||
static String toFen(char[][] grid) {
|
||||
StringBuilder fen = new StringBuilder();
|
||||
int countEmpty = 0;
|
||||
for (int r = 0; r < 8; r++) {
|
||||
for (int c = 0; c < 8; c++) {
|
||||
char ch = grid[r][c];
|
||||
System.out.printf("%2c ", ch == 0 ? '.' : ch);
|
||||
if (ch == 0) {
|
||||
countEmpty++;
|
||||
} else {
|
||||
if (countEmpty > 0) {
|
||||
fen.append(countEmpty);
|
||||
countEmpty = 0;
|
||||
}
|
||||
fen.append(ch);
|
||||
}
|
||||
}
|
||||
if (countEmpty > 0) {
|
||||
fen.append(countEmpty);
|
||||
countEmpty = 0;
|
||||
}
|
||||
fen.append("/");
|
||||
System.out.println();
|
||||
}
|
||||
return fen.append(" w - - 0 1").toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
Array.prototype.shuffle = function() {
|
||||
for (let i = this.length - 1; i > 0; i--) {
|
||||
let j = Math.floor(Math.random() * (i + 1));
|
||||
[this[i], this[j]] = [this[j], this[i]];
|
||||
}
|
||||
}
|
||||
|
||||
function randomFEN() {
|
||||
|
||||
let board = [];
|
||||
for (let x = 0; x < 8; x++) board.push('. . . . . . . .'.split(' '));
|
||||
|
||||
function getRandPos() {
|
||||
return [Math.floor(Math.random() * 8), Math.floor(Math.random() * 8)];
|
||||
}
|
||||
|
||||
function isOccupied(pos) {
|
||||
return board[pos[0]][pos[1]] != '.';
|
||||
}
|
||||
|
||||
function isAdjacent(pos1, pos2) {
|
||||
if (pos1[0] == pos2[0] || pos1[0] == pos2[0]-1 || pos1[0] == pos2[0]+1)
|
||||
if (pos1[1] == pos2[1] || pos1[1] == pos2[1]-1 || pos1[1] == pos2[1]+1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// place kings
|
||||
let wk, bk;
|
||||
do { wk = getRandPos(); bk = getRandPos(); }
|
||||
while (isAdjacent(wk, bk));
|
||||
board[wk[0]][wk[1]] = 'K';
|
||||
board[bk[0]][bk[1]] = 'k';
|
||||
|
||||
// get peaces
|
||||
let peaces = [];
|
||||
let names = 'PRNBQ';
|
||||
function pick() {
|
||||
for (x = 1; x < Math.floor(Math.random() * 32); x++)
|
||||
peaces.push(names[Math.floor(Math.random() * names.length)]);
|
||||
}
|
||||
pick();
|
||||
names = names.toLowerCase();
|
||||
pick();
|
||||
peaces.shuffle();
|
||||
|
||||
// place peaces
|
||||
while (peaces.length > 0) {
|
||||
let p = peaces.shift(), pos;
|
||||
// paws: cannot be placed in bottom or top row
|
||||
if (p == 'p' || p == 'P')
|
||||
do { pos = getRandPos() }
|
||||
while (isOccupied(pos) || pos[0] == 0 || pos[0] == 7);
|
||||
// everything else
|
||||
else do { pos = getRandPos(); } while (isOccupied(pos));
|
||||
board[pos[0]][pos[1]] = p;
|
||||
}
|
||||
|
||||
// write FEN
|
||||
let fen = [];
|
||||
for (x = 0; x < board.length; x++) {
|
||||
let str ='', buf = 0;
|
||||
for (let y = 0; y < board[x].length; y++)
|
||||
if (board[x][y] == '.') buf++;
|
||||
else {
|
||||
if (buf > 0) { str += buf; buf = 0; }
|
||||
str += board[x][y];
|
||||
}
|
||||
if (buf > 0) str += buf;
|
||||
fen.push(str);
|
||||
}
|
||||
fen = fen.join('/') + ' w - - 0 1';
|
||||
console.table(board); // for demonstrating purpose
|
||||
return fen;
|
||||
}
|
||||
|
||||
// example
|
||||
console.log(randomFEN());
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
module Chess
|
||||
|
||||
using Printf
|
||||
|
||||
struct King end
|
||||
struct Pawn end
|
||||
|
||||
function placepieces!(grid, ::King)
|
||||
axis = axes(grid, 1)
|
||||
while true
|
||||
r1, c1, r2, c2 = rand(axis, 4)
|
||||
if r1 != r2 && abs(r1 - r2) > 1 && abs(c1 - c2) > 1
|
||||
grid[r1, c1] = '♚'
|
||||
grid[r2, c2] = '♔'
|
||||
return grid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function placepieces!(grid, ch)
|
||||
axis = axes(grid, 1)
|
||||
while true
|
||||
r, c = rand(axis, 2)
|
||||
if grid[r, c] == ' '
|
||||
grid[r, c] = ch
|
||||
return grid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function placepieces!(grid, ch, ::Pawn)
|
||||
axis = axes(grid, 1)
|
||||
while true
|
||||
r, c = rand(axis, 2)
|
||||
if grid[r, c] == ' ' && r ∉ extrema(axis)
|
||||
grid[r, c] = ch
|
||||
return grid
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function randposition!(grid)
|
||||
placepieces!(grid, King())
|
||||
foreach("♙♙♙♙♙♙♙♙♙♟♟♟♟♟♟♟♟") do ch
|
||||
placepieces!(grid, ch, Pawn())
|
||||
end
|
||||
foreach("♖♘♗♕♗♘♖♜♞♝♛♝♞♜") do ch
|
||||
placepieces!(grid, ch)
|
||||
end
|
||||
return grid
|
||||
end
|
||||
|
||||
printgrid(grid) = println(join((join(grid[r, :], ' ') for r in 1:size(grid, 1)), '\n'))
|
||||
|
||||
end # module Chess
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
grid = fill(' ', 8, 8)
|
||||
Chess.randposition!(grid)
|
||||
Chess.printgrid(grid)
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
// version 1.2.0
|
||||
|
||||
import java.util.Random
|
||||
import kotlin.math.abs
|
||||
|
||||
val rand = Random()
|
||||
|
||||
val grid = List(8) { CharArray(8) }
|
||||
|
||||
const val NUL = '\u0000'
|
||||
|
||||
fun createFen(): String {
|
||||
placeKings()
|
||||
placePieces("PPPPPPPP", true)
|
||||
placePieces("pppppppp", true)
|
||||
placePieces("RNBQBNR", false)
|
||||
placePieces("rnbqbnr", false)
|
||||
return toFen()
|
||||
}
|
||||
|
||||
fun placeKings() {
|
||||
while (true) {
|
||||
val r1 = rand.nextInt(8)
|
||||
val c1 = rand.nextInt(8)
|
||||
val r2 = rand.nextInt(8)
|
||||
val c2 = rand.nextInt(8)
|
||||
if (r1 != r2 && abs(r1 - r2) > 1 && abs(c1 - c2) > 1) {
|
||||
grid[r1][c1] = 'K'
|
||||
grid[r2][c2] = 'k'
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun placePieces(pieces: String, isPawn: Boolean) {
|
||||
val numToPlace = rand.nextInt(pieces.length)
|
||||
for (n in 0 until numToPlace) {
|
||||
var r: Int
|
||||
var c: Int
|
||||
do {
|
||||
r = rand.nextInt(8)
|
||||
c = rand.nextInt(8)
|
||||
}
|
||||
while (grid[r][c] != NUL || (isPawn && (r == 7 || r == 0)))
|
||||
grid[r][c] = pieces[n]
|
||||
}
|
||||
}
|
||||
|
||||
fun toFen(): String {
|
||||
val fen = StringBuilder()
|
||||
var countEmpty = 0
|
||||
for (r in 0..7) {
|
||||
for (c in 0..7) {
|
||||
val ch = grid[r][c]
|
||||
print ("%2c ".format(if (ch == NUL) '.' else ch))
|
||||
if (ch == NUL) {
|
||||
countEmpty++
|
||||
}
|
||||
else {
|
||||
if (countEmpty > 0) {
|
||||
fen.append(countEmpty)
|
||||
countEmpty = 0
|
||||
}
|
||||
fen.append(ch)
|
||||
}
|
||||
}
|
||||
if (countEmpty > 0) {
|
||||
fen.append(countEmpty)
|
||||
countEmpty = 0
|
||||
}
|
||||
fen.append("/")
|
||||
println()
|
||||
}
|
||||
return fen.append(" w - - 0 1").toString()
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println(createFen())
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
g = ConstantArray["", {8, 8}];
|
||||
While[Norm@First@Differences[r = RandomChoice[Tuples[Range[8], 2], 2]] <= Sqrt[2], Null];
|
||||
g = ReplacePart[g, {r[[1]] -> "K", r[[2]] -> "k"}];
|
||||
avail = Position[g, "", {2}];
|
||||
n = RandomInteger[{2, 14}];
|
||||
rls = Thread[RandomSample[avail, n] -> RandomChoice[Characters@"NBRQnbrq", n]];
|
||||
g = ReplacePart[g, rls];
|
||||
avail = RandomSample[DeleteCases[Position[g, "", {2}], {8, _}], RandomInteger[{2, 8}]];
|
||||
g = ReplacePart[g, Thread[avail -> "P"]];
|
||||
avail = RandomSample[DeleteCases[Position[g, "", {2}], {1, _}], RandomInteger[{2, 8}]];
|
||||
g = ReplacePart[g, Thread[avail -> "p"]];
|
||||
g //= Map[Split];
|
||||
g = g /. (x : {"" ..}) :> ToString[Length[x]];
|
||||
g //= Map[StringJoin@*Flatten];
|
||||
g = StringRiffle[Reverse[g], "/"];
|
||||
g = g <> " w - - 0 1";
|
||||
g
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import random
|
||||
|
||||
type
|
||||
|
||||
Piece {.pure.} = enum
|
||||
None
|
||||
WhiteBishop = ('B', "♗")
|
||||
WhiteKing = ('K', "♔")
|
||||
WhiteKnight = ('N', "♘")
|
||||
WhitePawn = ('P', "♙")
|
||||
WhiteQueen = ('Q', "♕")
|
||||
WhiteRook = ('R', "♖")
|
||||
BlackBishop = ('b', "♝")
|
||||
BlackKing = ('k', "♚")
|
||||
BlackKnight = ('n', "♞")
|
||||
BlackPawn = ('p', "♟")
|
||||
BlackQueen = ('q', "♛")
|
||||
BlackRook = ('r', "♜")
|
||||
|
||||
Color {.pure.} = enum White, Black
|
||||
|
||||
Grid = array[8, array[8, Piece]]
|
||||
|
||||
const
|
||||
# White pieces except king and pawns.
|
||||
WhitePieces = [WhiteQueen, WhiteRook, WhiteRook, WhiteBishop,
|
||||
WhiteBishop, WhiteKnight, WhiteKnight]
|
||||
|
||||
# Black pieces except king and pawns.
|
||||
BlackPieces = [BlackQueen, BlackRook, BlackRook, BlackBishop,
|
||||
BlackBishop, BlackKnight, BlackKnight]
|
||||
|
||||
proc placeKings(grid: var Grid) =
|
||||
while true:
|
||||
let r1 = rand(7)
|
||||
let c1 = rand(7)
|
||||
let r2 = rand(7)
|
||||
let c2 = rand(7)
|
||||
if r1 != r2 and abs(r1 - r2) > 1 and abs(c1 - c2) > 1:
|
||||
grid[r1][c1] = WhiteKing
|
||||
grid[r2][c2] = BlackKing
|
||||
break
|
||||
|
||||
proc placePawns(grid: var Grid; color: Color) =
|
||||
let piece = if color == White: WhitePawn else: BlackPawn
|
||||
let numToPlace = rand(8)
|
||||
for n in 0..<numToPlace:
|
||||
var r, c: int
|
||||
while true:
|
||||
r = rand(7)
|
||||
c = rand(7)
|
||||
if grid[r][c] == None and r notin {0, 7}: break
|
||||
grid[r][c] = piece
|
||||
|
||||
|
||||
proc placePieces(grid: var Grid; color: Color) =
|
||||
var pieces = if color == White: WhitePieces else: BlackPieces
|
||||
pieces.shuffle()
|
||||
let numToPlace = rand(7)
|
||||
for n in 0..<numToPlace:
|
||||
var r, c: int
|
||||
while true:
|
||||
r = rand(7)
|
||||
c = rand(7)
|
||||
if grid[r][c] == None: break
|
||||
grid[r][c] = pieces[n]
|
||||
|
||||
|
||||
proc toFen(grid: Grid): string =
|
||||
var countEmpty = 0
|
||||
for r in 0..7:
|
||||
for c in 0..7:
|
||||
let piece = grid[r][c]
|
||||
if piece == None:
|
||||
stdout.write " . "
|
||||
inc countEmpty
|
||||
else:
|
||||
stdout.write ' ' & $piece & ' '
|
||||
if countEmpty > 0:
|
||||
result.add $countEmpty
|
||||
countEmpty = 0
|
||||
result.add chr(ord(piece))
|
||||
|
||||
if countEmpty > 0:
|
||||
result.add $countEmpty
|
||||
countEmpty = 0
|
||||
|
||||
result.add '/'
|
||||
echo ""
|
||||
|
||||
result.add " w - - 0 1"
|
||||
|
||||
|
||||
proc createFen(): string =
|
||||
var grid: Grid
|
||||
grid.placeKings()
|
||||
grid.placePawns(White)
|
||||
grid.placePawns(Black)
|
||||
grid.placePieces(White)
|
||||
grid.placePieces(Black)
|
||||
result = grid.toFen()
|
||||
|
||||
|
||||
randomize()
|
||||
echo createFen()
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
use utf8;
|
||||
use List::AllUtils <shuffle any natatime>;
|
||||
|
||||
sub pick1 { return @_[rand @_] }
|
||||
|
||||
sub gen_FEN {
|
||||
my $n = 1 + int rand 31;
|
||||
my @n = (shuffle(0 .. 63))[1 .. $n];
|
||||
|
||||
my @kings;
|
||||
|
||||
KINGS: {
|
||||
for my $a (@n) {
|
||||
for my $b (@n) {
|
||||
next unless $a != $b && abs(int($a/8) - int($b/8)) > 1 || abs($a%8 - $b%8) > 1;
|
||||
@kings = ($a, $b);
|
||||
last KINGS;
|
||||
}
|
||||
die 'No good place for kings!';
|
||||
}
|
||||
}
|
||||
|
||||
my ($row, @pp);
|
||||
my @pieces = <p P n N b B r R q Q>;
|
||||
my @k = rand() < .5 ? <K k> : <k K>;
|
||||
|
||||
for my $sq (0 .. 63) {
|
||||
if (any { $_ == $sq } @kings) {
|
||||
push @pp, shift @k;
|
||||
}
|
||||
elsif (any { $_ == $sq } @n) {
|
||||
$row = 7 - int $sq / 8;
|
||||
push @pp,
|
||||
$row == 0 ? pick1(grep { $_ ne 'P' } @pieces)
|
||||
: $row == 7 ? pick1(grep { $_ ne 'P' } @pieces)
|
||||
: pick1(@pieces);
|
||||
}
|
||||
else {
|
||||
push @pp, 'ø';
|
||||
}
|
||||
}
|
||||
|
||||
my @qq;
|
||||
my $iter = natatime 8, @pp;
|
||||
while (my $row = join '', $iter->()) {
|
||||
$row =~ s/((ø)\2*)/length($1)/eg;
|
||||
push @qq, $row;
|
||||
}
|
||||
return join('/', @qq) . ' w - - 0 1';
|
||||
}
|
||||
|
||||
say gen_FEN();
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">show_bad_boards</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">board</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">fen</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">64</span> <span style="color: #008080;">by</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">empty</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span> <span style="color: #008080;">to</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">7</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">empty</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">empty</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">empty</span><span style="color: #0000FF;">+</span><span style="color: #008000;">'0'</span>
|
||||
<span style="color: #000000;">empty</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">empty</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">empty</span><span style="color: #0000FF;">+</span><span style="color: #008000;">'0'</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><</span><span style="color: #000000;">57</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'/'</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" w - - 0 1"</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">p15</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"pppppppprrnnbbq"</span>
|
||||
<span style="color: #000080;font-style:italic;">-- promote 0..8 pawns</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">8</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shuffle</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">kings_adjacent</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p12</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">row_diff</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)-</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">/</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)),</span>
|
||||
<span style="color: #000000;">col_diff</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)-</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">row_diff</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">col_diff</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">lp</span>
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_board</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d pieces\n%s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">lp</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">pieces</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Kk"</span><span style="color: #0000FF;">&</span> <span style="color: #000080;font-style:italic;">-- kings</span>
|
||||
<span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p15</span><span style="color: #0000FF;">())[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">16</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span> <span style="color: #000080;font-style:italic;">-- white</span>
|
||||
<span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p15</span><span style="color: #0000FF;">())[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">16</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- black</span>
|
||||
<span style="color: #000000;">lp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pieces</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">64</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shuffle</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">64</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lp</span> <span style="color: #008080;">do</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pieces</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">kings_adjacent</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">show_bad_boards</span> <span style="color: #008080;">then</span> <span style="color: #000000;">show_board</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"kings adjacent - reshuffle\n\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000080;font-style:italic;">-- check no pawn will be on a promotion square,
|
||||
-- and (above spec) no pawn has gone backwards:</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'p'</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">8</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">57</span><span style="color: #0000FF;">..</span><span style="color: #000000;">64</span><span style="color: #0000FF;">]))=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">show_bad_boards</span> <span style="color: #008080;">then</span> <span style="color: #000000;">show_board</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"pawn on rank 1/8 - reshuffle\n\n"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #000000;">show_board</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">fen</span><span style="color: #0000FF;">()})</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
(load "@lib/simul.l")
|
||||
(seed (in "/dev/urandom" (rd 8)))
|
||||
(de pieceN (P)
|
||||
(case P
|
||||
("p" 8)
|
||||
("q" 1)
|
||||
(T 2) ) )
|
||||
(de pieceset ()
|
||||
(let C 0
|
||||
(make
|
||||
(for P (conc (cons "p") (shuffle '("r" "n" "b" "q")))
|
||||
(let (X (pieceN P) N (rand 0 (+ X C)))
|
||||
(do N
|
||||
(link P) )
|
||||
(if (= P "p")
|
||||
(and
|
||||
(> X N)
|
||||
(inc 'C (- X N)) )
|
||||
(and
|
||||
(> N X)
|
||||
(dec 'C (- N X)) ) ) ) ) ) ) )
|
||||
(de neib (A)
|
||||
(let
|
||||
(X (/ (dec A) 8)
|
||||
Y (% (dec A) 8) )
|
||||
(filter
|
||||
'((N)
|
||||
(and
|
||||
(<= 1 N 64)
|
||||
(<=
|
||||
(abs (- (/ (dec N) 8) X))
|
||||
1 )
|
||||
(<=
|
||||
(abs (- (% (dec N) 8) Y))
|
||||
1 ) ) )
|
||||
(mapcar
|
||||
'((B) (+ B A))
|
||||
(-9 -8 -7 -1 1 7 8 9) ) ) ) )
|
||||
(setq *B (need 64 "."))
|
||||
(setq *P (conc (pieceset) (mapcar uppc (pieceset)) (cons "K")))
|
||||
(for P *P
|
||||
(loop
|
||||
(T
|
||||
(=
|
||||
"."
|
||||
(car
|
||||
(setq @@
|
||||
(nth
|
||||
*B
|
||||
(apply
|
||||
rand
|
||||
(if (or (= "p" P) (= "P" P))
|
||||
(9 56)
|
||||
(1 64) ) ) ) ) ) )
|
||||
(set @@ P) ) ) )
|
||||
(loop
|
||||
(T
|
||||
(and
|
||||
(=
|
||||
"."
|
||||
(car
|
||||
(setq @@ (nth *B (setq @@@ (rand 1 64)))) ) )
|
||||
(fully
|
||||
'((N) (<> "K" (get *B N)))
|
||||
(neib @@@) ) )
|
||||
(set @@ "k") ) )
|
||||
(setq *FEN
|
||||
(make
|
||||
(while *B
|
||||
(let (C 0 Lst (cut 8 '*B))
|
||||
(prinl Lst)
|
||||
(link
|
||||
(make
|
||||
(for L Lst
|
||||
(if (= L ".")
|
||||
(inc 'C)
|
||||
(and
|
||||
(gt0 C)
|
||||
(link (swap 'C 0)) )
|
||||
(link L) ) )
|
||||
(and
|
||||
(gt0 C)
|
||||
(link C) ) ) ) ) ) ) )
|
||||
(println (pack (glue "/" *FEN) " w - - 0 1"))
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import random
|
||||
|
||||
board = [[" " for x in range(8)] for y in range(8)]
|
||||
piece_list = ["R", "N", "B", "Q", "P"]
|
||||
|
||||
|
||||
def place_kings(brd):
|
||||
while True:
|
||||
rank_white, file_white, rank_black, file_black = random.randint(0,7), random.randint(0,7), random.randint(0,7), random.randint(0,7)
|
||||
diff_list = [abs(rank_white - rank_black), abs(file_white - file_black)]
|
||||
if sum(diff_list) > 2 or set(diff_list) == set([0, 2]):
|
||||
brd[rank_white][file_white], brd[rank_black][file_black] = "K", "k"
|
||||
break
|
||||
|
||||
def populate_board(brd, wp, bp):
|
||||
for x in range(2):
|
||||
if x == 0:
|
||||
piece_amount = wp
|
||||
pieces = piece_list
|
||||
else:
|
||||
piece_amount = bp
|
||||
pieces = [s.lower() for s in piece_list]
|
||||
while piece_amount != 0:
|
||||
piece_rank, piece_file = random.randint(0, 7), random.randint(0, 7)
|
||||
piece = random.choice(pieces)
|
||||
if brd[piece_rank][piece_file] == " " and pawn_on_promotion_square(piece, piece_rank) == False:
|
||||
brd[piece_rank][piece_file] = piece
|
||||
piece_amount -= 1
|
||||
|
||||
def fen_from_board(brd):
|
||||
fen = ""
|
||||
for x in brd:
|
||||
n = 0
|
||||
for y in x:
|
||||
if y == " ":
|
||||
n += 1
|
||||
else:
|
||||
if n != 0:
|
||||
fen += str(n)
|
||||
fen += y
|
||||
n = 0
|
||||
if n != 0:
|
||||
fen += str(n)
|
||||
fen += "/" if fen.count("/") < 7 else ""
|
||||
fen += " w - - 0 1\n"
|
||||
return fen
|
||||
|
||||
def pawn_on_promotion_square(pc, pr):
|
||||
if pc == "P" and pr == 0:
|
||||
return True
|
||||
elif pc == "p" and pr == 7:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def start():
|
||||
piece_amount_white, piece_amount_black = random.randint(0, 15), random.randint(0, 15)
|
||||
place_kings(board)
|
||||
populate_board(board, piece_amount_white, piece_amount_black)
|
||||
print(fen_from_board(board))
|
||||
for x in board:
|
||||
print(x)
|
||||
|
||||
#entry point
|
||||
start()
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
place_kings <- function(brd){
|
||||
###
|
||||
# Function that puts the two kings on the board
|
||||
# and makes sure that they are not adjacent
|
||||
###
|
||||
while (TRUE) {
|
||||
# generate positions for white and black kings
|
||||
rank_white <- sample(1:8, 1) ; file_white <- sample(1:8, 1)
|
||||
rank_black <- sample(1:8, 1) ; file_black <- sample(1:8, 1)
|
||||
# compute the differences between ranks and files
|
||||
diff_vec <- c(abs(rank_white - rank_black), abs(file_white - file_black))
|
||||
# if the two kings are not adjacent, place them on the board
|
||||
if (sum(diff_vec) > 2 | setequal(diff_vec, c(0,2))) {
|
||||
brd[rank_white, file_white] <- "K"
|
||||
brd[rank_black, file_black] <- "k"
|
||||
break
|
||||
}
|
||||
}
|
||||
return(brd)
|
||||
}
|
||||
|
||||
pawn_on_extreme_ranks <- function(pc, pr){
|
||||
###
|
||||
# Function that checks whether a pawn is on the first or eight rank
|
||||
# (such a situation is not possible in chess)
|
||||
###
|
||||
if (pc %in% c("P","p") & pr %in% c(1,8))
|
||||
return(TRUE)
|
||||
else
|
||||
return(FALSE)
|
||||
}
|
||||
|
||||
populate_board <- function(brd, wp, bp){
|
||||
###
|
||||
# Function that puts pieces on the board making sure that they
|
||||
# are not on the same squares, and verifying for pawn_on_extreme_ranks
|
||||
###
|
||||
# initialization
|
||||
piece_list <- c("P", "N", "B", "R", "Q")
|
||||
for (color in c("white", "black")){
|
||||
# iterate for white (first) and black (after) pieces
|
||||
if (color == "white"){
|
||||
n_pieces = wp
|
||||
pieces = piece_list
|
||||
}
|
||||
else {
|
||||
n_pieces = bp
|
||||
pieces = tolower(piece_list)
|
||||
}
|
||||
# place pieces one by one until we have them
|
||||
while (n_pieces != 0){
|
||||
piece_rank <- sample(1:8, 1) ; piece_file <- sample(1:8, 1)
|
||||
piece <- sample(pieces, 1)
|
||||
# check if square is empty and it is not a pawn on an extreme rank
|
||||
if (brd[piece_rank, piece_file] == " " & !pawn_on_extreme_ranks(piece, piece_rank)){
|
||||
brd[piece_rank, piece_file] <- piece
|
||||
n_pieces <- n_pieces - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return(brd)
|
||||
}
|
||||
|
||||
fen_from_board <- function(brd){
|
||||
###
|
||||
# Function that prints out the FEN of a given input board
|
||||
###
|
||||
# create vector of positions by row
|
||||
fen <- apply(brd, 1, function(x) {
|
||||
r <- rle(x)
|
||||
paste(ifelse(r$values == " ", r$lengths, r$values), collapse = "")
|
||||
})
|
||||
# paste them together with separator '/' and add the final string
|
||||
fen <- paste(paste(fen, collapse = "/"), "w - - 0 1")
|
||||
return(fen)
|
||||
}
|
||||
|
||||
generate_fen <- function(){
|
||||
###
|
||||
# This function calls all the functions above and generates
|
||||
# the board representation along with its FEN
|
||||
###
|
||||
# initialization
|
||||
board <- matrix(" ", nrow = 8, ncol = 8)
|
||||
# generate random amount of white and black pieces (kings excluded)
|
||||
n_pieces_white <- sample(0:31, 1) ; n_pieces_black <- sample(0:31, 1)
|
||||
# place kings on board
|
||||
board <- place_kings(board)
|
||||
# put other pieces on board
|
||||
board <- populate_board(board, wp = n_pieces_white, bp = n_pieces_black)
|
||||
# print board and FEN
|
||||
print(board)
|
||||
cat("\n")
|
||||
cat(fen_from_board(board))
|
||||
}
|
||||
|
||||
generate_fen()
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*REXX program generates a chess position (random pieces & positions) in a FEN format.*/
|
||||
parse arg seed CBs . /*obtain optional arguments from the CL*/
|
||||
if datatype(seed,'W') then call random ,,seed /*SEED given for RANDOM repeatability? */
|
||||
if CBs=='' | CBs=="," then CBs=1 /*CBs: number of generated ChessBoards*/
|
||||
/* [↓] maybe display any # of boards. */
|
||||
do boards=1 for abs(CBs) /* [↓] maybe display separator & title*/
|
||||
if sign(CBs)\==CBs then do; say; say center(' board' boards" ", 79, '▒'); end
|
||||
@.=.; !.=@. /*initialize the chessboard to be empty*/
|
||||
do p=1 for random(2, 32) /*generate a random number of chessmen.*/
|
||||
if p<3 then call piece 'k' /*a king of each color. */
|
||||
else call piece substr('bnpqr', random(1, 5), 1)
|
||||
end /*p*/ /* [↑] place a piece on the chessboard*/
|
||||
call cb /*display the ChessBoard and its FEN.*/
|
||||
end /*boards*/ /* [↑] CB ≡ ─ ─ */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
cb: fen=; do r=8 for 8 by -1; $= /*the board rank (so far).*/
|
||||
do f=8 for 8 by -1; $= $ || @.r.f /*append the board file. */
|
||||
end /*f*/
|
||||
say $ /*display the board rank. */
|
||||
do e=8 for 8 by -1; $= changestr( copies(., e), $, e) /* . ≡ filler.*/
|
||||
end /*e*/
|
||||
fen= fen || $ || left('/', r\==1) /*append / if not 1st rank.*/
|
||||
end /*r*/ /* [↑] append $ str to FEN*/
|
||||
say /*display a blank sep. line*/
|
||||
say 'FEN='fen "w - - 0 1" /*Forsyth─Edwards Notation.*/
|
||||
return /* [↑] display chessboard.*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
piece: parse arg x; if p//2 then upper x; arg ux /*use white if odd P.*/
|
||||
if CBs<0 & p>2 then if random(1) then upper x /*CBs>0? Use balanced.*/
|
||||
/*[↓] # isn't changed.*/
|
||||
do #=0 by 0; r= random(1, 8); f= random(1, 8) /*random rank and file.*/
|
||||
if @.r.f\==. then iterate /*is position occupied?*/
|
||||
if (x=='p' & r==1) | (x=="P" & r==8) then iterate /*any promoting pawn? */
|
||||
/*[↑] skip these pawns*/
|
||||
if ux=='K' then do rr=r-1 for 3 /*[↓] neighbor ≡ king?*/
|
||||
do ff=f-1 for 3; if !.rr.ff=='K' then iterate # /*king?*/
|
||||
end /*rr*/ /*[↑] neighbor ≡ king?*/
|
||||
end /*ff*/ /*[↑] we're all done. */
|
||||
@.r.f= x /*put random piece. */
|
||||
!.r.f= ux; return /* " " " upper*/
|
||||
end /*#*/ /*#: isn't incremented.*/
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
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();
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
def hasNK( board, a, b )
|
||||
for g in -1 .. 1
|
||||
for f in -1 .. 1
|
||||
aa = a + f; bb = b + g
|
||||
if aa.between?( 0, 7 ) && bb.between?( 0, 7 )
|
||||
p = board[aa + 8 * bb]
|
||||
if p == "K" || p == "k"; return true; end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
def generateBoard( board, pieces )
|
||||
while( pieces.length > 1 )
|
||||
p = pieces[pieces.length - 1]
|
||||
pieces = pieces[0...-1]
|
||||
while( true )
|
||||
a = rand( 8 ); b = rand( 8 )
|
||||
if ( ( b == 0 || b == 7 ) && ( p == "P" || p == "p" ) ) ||
|
||||
( ( p == "k" || p == "K" ) && hasNK( board, a, b ) ); next; end
|
||||
if board[a + b * 8] == nil; break;end
|
||||
end
|
||||
board[a + b * 8] = p
|
||||
end
|
||||
end
|
||||
pieces = "ppppppppkqrrbbnnPPPPPPPPKQRRBBNN"
|
||||
for i in 0 .. 10
|
||||
e = pieces.length - 1
|
||||
while e > 0
|
||||
p = rand( e ); t = pieces[e];
|
||||
pieces[e] = pieces[p]; pieces[p] = t; e -= 1
|
||||
end
|
||||
end
|
||||
board = Array.new( 64 ); generateBoard( board, pieces )
|
||||
puts
|
||||
e = 0
|
||||
for j in 0 .. 7
|
||||
for i in 0 .. 7
|
||||
if board[i + 8 * j] == nil; e += 1
|
||||
else
|
||||
if e > 0; print( e ); e = 0; end
|
||||
print( board[i + 8 * j] )
|
||||
end
|
||||
end
|
||||
if e > 0; print( e ); e = 0; end
|
||||
if j < 7; print( "/" ); end
|
||||
end
|
||||
print( " w - - 0 1\n" )
|
||||
for j in 0 .. 7
|
||||
for i in 0 .. 7
|
||||
if board[i + j * 8] == nil; print( "." )
|
||||
else print( board[i + j * 8] ); end
|
||||
end
|
||||
puts
|
||||
end
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use rand::{Rng, distributions::{Distribution, Standard}};
|
||||
|
||||
const EMPTY: u8 = b'.';
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Board {
|
||||
grid: [[u8; 8]; 8],
|
||||
}
|
||||
|
||||
impl Distribution<Board> for Standard {
|
||||
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Board {
|
||||
let mut board = Board::empty();
|
||||
board.place_kings(rng);
|
||||
board.place_pieces(rng, b"PPPPPPPP", true);
|
||||
board.place_pieces(rng, b"pppppppp", true);
|
||||
board.place_pieces(rng, b"RNBQBNR", false);
|
||||
board.place_pieces(rng, b"rnbqbnr", false);
|
||||
board
|
||||
}
|
||||
}
|
||||
|
||||
impl Board {
|
||||
fn empty() -> Self {
|
||||
Board { grid: [[EMPTY; 8]; 8] }
|
||||
}
|
||||
|
||||
fn fen(&self) -> String {
|
||||
let mut fen = String::new();
|
||||
let mut count_empty = 0;
|
||||
for row in &self.grid {
|
||||
for &ch in row {
|
||||
print!("{} ", ch as char);
|
||||
if ch == EMPTY {
|
||||
count_empty += 1;
|
||||
} else {
|
||||
if count_empty > 0 {
|
||||
write!(fen, "{}", count_empty).unwrap();
|
||||
count_empty = 0;
|
||||
}
|
||||
fen.push(ch as char);
|
||||
}
|
||||
}
|
||||
if count_empty > 0 {
|
||||
write!(fen, "{}", count_empty).unwrap();
|
||||
count_empty = 0;
|
||||
}
|
||||
fen.push('/');
|
||||
println!();
|
||||
}
|
||||
fen.push_str(" w - - 0 1");
|
||||
fen
|
||||
}
|
||||
|
||||
fn place_kings<R: Rng + ?Sized>(&mut self, rng: &mut R) {
|
||||
loop {
|
||||
let r1: i8 = rng.gen_range(0, 8);
|
||||
let c1: i8 = rng.gen_range(0, 8);
|
||||
let r2: i8 = rng.gen_range(0, 8);
|
||||
let c2: i8 = rng.gen_range(0, 8);
|
||||
if r1 != r2 && (r1 - r2).abs() > 1 && (c1 - c2).abs() > 1 {
|
||||
self.grid[r1 as usize][c1 as usize] = b'K';
|
||||
self.grid[r2 as usize][c2 as usize] = b'k';
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn place_pieces<R: Rng + ?Sized>(&mut self, rng: &mut R, pieces: &[u8], is_pawn: bool) {
|
||||
let num_to_place = rng.gen_range(0, pieces.len());
|
||||
for &piece in pieces.iter().take(num_to_place) {
|
||||
let mut r = rng.gen_range(0, 8);
|
||||
let mut c = rng.gen_range(0, 8);
|
||||
while self.grid[r][c] != EMPTY || (is_pawn && (r == 7 || r == 0)) {
|
||||
r = rng.gen_range(0, 8);
|
||||
c = rng.gen_range(0, 8);
|
||||
}
|
||||
self.grid[r][c] = piece;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let b: Board = rand::random();
|
||||
println!("{}", b.fen());
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import scala.math.abs
|
||||
import scala.util.Random
|
||||
|
||||
object RandomFen extends App {
|
||||
val rand = new Random
|
||||
|
||||
private def createFen = {
|
||||
val grid = Array.ofDim[Char](8, 8)
|
||||
|
||||
def placeKings(grid: Array[Array[Char]]): Unit = {
|
||||
var r1, c1, r2, c2 = 0
|
||||
do {
|
||||
r1 = rand.nextInt(8)
|
||||
c1 = rand.nextInt(8)
|
||||
r2 = rand.nextInt(8)
|
||||
c2 = rand.nextInt(8)
|
||||
} while (r1 == r2 || abs(r1 - r2) <= 1 || abs(c1 - c2) <= 1)
|
||||
grid(r1)(c1) = 'K'
|
||||
grid(r2)(c2) = 'k'
|
||||
}
|
||||
|
||||
def placePieces(grid: Array[Array[Char]],
|
||||
pieces: String,
|
||||
isPawn: Boolean): Unit = {
|
||||
val numToPlace = rand.nextInt(pieces.length)
|
||||
|
||||
for (n <- 0 until numToPlace) {
|
||||
var r, c = 0
|
||||
do {
|
||||
r = rand.nextInt(8)
|
||||
c = rand.nextInt(8)
|
||||
} while (grid(r)(c) != 0 || (isPawn && (r == 7 || r == 0)))
|
||||
grid(r)(c) = pieces(n)
|
||||
}
|
||||
}
|
||||
|
||||
def toFen(grid: Array[Array[Char]]) = {
|
||||
val fen = new StringBuilder
|
||||
var countEmpty = 0
|
||||
for (r <- grid.indices) {
|
||||
for (c <- grid.indices) {
|
||||
val ch = grid(r)(c)
|
||||
print(f"${if (ch == 0) '.' else ch}%2c ")
|
||||
if (ch == 0) countEmpty += 1
|
||||
else {
|
||||
if (countEmpty > 0) {
|
||||
fen.append(countEmpty)
|
||||
countEmpty = 0
|
||||
}
|
||||
fen.append(ch)
|
||||
}
|
||||
}
|
||||
if (countEmpty > 0) {
|
||||
fen.append(countEmpty)
|
||||
countEmpty = 0
|
||||
}
|
||||
fen.append("/")
|
||||
println()
|
||||
}
|
||||
fen.append(" w - - 0 1").toString
|
||||
}
|
||||
|
||||
placeKings(grid)
|
||||
placePieces(grid, "PPPPPPPP", isPawn = true)
|
||||
placePieces(grid, "pppppppp", isPawn = true)
|
||||
placePieces(grid, "RNBQBNR", isPawn = false)
|
||||
placePieces(grid, "rnbqbnr", isPawn = false)
|
||||
toFen(grid)
|
||||
}
|
||||
|
||||
println(createFen)
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
class Fen {
|
||||
|
||||
public createFen() {
|
||||
let grid: string[][];
|
||||
|
||||
grid = [];
|
||||
|
||||
for (let r = 0; r < 8; r++) {
|
||||
grid[r] = [];
|
||||
for (let c = 0; c < 8; c++) {
|
||||
grid[r][c] = "0";
|
||||
}
|
||||
}
|
||||
|
||||
this.placeKings(grid);
|
||||
this.placePieces(grid, "PPPPPPPP", true);
|
||||
this.placePieces(grid, "pppppppp", true);
|
||||
this.placePieces(grid, "RNBQBNR", false);
|
||||
this.placePieces(grid, "rnbqbnr", false);
|
||||
return this.toFen(grid);
|
||||
}
|
||||
|
||||
private placeKings(grid: string[][]): void {
|
||||
let r1, c1, r2, c2: number;
|
||||
while (true) {
|
||||
r1 = Math.floor(Math.random() * 8);
|
||||
c1 = Math.floor(Math.random() * 8);
|
||||
r2 = Math.floor(Math.random() * 8);
|
||||
c2 = Math.floor(Math.random() * 8);
|
||||
if (r1 != r2 && Math.abs(r1 - r2) > 1 && Math.abs(c1 - c2) > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
grid[r1][c1] = "K";
|
||||
grid[r2][c2] = "k";
|
||||
}
|
||||
|
||||
private placePieces(grid: string[][], pieces: string, isPawn: boolean): void {
|
||||
let numToPlace: number = Math.floor(Math.random() * pieces.length);
|
||||
for (let n = 0; n < numToPlace; n++) {
|
||||
let r, c: number;
|
||||
do {
|
||||
r = Math.floor(Math.random() * 8);
|
||||
c = Math.floor(Math.random() * 8);
|
||||
} while (grid[r][c] != "0" || (isPawn && (r == 7 || r == 0)));
|
||||
|
||||
grid[r][c] = pieces.charAt(n);
|
||||
}
|
||||
}
|
||||
|
||||
private toFen(grid: string[][]): string {
|
||||
let result: string = "";
|
||||
let countEmpty: number = 0;
|
||||
for (let r = 0; r < 8; r++) {
|
||||
for (let c = 0; c < 8; c++) {
|
||||
let char: string = grid[r][c];
|
||||
if (char == "0") {
|
||||
countEmpty++;
|
||||
} else {
|
||||
if (countEmpty > 0) {
|
||||
result += countEmpty;
|
||||
countEmpty = 0;
|
||||
}
|
||||
result += char;
|
||||
}
|
||||
}
|
||||
if (countEmpty > 0) {
|
||||
result += countEmpty;
|
||||
countEmpty = 0;
|
||||
}
|
||||
result += "/";
|
||||
}
|
||||
return result += " w - - 0 1";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let fen: Fen = new Fen();
|
||||
console.log(fen.createFen());
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import "random" for Random
|
||||
import "/fmt" for Fmt
|
||||
|
||||
var rand = Random.new()
|
||||
|
||||
var grid = List.filled(8, null)
|
||||
for (i in 0..7) grid[i] = List.filled(9, ".")
|
||||
|
||||
var placeKings = Fn.new {
|
||||
while (true) {
|
||||
var r1 = rand.int(8)
|
||||
var c1 = rand.int(8)
|
||||
var r2 = rand.int(8)
|
||||
var c2 = rand.int(8)
|
||||
if (r1 != r2 && (r1 - r2).abs > 1 && (c1 - c2).abs > 1) {
|
||||
grid[r1][c1] = "K"
|
||||
grid[r2][c2] = "k"
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var placePieces = Fn.new { |pieces, isPawn|
|
||||
var numToPlace = rand.int(pieces.count)
|
||||
for (n in 0...numToPlace) {
|
||||
var r
|
||||
var c
|
||||
while (true) {
|
||||
r = rand.int(8)
|
||||
c = rand.int(8)
|
||||
if (grid[r][c] == "." && !(isPawn && (r == 7 || r == 0))) break
|
||||
}
|
||||
grid[r][c] = pieces[n]
|
||||
}
|
||||
}
|
||||
|
||||
var toFen = Fn.new {
|
||||
var fen = ""
|
||||
var countEmpty = 0
|
||||
for (r in 0..7) {
|
||||
for (c in 0..7) {
|
||||
var ch = grid[r][c]
|
||||
Fmt.write("$2s ", ch)
|
||||
if (ch == ".") {
|
||||
countEmpty = countEmpty + 1
|
||||
} else {
|
||||
if (countEmpty > 0) {
|
||||
fen = fen + countEmpty.toString
|
||||
countEmpty = 0
|
||||
}
|
||||
fen = fen + ch
|
||||
}
|
||||
}
|
||||
if (countEmpty > 0) {
|
||||
fen = fen + countEmpty.toString
|
||||
countEmpty = 0
|
||||
}
|
||||
fen = fen + "/"
|
||||
System.print()
|
||||
}
|
||||
return fen + " w - - 0 1"
|
||||
}
|
||||
|
||||
var createFen = Fn.new {
|
||||
placeKings.call()
|
||||
placePieces.call("PPPPPPPP", true)
|
||||
placePieces.call("pppppppp", true)
|
||||
placePieces.call("RNBQBNR", false)
|
||||
placePieces.call("rnbqbnr", false)
|
||||
return toFen.call()
|
||||
}
|
||||
|
||||
System.print(createFen.call())
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
dim grid(8, 8)
|
||||
|
||||
sub placeKings()
|
||||
local r1, r2, c1, c2
|
||||
|
||||
do
|
||||
r1 = int(ran(8))
|
||||
c1 = int(ran(8))
|
||||
r2 = int(ran(8))
|
||||
c2 = int(ran(8))
|
||||
if (r1 <> r2 and abs(r1 - r2) > 1 and abs(c1 - c2) > 1) then
|
||||
grid(r1, c1) = asc("K")
|
||||
grid(r2, c2) = asc("k")
|
||||
return
|
||||
end if
|
||||
loop
|
||||
end sub
|
||||
|
||||
sub placePieces(pieces$, isPawn)
|
||||
local n, r, c, numToPlace
|
||||
|
||||
numToPlace = int(ran(len(pieces$)))
|
||||
for n = 0 to numToPlace-1
|
||||
repeat
|
||||
r = int(ran(8))
|
||||
c = int(ran(8))
|
||||
until(not(grid(r, c) or (isPawn and (r = 7 or r = 0))))
|
||||
grid(r, c) = asc(mid$(pieces$, n, 1))
|
||||
next
|
||||
end sub
|
||||
|
||||
sub toFen()
|
||||
local fen$, ch, r, c, countEmpty
|
||||
|
||||
for r = 0 to 8-1
|
||||
for c = 0 to 8-1
|
||||
ch = grid(r, c)
|
||||
if ch then print chr$(ch); else print "."; end if
|
||||
if not ch then
|
||||
countEmpty = countEmpty + 1
|
||||
else
|
||||
if countEmpty then
|
||||
fen$ = fen$ + chr$(countEmpty + 48)
|
||||
countEmpty = 0
|
||||
end if
|
||||
fen$ = fen$ + chr$(ch)
|
||||
end if
|
||||
next
|
||||
if countEmpty then
|
||||
fen$ = fen$ + chr$(countEmpty + 48)
|
||||
countEmpty = 0
|
||||
end if
|
||||
fen$ = fen$ + "/"
|
||||
print
|
||||
next
|
||||
fen$ = fen$ + " w - - 0 1"
|
||||
print fen$
|
||||
end sub
|
||||
|
||||
sub createFen()
|
||||
placeKings()
|
||||
placePieces("PPPPPPPP", TRUE)
|
||||
placePieces("pppppppp", TRUE)
|
||||
placePieces("RNBQBNR", FALSE)
|
||||
placePieces("rnbqbnr", FALSE)
|
||||
toFen()
|
||||
end sub
|
||||
|
||||
createFen()
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
1 DEF FN r(v)=INT (RND*v)+1: REM we'll be using this a lot here for setup, although in real chess it should barely be used at all...
|
||||
|
||||
10 GO SUB 9400: REM modularity is pretty much vital in making Sinclair BASIC legible
|
||||
20 GO SUB 9100
|
||||
30 GO SUB 9200
|
||||
40 GO SUB 8800
|
||||
50 GO TO 9500
|
||||
|
||||
8799 REM Material assignment
|
||||
8800 LET b=FN r(16)-1: REM give black and white a random number of additional pieces each
|
||||
8810 LET w=FN r(16)-1
|
||||
8820 FOR x=1 TO b
|
||||
8830 LET p=LEN b$
|
||||
8840 LET k=FN r(p)
|
||||
8850 LET r=FN r(8): REM defined functions can have the same name as variables
|
||||
8860 LET f=FN r(8)
|
||||
8870 IF d$(r,f)<>" " THEN GO TO 8840: REM piece already there
|
||||
8880 IF b$(k)="p" AND (r=1 OR r=8) THEN GO TO 8840: REM pawn on 1st or 8th rank trapping
|
||||
8890 LET d$(r,f)=b$(k)
|
||||
8900 IF k=p THEN LET b$=b$(1 TO k-1): GO TO 8920
|
||||
8910 LET b$=b$( TO k-1)+b$(k+1 TO )
|
||||
8920 NEXT x
|
||||
8930 FOR x=1 TO w: REM now doing for white what we just did for black, could be tidied
|
||||
8940 LET p=LEN w$
|
||||
8950 LET k=FN r(p)
|
||||
8960 LET r=FN r(8)
|
||||
8970 LET f=FN r(8)
|
||||
8980 IF d$(r,f)<>" " THEN GO TO 8950
|
||||
8990 IF w$(k)="P" AND (r=1 OR r=8) THEN GO TO 8950
|
||||
9000 LET d$(r,f)=w$(k)
|
||||
9010 IF k=p THEN LET w$=w$(1 TO k-1): GO TO 9030
|
||||
9020 LET w$=w$( TO k-1)+w$(k+1 TO )
|
||||
9030 NEXT x
|
||||
9040 RETURN
|
||||
|
||||
9099 REM Kings
|
||||
9100 LET rw=FN r(8)
|
||||
9110 LET fw=FN r(8)
|
||||
9120 LET d$(rw,fw)="K"
|
||||
9130 LET rb=FN r(8)
|
||||
9140 LET fb=FN r(8)
|
||||
9150 LET rd=ABS (rw-rb): REM find distance between kings
|
||||
9160 LET fd=ABS (fd-fb)
|
||||
9170 IF rd<2 AND fd<2 THEN GO TO 9130
|
||||
9180 LET d$(rb,fb)="k"
|
||||
9190 RETURN
|
||||
|
||||
9199 REM Promotions
|
||||
9200 FOR b=1 TO 8
|
||||
9210 LET v=FN r(30): REM 30% chance of promoting each pawn
|
||||
9220 IF v=1 THEN LET b$(7+b)="q": GO TO 9260
|
||||
9230 IF v<3 THEN LET b$(7+b)="r": GO TO 9260
|
||||
9240 IF v<7 THEN LET b$(7+b)="n": GO TO 9260
|
||||
9250 IF v<10 THEN LET b$(7+b)="b"
|
||||
9260 NEXT b
|
||||
9270 FOR w=1 TO 8
|
||||
9280 LET v=FN r(30)
|
||||
9290 IF v=1 THEN LET w$(7+w)="Q": GO TO 9330
|
||||
9300 IF v<3 THEN LET w$(7+w)="R": GO TO 9330
|
||||
9310 IF v<7 THEN LET w$(7+w)="N": GO TO 9330
|
||||
9320 IF v<10 THEN LET w$(7+w)="B"
|
||||
9330 NEXT b
|
||||
9340 RETURN
|
||||
|
||||
9399 REM Setup
|
||||
9400 LET b$="qrrnnbbpppppppp": REM we'll set the kings specifically later
|
||||
9410 LET w$="QRRNNBBPPPPPPPP"
|
||||
9420 DIM d$(8,8): REM string arrays are autofilled with spaces; this defines the board area
|
||||
9430 LET f$=""
|
||||
9440 LET g$=""
|
||||
9450 RETURN
|
||||
|
||||
9499 REM Board
|
||||
9500 FOR x=1 TO 8
|
||||
9510 PRINT 9-x;: REM rank number
|
||||
9520 FOR y=1 TO 8
|
||||
9530 PRINT INVERSE (((x+y)/2)<>INT ((x+y)/2));d$(x,y);: REM evaluates to 1, a black square, if rank number + file number, read from the top left, is odd; the bottom right square is 8 + 8 = 16 = even = white, conforming to "white to the right" standards
|
||||
9540 LET f$=f$+d$(x,y): REM building the FEN
|
||||
9550 NEXT y
|
||||
9560 PRINT ': REM newline
|
||||
9570 LET f$=f$+"/"
|
||||
9580 NEXT x
|
||||
9590 PRINT " abcdefgh"''
|
||||
9600 LET k=LEN f$: REM f$ now contains the full string of the board, but we need to count the spaces into numbers
|
||||
9610 LET t=0: REM counter variable
|
||||
9620 FOR x=1 TO k
|
||||
9630 LET t$=f$(x)
|
||||
9640 IF t$<>" " AND t=0 THEN GO TO 9670: REM not empty and not currently running through blank spaces
|
||||
9650 IF t$=" " THEN LET t=t+1: GO TO 9670: REM number of blanks in this batch so far
|
||||
9660 LET f$(x-1)=STR$ t: LET t=0: REM not empty, so a blank space sequence must have ended; insert the counter into the string (STR$ turns the numeric value into its string representation)
|
||||
9670 NEXT x
|
||||
9680 FOR x=1 TO k: REM now strip the spaces out
|
||||
9690 IF f$(x)<>" " THEN LET g$=g$+f$(x)
|
||||
9700 NEXT x
|
||||
9710 LET g$=g$( TO LEN g$-1)+" w - - 0 1": REM knock off the final /
|
||||
9720 PRINT g$
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
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
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
do(5){ pickFEN().println() }
|
||||
Loading…
Add table
Add a link
Reference in a new issue