Translating FEN strings to chess peices with dynamic chess board divs

153 Views Asked by At

Given a valid FEN string, I want to change the classes of certain board places to have the chess peice go in that spot. However, because it is too tedious to do myself, I am generating a chess board dynamically. I am also (currently) not worrying about the "w KQkq - 0 1" part of the string.

I want the classes within the element to change, however I expect the problem is because the elements are not fully rendered yet. This is what I am trying:

class Grid {
    constructor (length, height) {
        this.length = length;
        this.height = height;
    }
    render(fen) {
        let total = this.length * this.height;
        for (let i = 1; i <= total; i++) {
            const whiteSquare = document.createElement('div');
            whiteSquare.style.cssText = 'height:100px;width:100px;background-color:#ff9c9c;display:inline-block;padding:0;';
            whiteSquare.id = `${i}`;
            whiteSquare.className = 'ws';
            const blackSquare = document.createElement('div');
            blackSquare.style.cssText = 'height:100px;width:100px;background-color:#fa6666;display:inline-block;padding:0;';
            blackSquare.id = `${i}`;
            blackSquare.className = 'bs';
            const br = document.createElement('br');
            console.log(`${i}`)
            document
                .getElementById('board')
                .appendChild(i % 2 === Math.ceil(i / this.length) % 2
                    ? whiteSquare
                    : blackSquare
                );
            if (i % this.length == 0) document.getElementById('board').appendChild(br);
            fen.split('');
            let el;
            for (let i = 0; i < fen.length; i++) {
                el = document.getElementById(i);
                switch (fen[i]) {
                    case 'p':
                        el.classList.add('bpawn');
                        break;
                    case 'r':
                        el.classList.add('brook');
                        break;
                    case 'n':
                        el.classList.add('bknight');
                        break;
                    case 'b':
                        el.classList.add('bbishop');
                        break;
                    case 'q':
                        el.classList.add('bqueen');
                        break;
                    case 'k':
                        el.classList.add('bking');
                        break;
                    case 'P':
                        el.classList.add('wpawn');
                        break;
                    case 'R':
                        el.classList.add('wrook');
                        break;
                    case 'N':
                        el.classList.add('wknight');
                        break;
                    case 'B':
                        el.classList.add('wbishop');
                        break;
                    case 'Q':
                        el.classList.add('wqueen');
                        break;
                    case 'K':
                        el.classList.add('wking');
                        break;
                    default:
                        break;
                }
            }
        }
    }
}
let board = new Grid(8, 8);
board.render('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')

This generates an error saying that classList is not defined. Is there a way to render these strings with dynamic board slots?

1

There are 1 best solutions below

1
On BEST ANSWER

There are a few things wrong. First off your first for loop starts at 1 while the second one starts at 0. Making the IDs inconsistent.

Furthermore you have the for loops nested but instead they need to be one after the other so we know all elements are added to the DOM.

I made the squares a bit smaller so they look better in the small snippet preview.

class Grid {
  constructor(length, height) {
    this.length = length;
    this.height = height;
  }

  render(fen) {
    let total = this.length * this.height;

    for (let i = 1; i <= total; i++) {
      const whiteSquare = document.createElement('div');
      whiteSquare.style.cssText = 'height:50px;width:50px;background-color:#ff9c9c;display:inline-block;padding:0;';
      whiteSquare.id = `${i}`;
      whiteSquare.className = 'ws';

      const blackSquare = document.createElement('div');
      blackSquare.style.cssText = 'height:50px;width:50px;background-color:#fa6666;display:inline-block;padding:0;';
      blackSquare.id = `${i}`;
      blackSquare.className = 'bs';

      const br = document.createElement('br');

      // console.log(`${i}`)

      document
        .getElementById('board')
        .appendChild(i % 2 === Math.ceil(i / this.length) % 2 ?
          whiteSquare :
          blackSquare
        );

      if (i % this.length == 0) document.getElementById('board').appendChild(br);
    }

    fen.split('');

    let el;
    for (let i = 1; i <= fen.length; i++) {
      el = document.getElementById(i);

      switch (fen[i]) {
        case 'p':
          el.classList.add('bpawn');
          break;
        case 'r':
          el.classList.add('brook');
          break;
        case 'n':
          el.classList.add('bknight');
          break;
        case 'b':
          el.classList.add('bbishop');
          break;
        case 'q':
          el.classList.add('bqueen');
          break;
        case 'k':
          el.classList.add('bking');
          break;
        case 'P':
          el.classList.add('wpawn');
          break;
        case 'R':
          el.classList.add('wrook');
          break;
        case 'N':
          el.classList.add('wknight');
          break;
        case 'B':
          el.classList.add('wbishop');
          break;
        case 'Q':
          el.classList.add('wqueen');
          break;
        case 'K':
          el.classList.add('wking');
          break;
        default:
          break;
      }
    }
  }
}

let board = new Grid(8, 8);
board.render('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
<div id="board"></div>