Generate Chess960 starting position: Difference between revisions

m
m (syntax highlighting fixup automation)
 
(15 intermediate revisions by 11 users not shown)
Line 13:
 
;Task:
The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed withusing either the [[wp:Chess symbols in Unicode|Chesschess symbols in Unicode: (♔♕♖♗♘)]] or with, the letters '''K'''ing '''Q'''ueen '''R'''ook '''B'''ishop k'''N'''ight, or the corresponding letters in a language other than English.
<br><br>
 
Line 185:
chess960 ?960
487 QRBNKNRB</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="arturo">; Using Edward Collins' single-die method
; http://www.edcollins.com/chess/fischer-random.htm
 
chess960: function [][
result: array.of: 8 ø
vacant: @0..7 ; open squares available to put pieces
result\[remove 'vacant <= 2 * random 0 3]: 'bishop ; place on random black square
result\[remove 'vacant <= 1 + 2 * random 0 3]: 'bishop ; place on random white square
loop ['queen 'knight 'knight] 'piece [
result\[remove 'vacant <= sample vacant]: piece ; place on random open square
]
result\[vacant\0]: 'rook ; place king between rooks on remaining open squares
result\[vacant\1]: 'king
result\[vacant\2]: 'rook
result
]
 
do.times:5 -> print chess960</syntaxhighlight>
 
{{out}}
 
<pre>bishop knight rook queen king knight rook bishop
knight rook queen bishop bishop king knight rook
rook bishop bishop knight knight king rook queen
bishop knight rook queen king knight rook bishop
rook king knight knight bishop queen rook bishop</pre>
 
=={{header|AutoHotkey}}==
Line 246 ⟶ 275:
next i
end</syntaxhighlight>
 
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> VDU 23, 22, 240; 360; 8, 16, 16, 136
*FONT Arial, 20
FOR I% = 1 TO 10
Rank1$ = "202"
FOR Piece = 1 TO 3
P% = RND(LENRank1$ + 1)
Rank1$ = LEFT$(Rank1$, P% - 1) + MID$("144", Piece, 1) + MID$(Rank1$, P%)
NEXT
P% = RND(7)
Rank1$ = LEFT$(Rank1$, P% - 1) + "3" + MID$(Rank1$, P%)
IF P% > 5 P% += 1 ELSE P% += RND(4 - (P% >> 1)) * 2 - 1
Rank1$ = LEFT$(Rank1$, P% - 1) + "3" + MID$(Rank1$, P%)
FOR Piece = 1 TO 8
VDU &E2, &99, &94 + VALMID$(Rank1$, Piece, 1)
NEXT
PRINT
NEXT</syntaxhighlight>
{{out}}
<pre>♘ ♖ ♗ ♔ ♖ ♘ ♕ ♗
♘ ♖ ♔ ♘ ♕ ♖ ♗ ♗
♕ ♗ ♖ ♔ ♗ ♘ ♖ ♘
♖ ♘ ♔ ♗ ♖ ♕ ♗ ♘
♖ ♗ ♗ ♘ ♔ ♖ ♘ ♕
♘ ♖ ♗ ♗ ♕ ♔ ♘ ♖
♖ ♔ ♕ ♘ ♗ ♘ ♖ ♗
♘ ♘ ♖ ♔ ♖ ♗ ♗ ♕
♖ ♕ ♔ ♘ ♗ ♗ ♖ ♘
♖ ♕ ♔ ♘ ♘ ♗ ♗ ♖</pre>
 
==={{header|Commodore BASIC}}===
Line 551 ⟶ 611:
RNKBNRBQ
QNRBBNKR</pre>
 
 
=={{header|C#}}==
{{trans|Go}}
<syntaxhighlight lang="C#">
using System;
 
class Program
{
struct Symbols
{
public char K, Q, R, B, N;
 
public Symbols(char k, char q, char r, char b, char n)
{
K = k; Q = q; R = r; B = b; N = n;
}
}
 
private static Symbols A = new Symbols('K', 'Q', 'R', 'B', 'N');
private static Symbols W = new Symbols('♔', '♕', '♖', '♗', '♘');
private static Symbols B = new Symbols('♚', '♛', '♜', '♝', '♞');
 
private static string[] krn = new string[]
{
"nnrkr", "nrnkr", "nrknr", "nrkrn",
"rnnkr", "rnknr", "rnkrn",
"rknnr", "rknrn",
"rkrnn"
};
 
private static string Chess960(Symbols sym, int id)
{
char[] pos = new char[8];
int q = id / 4, r = id % 4;
pos[r * 2 + 1] = sym.B;
r = q % 4; q /= 4;
pos[r * 2] = sym.B;
r = q % 6; q /= 6;
int placementIndex = 0; // Adjusted variable name to prevent conflict
for (int i = 0; ; i++)
{
if (pos[i] != '\0') continue;
if (r == 0)
{
pos[i] = sym.Q;
break;
}
r--;
}
while (pos[placementIndex] != '\0') placementIndex++; // Adjusted loop to prevent conflict
foreach (char f in krn[q])
{
while (pos[placementIndex] != '\0') placementIndex++;
switch (f)
{
case 'k':
pos[placementIndex] = sym.K;
break;
case 'r':
pos[placementIndex] = sym.R;
break;
case 'n':
pos[placementIndex] = sym.N;
break;
}
}
return new string(pos);
}
 
static void Main(string[] args)
{
Console.WriteLine(" ID Start position");
foreach (int id in new int[] { 0, 518, 959 })
{
Console.WriteLine($"{id,3} {Chess960(A, id)}");
}
Console.WriteLine("\nRandom");
Random rand = new Random();
for (int i = 0; i < 5; i++)
{
Console.WriteLine(Chess960(W, rand.Next(960)));
}
}
}
</syntaxhighlight>
{{out}}
<pre>
ID Start position
0 BBQNNRKR
518 RNBQKBNR
959 RKRNNQBB
 
Random
♘♕♖♔♗♖♘♗
♗♗♖♘♔♖♕♘
♖♕♘♔♖♗♗♘
♘♖♗♔♘♗♖♕
♖♘♕♗♔♘♗♖
 
</pre>
 
=={{header|C++}}==
Line 775 ⟶ 936:
{{out}}
<pre>QBNNBRKR</pre>
 
=={{header|EasyLang}}==
{{trans|Lua}}
<syntaxhighlight>
len t$[] 8
proc randins c$ l r . pos .
repeat
pos = randint (r - l + 1) + l - 1
until t$[pos] = ""
.
t$[pos] = c$
.
randins "K" 2 7 king
randins "R" 1 (king - 1) h
randins "R" (king + 1) 8 h
randins "B" 1 8 b1
repeat
randins "B" 1 8 b2
until (b2 - b1) mod 2 <> 0
t$[b2] = ""
.
randins "Q" 1 8 b1
randins "N" 1 8 b1
randins "N" 1 8 b1
print strjoin t$[]
</syntaxhighlight>
{{out}}
<pre>
RBBNQNKR
</pre>
 
=={{header|EchoLisp}}==
Line 1,142 ⟶ 1,333:
 
=={{header|J}}==
BuildThe simplest J approach for this task is to initially build a table of the starting positions. thenThen, for the task, we pick one position from the table at random. There are 40320 distinct permutations of 8 items and 5040 distinct permutations of these chess pieces and (as the task name points out) only 960 permutations which also satisfy the constraints on bishop and rook position, so little memory is needed to generate the table. Also, since the table is built at "compile time", execution is fast (though "compilation" is reasonably fast also).
 
<syntaxhighlight lang="j">row0=: u: 9812+2}.5|i.10
Line 1,249 ⟶ 1,440:
♗ | ♘ | ♖ | ♘ | ♕ | ♗ | ♔ | ♖<br/>
♘ | ♗ | ♖ | ♔ | ♗ | ♘ | ♖ | ♕<br/>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq'''
 
'''Also works with fq, a Go implementation of a large subset of jq'''
 
<syntaxhighlight lang=jq>
### Utilities
# The glyphs in .
def chars: explode[] | [.] | implode;
 
# input: an array
# $keys : an array of strings
def objectify($keys):
with_entries(.key = $keys[.key]) ;
 
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
 
 
def Symbols: ["k", "q", "r", "b", "n"];
 
def A: ["K", "Q", "R", "B", "N"] | objectify(Symbols);
def W: ["♔", "♕", "♖", "♗", "♘"] | objectify(Symbols);
def B: ["♚", "♛", "♜", "♝", "♞"] | objectify(Symbols);
 
def krn: [
"nnrkr", "nrnkr", "nrknr", "nrkrn",
"rnnkr", "rnknr", "rnkrn",
"rknnr", "rknrn",
"rkrnn"
];
 
# $sym specifies the Symbols
# $id specifies the position
def chess960($sym):
. as $id
| { q: (($id/4)|floor),
r: ($id % 4)
}
| .pos[.r*2+1] = $sym.b
| .t = .q
| .q |= ((./4)|floor)
| .r = (.t % 4)
| .pos[.r*2] = $sym.b
| .t = .q
| .q |= ((./6)|floor)
| .r = .t % 6
| .i = 0
| .break = false
| until( .break;
if .pos[.i] == null
then if .r == 0
then .pos[.i] = $sym.q
| .break = true
else .r += -1
end
else .
end
| .i += 1 )
| .i = 0
| reduce (krn[.q]|chars) as $f (.;
# find next insertion point
until(.pos[.i] == null; .i += 1)
| if $f | IN("k", "r", "n")
then .pos[.i] = $sym[$f]
else .
end )
| .pos
| join(" ") ;
 
def display960($sym):
"\(lpad(3)) \(chess960($sym))";
" ID Start position",
( 0, 518, 959 | display960(A) ),
"\nPseudo-random starting positions:",
(699, 889, 757, 645, 754 | display960(W))
</syntaxhighlight>
{{output}}
<pre>
ID Start position
0 B B Q N N R K R
518 R N B Q K B N R
959 R K R N N Q B B
 
Pseudo-random starting positions:
699 ♖ ♕ ♔ ♘ ♗ ♘ ♖ ♗
889 ♖ ♕ ♔ ♗ ♗ ♖ ♘ ♘
757 ♖ ♔ ♗ ♗ ♘ ♘ ♖ ♕
645 ♖ ♘ ♗ ♗ ♔ ♖ ♕ ♘
754 ♗ ♖ ♔ ♘ ♘ ♗ ♖ ♕
</pre>
 
 
=={{header|Julia}}==
Line 1,357 ⟶ 1,643:
{{out}}
<pre>NNRQBBKR</pre>
 
=={{header|M2000 Interpreter}}==
 
<syntaxhighlight lang="m2000 interpreter">
Module Chess960 {
function OneFrom960$ {
def q$="♕", h$="♘", t$="♖", b$="♗", k$="♔"
def integer b1, b2, t1, t2, k, q
buffer p as integer *8
return p, 0:=string$(h$, 8)
k=random(1, 6)
t1=random(0,k-1)
t2=random(k+1, 7)
used=list:=k, t1, t2
do : b1=random(0,7): until not exist(used, b1)
append used, b1
n=b1 mod 2
do : b2=random(0,7): until not exist(used, b2) and b2 mod 2 <> n
append used, b2
do : q=random(0,7): until not exist(used, q)
// place pawns to positions
return p, k:=k$, t1:=t$, t2:=t$, b1:=b$, b2:=b$, q:=q$
=Eval$(p)+{
} // append new line to every solution
}
document doc$
For i=0 to 7:doc$+=OneFrom960$(): next
clipboard doc$
report doc$
}
Chess960
</syntaxhighlight>
{{out}}
<pre>
♘♗♗♘♖♕♔♖
♗♕♖♘♘♔♖♗
♗♗♕♖♔♘♖♘
♘♖♕♗♗♔♖♘
♖♔♘♗♖♕♗♘
♖♔♖♗♘♘♗♕
♘♘♗♕♖♗♔♖
♖♔♕♘♘♗♗♖
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Line 1,743 ⟶ 2,072:
♖♗♔♕♗♖♘♘
♘♖♔♖♕♗♗♘</pre>
 
=={{header|Prolog}}==
Uses <code lang="prolog">random_permutation/2</code> defined in SWI-Prolog.
 
<syntaxhighlight lang="prolog">
check(Row) :-
nth1(King, Row, ♔),
nth1(Rook1, Row, ♖),
nth1(Rook2, Row, ♖),
nth1(Bishop1, Row, ♗),
nth1(Bishop2, Row, ♗),
Rook1 < King, King < Rook2,
(Bishop1 + Bishop2) mod 2 =:= 1.
 
generate(Row) :-
random_permutation([♖,♘,♗,♕,♔,♗,♘,♖], Row),
check(Row) ; generate(Row).
</syntaxhighlight>
 
Example run:
<syntaxhighlight lang="prolog">
?- generate(X).
X = [♘, ♗, ♖, ♕, ♘, ♔, ♗, ♖] ;
X = [♘, ♗, ♖, ♕, ♘, ♔, ♗, ♖] ;
X = [♘, ♖, ♘, ♕, ♔, ♖, ♗, ♗] ;
X = [♘, ♖, ♘, ♕, ♔, ♖, ♗, ♗]
</syntaxhighlight>
 
=={{header|Python}}==
Line 2,184 ⟶ 2,540:
960 12345 6 7 8 NNBBQRKR
960 solutions</pre>
 
=={{header|RPL}}==
We use here the single die method, starting with a list of rooks that are gradually replaced by other pieces.
{{works with|HP|48G}}
≪ SWAP 1 ≪ 'R' SAME ≫ DOLIST 0 SWAP
1 OVER SIZE '''FOR''' j
DUP j GET ROT + SWAP
j 3 PICK PUT
'''NEXT'''
SWAP DROP SWAP POS
≫ '<span style="color:blue">ROOKPOS</span>' STO
≪ { } 1 8 '''START''' 'R' + '''NEXT'''
RAND 4 * FLOOR 2 * 1 + 'B' PUT
RAND 4 * CEIL 2 * 'B' PUT
DUP RAND 6 * CEIL <span style="color:blue">ROOKPOS</span> 'Q' PUT
DUP RAND 5 * CEIL <span style="color:blue">ROOKPOS</span> 'N' PUT
DUP RAND 4 * CEIL <span style="color:blue">ROOKPOS</span> 'N' PUT
DUP 2 <span style="color:blue">ROOKPOS</span> 'K' PUT
≫ '<span style="color:blue">→CH360</span>' STO
{{out}}
<pre>
3: { N Q R K B B R N }
2: { R K B B R Q N N }
1: { Q N R B K N B R }
</pre>
 
=={{header|Ruby}}==
Line 2,625 ⟶ 3,007:
♘♕♗♖♔♖♘♗
♘♘♖♔♗♗♕♖</pre>
 
=={{header|UNIX Shell}}==
{{trans|raku}}
{{works with|bash}}
<syntaxhighlight lang=bash>declare -a pieces=(♖ ♖ ♖ ♕ ♗ ♗ ♘ ♘)
declare -i i pick index
declare -ai picking_history
declare attempt
 
until [[ "$attempt" =~ ♗(..)*♗ ]]
do
attempt=''
picking_history=()
for _ in {1..8}
do
while ((picking_history[pick=RANDOM%8]++))
do :
done
attempt+="${pieces[pick]}"
done
done
for i in {0..7}
do
if [[ "${attempt:i:1}" = ♖ ]] && ((index++))
then echo "${attempt:0:i}♔${attempt:i+1}"; break;
fi
done</syntaxhighlight>
 
=={{header|Wren}}==
Line 2,630 ⟶ 3,039:
{{libheader|Wren-dynamic}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "random" for Random
import "./dynamic" for Tuple
import "./fmt" for Fmt
 
var Symbols = Tuple.create("Symbols", ["k", "q", "r", "b", "n"])
1,983

edits