Obtaining the FEN from a non-nested chess board list using JavaScript

My chess Program.js is not running smoothly;

I need to extract the FEN from 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 looked at various examples, but they all use nested lists like this

board2 = [
    [],
    []
]

and it doesn't work with my current system

The algorithm I created works only for the initial case shown in "board1" list

For a different scenario, it 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 am looking for an algorithm that can generate the correct FEN for any board setup, such as the one mentioned above

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

This is the algorithm I currently have

function getFEN2(board) {
let result;
let counter = 0;
let save = [];

for (a in board) {
    index = parseInt(a)
    v = board[index];
    if (v === " ") {
        counter += 1;
        if (counter > 1) {
            save[save.length - 1] = counter.toString();
        } else if (cnt < 1) {
            save.push(counter.toString()); 
        }
    } else if (v !== " ") {
        save.push(v); 
        counter = 0; 
    }
    
    
    if ((index + 1) % 8 === 0) {
        save.push("/");
        counter = 0;
    }
}
result = save.join(""); 
return result;

// Thank you for your help

Answer №1

Your approach correctly utilizes the modulus operator to determine the file, but overlooks the fact that the ranks are added to the FEN starting with the last row in the board array. As a result, a more straightforward solution involves using nested for loops, where the outer loop manages the rank while the inner loop handles the file.

It's important to note how the rank iterates from 7 to 0 in order to maintain the correct order of ranks in the resulting FEN representation.

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 );

Similar to your method, this solution also accumulates empty squares until encountering a non-empty square or reaching the end of the rank, at which point the count of empty squares is appended to the FEN notation.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize Electron to Connect with the Backend

Currently, I am working on developing a small desktop application utilizing electron and P5 for the front-end. My goal is to make sure that this application operates seamlessly offline by storing data locally instead of relying on a database. The challen ...

array_merge eliminates an empty string from the array

I have encountered an issue while using array_merge() that I need help understanding: $defaultOptions = [ 'active' => null, 'activeClass' => 'active', 'wrapper' => [ &apos ...

VueJs does not display the source code of components for users

I've recently delved into working with vueJS2 and am currently learning about components. I have a question for the experts in this field. As far as I understand, VueJS processes HTML using JavaScript, which is why the rest of the HTML code may not b ...

Organize table information using rowspan functionality

View of Current Table I am looking to implement a side column in my table using rowspan to group dates within each pay period. The goal is for a supervisor to be able to create a new pay period, which will assign a unique integer in the database and then ...

What is the process for showcasing specific Firestore items on a webpage?

database I've encountered an intriguing bug in my code that is proving difficult to resolve. The code involves a straightforward setup with React and Firestore, where items are listed on one page and their details are displayed on the next. However, t ...

What are the steps to create a custom progress bar using JavaScript?

I have experience with HTML and CSS. Below is the HTML code: <div id="wrapper"> <ul id="top"> <center><li><a href="#one" class="button">GENERATE</a></li></center> </ul> <div class="box" i ...

creating a spherical image mapping with three.js

I am currently facing a challenge in UV mapping a cube-map texture onto a sphere. The process of mapping a cube-map onto a cube was straightforward for me. I successfully mapped an image onto a cube using the following steps: Click here to open the image ...

Could you please clarify the specific functionality of this script?

I've been trying to figure out the communication process between (a website that tracks real-time changes in Roblox's catalog and updates the client) and I came across this script while inspecting the site. It seems like this script is responsib ...

How can I import tamplateData into my JavaScript files in Docpad?

Looking for a DocPad plugin that can preprocess JS files and utilize templateData variables and helpers to access configuration values. While experimenting with Hogan, I managed to retrieve the variables but encountered difficulty in invoking the helpers. ...

Can you please explain the function of this JavaScript code for the Isotope filter?

I am struggling to grasp the functionality of a section of vanilla JS code related to the Isotope filter. You can find the original code here. var buttonGroups = document.querySelectorAll('.button-group'); for (var i = 0; i < buttonGroups.le ...

Creating an Add-in using the Excel JavaScript API based on an already existing spreadsheet

Is there a way to create an Add-in using Excel JavaScript API from an existing spreadsheet? When running npm start, it generates a blank workbook. I believe changes need to be made in the Manifest.xml file, as npm start triggers office-addin-debugging star ...

Utilize pivot to manage user roles and permissions in ExpressJS application using Mongoose

My user schema is structured as shown below const userSchema = mongoose.Schema({ username: { type: String, required: true, }, first_name: { type: String, required: true, }, last_name: { type: Stri ...

I am currently working on implementing a feature in my app that allows users to easily log in using their Google account

Currently, I am in the process of enhancing my app to enable users to log in using their Google account. The frontend is built with ReactJS, tailwindcss, and sanity. The login button successfully writes user data to the sanity database. However, I suspect ...

The functionality of a website's design acts as a safeguard against unauthorized data transfers

I am encountering a major issue with my website. The layout I have created seems to be hindering me from making any modifications. My website consists of several containers, with three small containers stacked on top of each other as the main section of ...

Guide to comparing two TSX elements in a React + TSX environment

I am facing difficulties in comparing two React TSX elements. Despite being new to both React and TSX, I have tried copying and pasting the exact elements for comparison but it doesn't seem to work. Can you guide me on what might be causing this issue ...

What is the correct way to implement Axios interceptor in TypeScript?

I have implemented an axios interceptor: instance.interceptors.response.use(async (response) => { return response.data; }, (err) => { return Promise.reject(err); }); This interceptor retrieves the data property from the response. The re ...

What is the process for moving information between files?

I have two files which are named as, employee-rates-controller.ts: private load() { return this.entityService .load(this.$scope.projectRevisionUid) .then(resp => { localStorage.removeItem('employeerates'); this.$ ...

Having trouble with React list.map not functioning properly while deleting items from local storage?

I'm currently developing a budget tracking application that allows users to input various incomes and expenses. To manage the state of this app, I am utilizing useReducer. Each income and expense is represented as an object, and upon submission by the ...

Tips for targeting an element for focus following a re-render in ReactJS

Within my web application, when a user hits the enter key, they are able to save the current record. A message confirming that the "record has been successfully saved" is then displayed. However, I have noticed that the blinking cursor in one of the input ...

Problem with CSS: In Chrome, text fields have 3px additional margin-right

https://i.sstatic.net/I8mzi.jpg I am facing an issue with the margins of my text fields. Even though I have set a margin-right of 5px for each field, Google Chrome seems to be adding an additional 3-4px automatically. This problem is evident when I dynami ...