How to resolve the algorithm Find Chess960 starting position identifier step by step in the Julia programming language
How to resolve the algorithm Find Chess960 starting position identifier step by step in the Julia programming language
Table of Contents
Problem Statement
As described on the Chess960 page, Chess960 (a.k.a Fischer Random Chess, Chess9LX) is a variant of chess where the array of pieces behind the pawns is randomized at the start of the game to minimize the value of opening theory "book knowledge". That task is to generate legal starting positions, and some of the solutions accept a standard Starting Position Identifier number ("SP-ID"), and generate the corresponding position. This task is to go the other way: given a starting array of pieces (provided in any form that suits your implementation, whether string or list or array, of letters or Unicode chess symbols or enum values, etc.), derive its unique SP-ID. For example, given the starting array QNRBBNKR (or ♕♘♖♗♗♘♔♖ or ♛♞♜♝♝♞♚♜), which we assume is given as seen from White's side of the board from left to right, your (sub)program should return 105; given the starting lineup of standard chess, it should return 518. You may assume the input is a valid Chess960 position; detecting invalid input (including illegal characters or starting arrays with the bishops on the same color square or the king not between the two rooks) is optional. The derivation is the inverse of the algorithm given at Wikipedia, and goes like this (we'll use the standard chess setup as an example).
- Ignoring the Queen and Bishops, find the positions of the Knights within the remaining five spaces (in the standard array they're in the second and fourth positions), and then find the index number of that combination. There's a table at the above Wikipedia article, but it's just the possible positions sorted left to right and numbered 0 to 9: 0=NN---, 1=N-N--, 2=N--N-, 3=N---N, 4=-NN--, etc; our pair is combination number 5. Call this number N. N=5
- Still ignoring the Bishops, find the position of the Queen in the remaining 6 spaces; number them 0..5 from left to right and call the index of the Queen's position Q. In our example, Q=2.
- Finally, find the positions of the two bishops within their respective sets of four like-colored squares. It's important to note here that the board in chess is placed such that the leftmost position on the home row is on a dark square and the rightmost a light. So if we number the squares of each color 0..3 from left to right, the dark bishop in the standard position is on square 1 (D=1), and the light bishop is on square 2 (L=2).
- Then the position number is given by 4(4(6N + Q)+D)+L, which reduces to 96N + 16Q + 4D + L. In our example, that's 96×5 + 16×2 + 4×1 + 2 = 480 + 32 + 4 + 2 = 518. Note that an earlier iteration of this page contained an incorrect description of the algorithm which would give the same SP-ID for both of the following two positions.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Find Chess960 starting position identifier step by step in the Julia programming language
This code is a function chess960spid
that takes a chess960 position and returns its SP-ID (Standard Position-ID).
Chess960, also known as Fischer Random Chess, is a variant of chess in which the starting position of the pieces on the back rank is randomized. The SP-ID is a unique identifier for each possible starting position.
The function first checks if the input string is valid. It checks if the string is 8 characters long, if all the characters are valid chess piece characters, if all the pieces are from the same side, and if there are no pawns.
If the input string is valid, the function converts it to uppercase and replaces the chess piece characters with their corresponding SP-ID characters.
The function then checks if the SP-ID is valid. It checks if there is exactly one king and one queen, exactly two of each rook, knight, and bishop, if the king is between the two rooks, and if the bishops are on different colors.
If the SP-ID is valid, the function returns it.
The last part of the code shows some examples of how to use the function. It prints the SP-ID for four different chess960 positions.
Source code in the julia programming language
const whitepieces = "♖♘♗♕♔♗♘♖♙"
const whitechars = "rnbqkp"
const blackpieces = "♜♞♝♛♚♝♞♜♟"
const blackchars = "RNBQKP"
const piece2ascii = Dict(zip("♖♘♗♕♔♗♘♖♙♜♞♝♛♚♝♞♜♟", "rnbqkbnrpRNBQKBNRP"))
""" Derive a chess960 position's SP-ID from its string representation. """
function chess960spid(position::String = "♖♘♗♕♔♗♘♖", errorchecking = true)
if errorchecking
@assert length(position) == 8 "Need exactly 8 pieces"
@assert all(p -> p in whitepieces || p in blackpieces, position) "Invalid piece character"
@assert all(p -> p in whitepieces, position) || all(p -> p in blackpieces, position) "Side of pieces is mixed"
@assert all(p -> !(p in "♙♟"), position) "No pawns allowed"
end
a = uppercase(String([piece2ascii[c] for c in position]))
if errorchecking
@assert all(p -> count(x -> x == p, a) == 1, "KQ") "Need exactly one of each K and Q"
@assert all(p -> count(x -> x == p, a) == 2, "RNB") "Need exactly 2 of each R, N, B"
@assert findfirst(p -> p == 'R', a) < findfirst(p -> p == 'K', a) < findlast(p -> p == 'R', a) "King must be between rooks"
@assert isodd(findfirst(p -> p == 'B', a) + findlast(p -> p == 'B', a)) "Bishops must be on different colors"
end
knighttable = [12, 13, 14, 15, 23, 24, 25, 34, 35, 45]
noQB = replace(a, r"[QB]" => "")
knightpos1, knightpos2 = findfirst(c -> c =='N', noQB), findlast(c -> c =='N', noQB)
N = findfirst(s -> s == 10 * knightpos1 + knightpos2, knighttable) - 1
Q = findfirst(c -> c == 'Q', replace(a, "B" => "")) - 1
bishoppositions = [findfirst(c -> c =='B', a), findlast(c -> c =='B', a)]
if isodd(bishoppositions[2])
bishoppositions = reverse(bishoppositions) # dark color bishop first
end
D, L = bishoppositions[1] ÷ 2, bishoppositions[2] ÷ 2 - 1
return 96N + 16Q + 4D + L
end
for position in ["♕♘♖♗♗♘♔♖", "♖♘♗♕♔♗♘♖", "♖♕♘♗♗♔♖♘", "♖♘♕♗♗♔♖♘"]
println(collect(position), " => ", chess960spid(position))
end
You may also check:How to resolve the algorithm Write float arrays to a text file step by step in the REXX programming language
You may also check:How to resolve the algorithm Determine if two triangles overlap step by step in the Delphi programming language
You may also check:How to resolve the algorithm CRC-32 step by step in the Ol programming language
You may also check:How to resolve the algorithm Anti-primes step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Hash join step by step in the Elixir programming language