how to get the FEN out of unNested chess board list in JavaScript

Viewed 117

I made a chess Program.js that is not working fine;

I want to generate the FEN out of the board list that looks like this

board1 = [
        "R", "N", "B", "K", "Q", "B", "N", "Q", 
        "P", "P", "P", "P", "P", "P", "P", "P",
        " ", " ", " ", " ", " ", " ", " ", " ",
        " ", " ", " ", " ", " ", " ", " ", " ",
        " ", " ", " ", " ", " ", " ", " ", " ",
        " ", " ", " ", " ", " ", " ", " ", " ",
        "p", "p", "p", "p", "p", "p", "p", "p",
        "r", "n", "b", "q", "k", "b", "n", "r"
]

I have seen a lot of examples but all of them on nested lists like this

board2 = [
    [],
    []
]

and it is just not working with my system

the algorithm I built is shitty and it is just working for the starting case like the list shown up "board1"

for the last one, it generates this

rnbkqbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR/

but not for this for example (after 4 moves) it just generates something like this (for board 3)

rbqkbr/pp2ppp2223p33P3222/PP2PPP/RBQKBR/

board3 = ['R', ' ', 'B', 'K', 'Q', 'B', ' ', 'R',
         'P', 'P', 'P', ' ', ' ', 'P', 'P', 'P',
         ' ', ' ', 'N', ' ', ' ', 'N', ' ', ' ',
         ' ', ' ', ' ', 'P', 'P', ' ', ' ', ' ',
         ' ', ' ', ' ', 'p', 'p', ' ', ' ', ' ',
         ' ', ' ', 'n', ' ', ' ', 'n', ' ', ' ',
         'p', 'p', 'p', ' ', ' ', 'p', 'p', 'p',
         'r', ' ', 'b', 'k', 'q', 'b', ' ', 'r'
        ]

I want an algorithm that generates the right FEN for the last board and for any other ones, the right one will be

r1bqkb1r/ppp2ppp/2n2n2/3pp3/3PP3/2N2N2/PPP2PPP/R1BKQB1R/

this is the algorithm I have

function getFEN2(board) {
let result;
let counter = 0; // counter for successive empty cell along the row
let save = []; // temp container

for (a in board) {
    index = parseInt(a)
    v = board[index];
    if (v === " ") {
        counter += 1;
        // sum up the successive empty cell and update save
        if (counter > 1) {
            save[save.length - 1] = counter.toString();
        } else if (cnt < 1) {
            save.push(counter.toString()); // add
        }
    } else if (v !== " ") {
        save.push(v); // add
        counter = 0; // reset, there is no successive number
    }
    
    
    if ((index + 1) % 8 === 0) {
        save.push("/");
        counter = 0;
    }
}
result = save.join(""); // convert list to string
return result;

}

// thank you in advance

1 Answers

Your solution correctly makes use of the modulus operator to determine the file, but does not take into consideration that the ranks are added to the FEN beginning with the last row in the board array. Subsequently, the solution is easier with a pair of nested for loops, with the outer loop handling the rank and the inner loop handling the file.

Note how the rank iterates from 7 to 0 to facilitate the proper order of ranks in the resulting FEN.

board3 = [
  'R', ' ', 'B', 'K', 'Q', 'B', ' ', 'R',
  'P', 'P', 'P', ' ', ' ', 'P', 'P', 'P',
  ' ', ' ', 'N', ' ', ' ', 'N', ' ', ' ',
  ' ', ' ', ' ', 'P', 'P', ' ', ' ', ' ',
  ' ', ' ', ' ', 'p', 'p', ' ', ' ', ' ',
  ' ', ' ', 'n', ' ', ' ', 'n', ' ', ' ',
  'p', 'p', 'p', ' ', ' ', 'p', 'p', 'p',
  'r', ' ', 'b', 'k', 'q', 'b', ' ', 'r'
]


let fen='';
for ( let rank = 7; 0 <= rank; rank-- ) {
  let emptySquares = 0;
  for ( let file = 0; file <= 7; file++ ) {
    let p = board3[ rank * 8 + file ]; 
    if ( p === ' ' ) {
      emptySquares++;
    } else {
      if ( emptySquares ) {
        fen += emptySquares.toString();
        emptySquares = 0;
      }
      fen += p;
    }
  }
  if ( emptySquares ) {
    fen += emptySquares.toString();
  }  
  fen += '/';
}

console.log( fen );

And just like your solution attempt, empty squares are simply summed until a non-empty square or the end of the rank is encountered, whereupon the current sum of empty squares is added to the FEN.

Related