Developer log for an AI algorithm

Greetings everyone! I am thrilled to introduce to you my latest project, NerOS. It’s an AI algorithm that combines path-finding AI, field of view (FOV), evolutionary algorithms, and computer vision trained with reinforcement learning. With the help of these cutting-edge technologies, I am confident that NerOS will become a powerful and intelligent tool.

I have created this developer log to document my progress as I work on NerOS. Every step I take, every challenge I encounter, and every success I achieve will be recorded here. My aim is to provide a clear and comprehensive overview of NerOS’s development process so that others can learn from my experience.

The idea of NerOS has been in my mind for a while, and now I am ready to bring it to life. As I embark on this journey, I am excited to share my knowledge, insights, and discoveries with all of you. I am confident that by working on NerOS, I will be able to push the boundaries of AI and create something truly remarkable.

Thank you for taking the time to read my developer log, and I hope that you will join me on this exciting journey. Stay tuned for regular updates on NerOS’s development progress, as I strive to make it the most advanced AI algorithm I can.

As we embark on the journey to build NeurOS, we will need to implement various advanced technologies that will work together to create a powerful AI algorithm. These technologies include Path-finding AI, FOV, Evolutionary Algorithms, and Computer Vision trained with reinforcement learning.

The Path-finding AI component of NeurOS will involve the implementation of a search algorithm that will find the optimal path between two points in a given environment. You will have to choose from a variety of search algorithms, such as A* and Dijkstra’s algorithm, and select the one that is most appropriate for your specific use case.

The FOV component of NeurOS Version 0 will require developing a method for the AI to perceive its surroundings. This could involve the use of sensors like cameras or lidar and processing the data using advanced machine learning techniques such as convolutional neural networks (CNNs).

To incorporate Evolutionary Algorithms into NeurOS Version 0, you will need to define a fitness function that evaluates the performance of each candidate solution. Additionally, you will need to choose the specific evolutionary algorithm that you will use, such as genetic algorithms or particle swarm optimization.

The last component of NeurOS Version 0 is Computer Vision trained with reinforcement learning. To train the AI using reinforcement learning, you will need to develop a reward function that encourages the AI to behave in the desired way. You will also need to choose a suitable reinforcement learning algorithm, such as Q-learning or policy gradients, and incorporate computer vision into the training process.

Building NeurOS Version 0 will require a deep understanding of these various functions and how they can be integrated into a cohesive system. It will also demand a significant amount of coding and testing to ensure that the algorithm is working as intended. However, with dedication and perseverance, we can create an exceptional AI algorithm that can revolutionize the field of artificial intelligence. Stay tuned for regular updates on the development progress of NeurOS, as we work towards building an intelligent and powerful tool.

I invite anyone who is interested in contributing to or learning more about the NeurOS project to contact me at any time. Whether you have a specific question, an idea to share, or would like to offer your expertise and collaborate on the project, I welcome your input. Please do not hesitate to reach out to me with any questions or comments you may have. I am excited to hear from you and to work together to create an exceptional AI algorithm with NeurOS.

Hi @Jacob_McBride2! Good idea. It will take a lot of work to realize this. What will be the use cases for the end user? Will the name be NeurOS or NerOs, since you use them both?

1 Like

the use of the AI could be en enemy AI, A animal AI, NPC AI, and it could be used as AI for creatures in simulations. and the correct name was NeurOS (I must have misspelled the other word) The AI is in version 0 as of now but I’d like help with this project as well.

1 Like

I want to train the AI with reinforcement learning as well.

I started the A* algorithm pathfinding.

Here we made point A (green square) and point B (red square) and have the pathfinding navigate the blocks to get to point B.
Example (before the find path is clicked)
Screenshot 2023-05-15 10.56.55 PM

then we have when it is clicked:
Screenshot 2023-05-15 10.57.25 PM
The yellow lines show the Pathfinding program reach it’s destination while avoiding the black blocks.

Here is the JS code for the program:

