Generate random chess position: Difference between revisions

Content added Content deleted
m (→‎{{header|REXX}}: fixed a typo.)
m (→‎{{header|REXX}}: changed/added comments and whitespace, changed indentations.)
Line 213: Line 213:


This version also allows any number of chessboards to be displayed.
This version also allows any number of chessboards to be displayed.
<lang rexx>/*REXX pgm gens a chess position (random pieces & positions) in a FEN format.*/
<lang rexx>/*REXX program generates a chess position (random pieces & positions) in a FEN format.*/
parse arg seed CBs . /*obtain optional arguments from the CL*/
parse arg seed CBs . /*obtain optional arguments from the CL*/
if seed\=='' & seed\="," then call random ,,seed /*RANDOM repeatability? */
if datatype(seed,'W') then call random ,,seed /*SEED given for RANDOM repeatability? */
if CBs =='' | CBs =',' then CBs=1 /*CBs: number of generated chessboards*/
if CBs=='' | CBs=="," then CBs=1 /*CBs: number of generated ChessBoards*/
/* [↓] maybe display any # of boards. */
/* [↓] maybe display any # of boards. */
do boards=1 for abs(CBs) /* [↓] maybe display separator & title*/
do boards=1 for abs(CBs) /* [↓] maybe display separator & title*/
if abs(CBs)\==1 then do; say; say center(' board' boards" ",79,'▒'); end
if sign(CBs)\==CBs then do; say; say center(' board' boards" ", 79, '▒'); end
@.=. /*initialize the chessboard to be empty*/
@.=. /*initialize the chessboard to be empty*/
do p=1 for random(2,32) /*generate a random number of chessmen.*/
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. */
if p<3 then call piece 'k' /*a king of each color. */
else call piece substr('bnpqr', random(1, 5), 1)
else call piece substr('bnpqr', random(1, 5), 1)
end /*p*/ /* [↑] place a piece. */
end /*p*/ /* [↑] place a piece on the chessboard*/
call cb /*display the ChessBoard and its FEN.*/
call cb /*display the ChessBoard and its FEN.*/
end /*boards*/ /* [↑] CB ≡ ─ ─ */
end /*boards*/ /* [↑] CB ≡ ─ ─ */
exit /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*────────────────────────────────────────────────────────────────────────────*/
cb: fen=; do r=8 for 8 by -1; $= /*board rank (so far).*/
cb: fen=; do r=8 for 8 by -1; $= /*the board rank (so far).*/
do f=8 for 8 by -1; $=$ || @.r.f; end /*f*/ /*append file.*/
do f=8 for 8 by -1; $=$ || @.r.f; end /*f*/ /*append the board file. */
say $ /*display board rank. */
say $ /*display the board rank. */
do e=8 for 8 by -1; $=changestr(copies(., e), $, e); end /*e*/
do e=8 for 8 by -1; $=changestr(copies(.,e),$,e); end /*e*/ /*.≡filler*/
fen=fen || $ || left('/', r\==1) /*append / if not the 1st rank.*/
fen=fen || $ || left('/', r\==1) /*append / if not 1st rank.*/
end /*r*/
end /*r*/ /* [↑] append $ str to FEN*/
say /*a blank line (after the board).*/
say /*display a blank sep. line*/
say 'FEN='fen "w - - 0 1" /*show Forsyth-Edwards Notation.*/
say 'FEN='fen "w - - 0 1" /*Forsyth─Edwards Notation.*/
return /* [↑] build/display chessboard.*/
return /* [↑] display chessboard.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*────────────────────────────────────────────────────────────────────────────*/
piece: parse arg x; if p//2 then upper x; arg ux /*use white if odd P.*/
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*/
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 & file.*/
do #=0 by 0; r=random(1, 8); f=random(1, 8) /*random rank and file.*/
if @.r.f\==. then iterate /*position occupied? */
if @.r.f\==. then iterate /*is position occupied?*/
if (x=='p' & r==1)|(x=='P' & r==8) then iterate /*any promoting pawn?*/
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?*/
if ux=='K' then do rr=r-1 for 3 /*[↓] neighbor ≡ king?*/
do ff=f-1 for 3; z=@.rr.ff /*obtain the neighbor*/
do ff=f-1 for 3; z=@.rr.ff; upper z /*an uppercase neighbor*/
upper z; if z=='K' then iterate #
if z=='K' then iterate # /*if a king, then skip.*/
end /*rr*/ /*[↑] neighbor≡king?*/
end /*rr*/ /*[↑] neighbor ≡ king?*/
end /*ff*/
end /*ff*/ /*[↑] we're all done. */
@.r.f=x; return /*place random piece.*/
@.r.f=x; return /*place random piece. */
end /*#*/ /*#: not incremented.*/</lang>
end /*#*/ /*#: not incremented. */</lang>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, &nbsp; so one is included here: &nbsp; ───► &nbsp; [[CHANGESTR.REX]]. <br><br>
Some older REXXes don't have a &nbsp; '''changestr''' &nbsp; BIF, &nbsp; so one is included here: &nbsp; ───► &nbsp; [[CHANGESTR.REX]]. <br><br>
'''output''' &nbsp; showing five chess positions (starting with a specific position by seeding the &nbsp; '''random''' &nbsp; BIF with &nbsp; '''96'''),
'''output''' &nbsp; showing five chess positions (starting with a specific position by seeding the &nbsp; '''random''' &nbsp; BIF with &nbsp; '''96'''),