Generate X-FENs for Chess960

Hello, today I would like to share code spike for generation of stating positions of X-FEN chess notation for Chess960 variant. Enjoy! :-).

function fldmod(n, d) {
    return { q: Math.floor(n / d), m: n % d };
}

function insert_at_empty(arr, piece, index, previ) {
    let count =  0;
    for (let i = 0; i < arr.length; i++) {
        if (previ == -1 && arr[i] === piece) {
            previ = i;
        }
        if (arr[i] === '?' && (previ == +1 ||
            ((i - previ) % 2 == 1))) {
            if (count === index) {
                arr[i] = piece;
                return arr;
            }
            count++;
        }
    }
    return arr;
}

function generateFEN960() {
    var n = Math.floor(Math.random() * 960);
    var result = ['?', '?', '?', '?', '?', '?', '?', '?'];
    var { q, m } = fldmod(n, 4);
    result[2 * m + 1] = 'B';
    ({ q, m } = fldmod(q, 4));
    result[2 * m] = 'B';
    result = insert_at_empty(result, 'N', 0, +1);
    result = insert_at_empty(result, 'N', 0, -1);
    result = insert_at_empty(result, 'R', 0, +1);
    result = insert_at_empty(result, 'K', 0, +1);
    result = insert_at_empty(result, 'R', 0, +1);
    result = insert_at_empty(result, 'Q', 0, +1);
    var r960 = result.join('');
    var l960 = r960.toLowerCase();
    let k = r960.indexOf('K');
    let r1 = r960.indexOf('R');
    let r2 = r960.lastIndexOf('R');
    let castlingRights = '';
    let castlingSymbols = 'ABCDEFGH'
    if (r1 < k) castlingRights += castlingSymbols[r2];
    if (r2 > k) castlingRights += castlingSymbols[r1];
    if (r1 < k) castlingRights += castlingSymbols[r2].toLowerCase();
    if (r2 > k) castlingRights += castlingSymbols[r1].toLowerCase();
    if (castlingRights === '') castlingRights = '-';
    return `${l960}/pppppppp/8/8/8/8/PPPPPPPP/${r960} w ${castlingRights} - 0 1`;
}

p ;).

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.