static IsGoodPosition(position) {
    if (position.length == 0) return false;
    const rows = position.split("/");
    if (rows.length != V.size.x) return false;
    let pieces = { "w": 0, "b": 0 };
    const withBall = Object.keys(V.HAS_BALL_DECODE).concat(['a']);
    let ballCount = 0;
    for (let row of rows) {
      let sumElts = 0;
      for (let i = 0; i < row.length; i++) {
        const lowerRi = row[i].toLowerCase();
        if (V.PIECES.includes(lowerRi)) {
          if (lowerRi != 'a') pieces[row[i] == lowerRi ? "b" : "w"]++;
          if (withBall.includes(lowerRi)) ballCount++;
          sumElts++;
        }
        else {
          const num = parseInt(row[i], 10);
          if (isNaN(num)) return false;
          sumElts += num;
        }
      }
      if (sumElts != V.size.y) return false;
    }
    if (ballCount != 1 || Object.values(pieces).some(v => v == 0))
      return false;
    return true;
  }
// + at least one piece per color.
+ at least one piece per color.
+ at least one piece per color .
static IsGoodPosition(position) {
    if (position.length == 0) return false;
    const rows = position.split("/");
    if (rows.length != V.size.x) return false;
    let pieces = { "w": 0, "b": 0 };
    const withBall = Object.keys(V.HAS_BALL_DECODE).concat(['a']);
    let ballCount = 0;
    for (let row of rows) {
      let sumElts = 0;
      for (let i = 0; i < row.length; i++) {
        const lowerRi = row[i].toLowerCase();
        if (V.PIECES.includes(lowerRi)) {
          if (lowerRi != 'a') pieces[row[i] == lowerRi ? "b" : "w"]++;
          if (withBall.includes(lowerRi)) ballCount++;
          sumElts++;
        }
        else {
          const num = parseInt(row[i], 10);
          if (isNaN(num)) return false;
          sumElts += num;
        }
      }
      if (sumElts != V.size.y) return false;
    }
    if (ballCount != 1 || Object.values(pieces).some(v => v == 0))
      return false;
    return true;
  }
static IsGoodPosition ( position ) { if ( position . length == 0 ) return false ; const rows = position . split ( "/" ) ; if ( rows . length != V . size . x ) return false ; let pieces = { "w" : 0 , "b" : 0 } ; const withBall = Object . keys ( V . HAS_BALL_DECODE ) . concat ( [ 'a' ] ) ; let ballCount = 0 ; for ( let row of rows ) { let sumElts = 0 ; for ( let i = 0 ; i < row . length ; i ++ ) { const lowerRi = row [ i ] . toLowerCase ( ) ; if ( V . PIECES . includes ( lowerRi ) ) { if ( lowerRi != 'a' ) pieces [ row [ i ] == lowerRi ? "b" : "w" ] ++ ; if ( withBall . includes ( lowerRi ) ) ballCount ++ ; sumElts ++ ; } else { const num = parseInt ( row [ i ] , 10 ) ; if ( isNaN ( num ) ) return false ; sumElts += num ; } } if ( sumElts != V . size . y ) return false ; } if ( ballCount != 1 || Object . values ( pieces ) . some ( v => v == 0 ) ) return false ; return true ; }
+ at least one piece per color.
+ at least one piece per color .