const gridWidth = 10;
const gridHeight = 10;
let grid = [];
let startNode = { x: 0, y: 0 };
let targetNode = { x: 9, y: 9 };

function createGrid() {
    const gridElement = document.getElementById('grid');
    for (let i = 0; i < gridHeight; i++) {
        const row = document.createElement('div');
        for (let j = 0; j < gridWidth; j++) {
            const node = document.createElement('div');
            node.className = 'node';
            if (i === startNode.y && j === startNode.x) {
                node.className += ' start';
            } else if (i === targetNode.y && j === targetNode.x) {
                node.className += ' target';
            } else if (grid[i][j]) {
                node.className += ' obstacle';
            }
            node.addEventListener('click', () => toggleObstacle(node, j, i));
            row.appendChild(node);
        }
        gridElement.appendChild(row);
    }
}

function toggleObstacle(node, x, y) {
    if (node.classList.contains('obstacle')) {
        node.classList.remove('obstacle');
        grid[y][x] = false;
    } else {
        node.classList.add('obstacle');
        grid[y][x] = true;
    }
}

function initializeGrid() {
    for (let i = 0; i < gridHeight; i++) {
        grid[i] = [];
        for (let j = 0; j < gridWidth; j++) {
            // Randomly assign obstacles
            const isObstacle = Math.random() < 0.2; // Adjust the obstacle probability as needed
            grid[i][j] = isObstacle;
        }
    }
}

function runPathfinding() {
    const path = findPath(startNode, targetNode);
    if (path) {
        visualizePath(path);
    } else {
        alert('No path found!');
    }
}

function findPath(start, target) {
    const openList = [];
    const closedList = [];
    const cameFrom = {};

    // Initialize the start node
    const startNode = {
        position: { x: start.x, y: start.y },
        gScore: 0,
        fScore: heuristic(start, target),
    };

    openList.push(startNode);

    while (openList.length > 0) {
        // Find the node with the lowest fScore
        let current = openList[0];
        let currentIndex = 0;

        for (let i = 1; i < openList.length; i++) {
            if (openList[i].fScore < current.fScore) {
                current = openList[i];
                currentIndex = i;
            }
        }

        // Check if the target has been reached
        if (current.position.x === target.x && current.position.y === target.y) {
            return reconstructPath(cameFrom, current);
        }

        // Move the current node from open list to closed list
        openList.splice(currentIndex, 1);
        closedList.push(current);

        // Generate neighbor nodes
        const neighbors = getNeighbors(current.position);

        for (const neighbor of neighbors) {
            if (closedList.some((node) => node.position.x === neighbor.x && node.position.y === neighbor.y)) {
                continue; // Ignore the neighbor which is already evaluated
            }

            const gScore = current.gScore + 1; 
// Distance between neighbors is always 1 in this grid            
          const existingNodeIndex = openList.findIndex((node) => node.position.x === neighbor.x && node.position.y === neighbor.y);

            if (existingNodeIndex === -1) {
                // Discover a new node
                const newNode = {
                    position: { x: neighbor.x, y: neighbor.y },
                    gScore: gScore,
                    fScore: gScore + heuristic(neighbor, target),
                };

                openList.push(newNode);
                cameFrom[`${neighbor.x},${neighbor.y}`] = current;
            } else {
                // Update existing node if new path is better
                const existingNode = openList[existingNodeIndex];

                if (gScore < existingNode.gScore) {
                    existingNode.gScore = gScore;
                    existingNode.fScore = gScore + heuristic(neighbor, target);
                    cameFrom[`${neighbor.x},${neighbor.y}`] = current;
                }
            }
        }
    }

    // No path found
    return null;
}

function reconstructPath(cameFrom, current) {
    const path = [];
    while (current) {
        path.unshift(current.position);
        current = cameFrom[`${current.position.x},${current.position.y}`];
    }
    return path;
}

function getNeighbors(position) {
    const { x, y } = position;
    const neighbors = [];

    // Add top neighbor
    if (y > 0) {
        neighbors.push({ x, y: y - 1 });
    }

    // Add bottom neighbor
    if (y < gridHeight - 1) {
        neighbors.push({ x, y: y + 1 });
    }

    // Add left neighbor
    if (x > 0) {
        neighbors.push({ x: x - 1, y });
    }

    // Add right neighbor
    if (x < gridWidth - 1) {
        neighbors.push({ x: x + 1, y });
    }

    return neighbors;
}

function heuristic(node, target) {
    // Simple Manhattan distance heuristic
    return Math.abs(node.x - target.x) + Math.abs(node.y - target.y);
}

function visualizePath(path) {
    const gridElement = document.getElementById('grid');
    const nodes = gridElement.getElementsByClassName('node');

    // Reset grid colors
    for (const node of nodes) {
        node.classList.remove('path');
    }

    // Highlight path
    for (const position of path) {
        const nodeIndex = position.y * gridWidth + position.x;
        nodes[nodeIndex].classList.add('path');
    }
}

initializeGrid();
createGrid();
function getNeighbors(position) {
    const { x, y } = position;
    const neighbors = [];

    // Add top neighbor
    if (y > 0 && !grid[y - 1][x]) {
        neighbors.push({ x, y: y - 1 });
    }

    // Add bottom neighbor
    if (y < gridHeight - 1 && !grid[y + 1][x]) {
        neighbors.push({ x, y: y + 1 });
    }

    // Add left neighbor
    if (x > 0 && !grid[y][x - 1]) {
        neighbors.push({ x: x - 1, y });
    }

    // Add right neighbor
    if (x < gridWidth - 1 && !grid[y][x + 1]) {
        neighbors.push({ x: x + 1, y });
    }

    return neighbors;
}

This JavaScript code represents a basic grid-based pathfinding algorithm. Let’s break it down and explain each part:

  1. The code defines the dimensions of the grid (gridWidth and gridHeight) and initializes the grid array (grid).
  2. startNode and targetNode represent the starting and target positions on the grid.
  3. The createGrid function creates the grid on the webpage by dynamically generating HTML elements. It assigns CSS classes to represent different types of nodes (start, target, and obstacles) and attaches click event listeners to toggle obstacles on the grid.
  4. The toggleObstacle function is called when a node is clicked. It toggles the obstacle status of the clicked node and updates the corresponding value in the grid array.
  5. The initializeGrid function randomly assigns obstacles to the grid based on a specified probability (0.2 in this case). It fills the grid array accordingly.
  6. The runPathfinding function is called when the pathfinding algorithm needs to be executed. It calls the findPath function to retrieve the path between the start and target nodes. If a path is found, it calls the visualizePath function to highlight the path on the grid. Otherwise, it displays an alert indicating that no path was found.
  7. The findPath function implements the A* pathfinding algorithm. It maintains an open list of nodes to be evaluated, a closed list of evaluated nodes, and a cameFrom object to track the optimal path. It iterates until the open list is empty or the target node is reached. It calculates the gScore and fScore for each neighbor and updates the open list accordingly. If a path is found, it calls the reconstructPath function to retrieve the optimal path.
  8. The reconstructPath function reconstructs the path from the cameFrom object by tracing back from the target node to the start node.
  9. The getNeighbors function returns the neighboring positions of a given position on the grid. It considers the top, bottom, left, and right neighbors and checks for out-of-bounds positions and obstacles in the grid array.
  10. The heuristic function calculates the Manhattan distance heuristic between two nodes. It is used to estimate the distance between a node and the target node.
  11. The visualizePath function highlights the nodes in the calculated path by adding a CSS class to the corresponding HTML elements.

To add Field of View (FOV) to this code, you would need to define how the FOV works and modify the getNeighbors function accordingly. FOV determines which nodes are visible or accessible from a given node based on a certain range or vision cone. You would need to specify the FOV rules and update the getNeighbors function to consider the FOV restrictions when generating the neighboring positions.