Discover the route connecting two points. The current maze algorithm is operating at a sluggish

I'm in the process of developing an algorithm to identify the most efficient route between two points within a maze, but I've hit a snag with its current speed.

Here's what I've done so far:

Auxiliary classes:

import { Coord } from "./Coord";

export class MazeResult {
    position: Coord;
    path: Array<Coord>;

    constructor (_position: Coord, _path: Array<Coord>) {
        this.position = _position;
        this.path = _path;
    }
}

export class Coord {
    coordX: number;
    coordY: number;
    isFree: boolean;
    element: Element;
    distance: number;

    constructor (xpos: number, ypos: number) {
        this.coordX = xpos;
        this.coordY = ypos;
        this.distance = 0;
    }
}

function isValid(visited: Array<Coord>, position: Coord)
{
    let checkPosition = mapPositions.find(_p => _p.coordX == position.coordX &&
                                                _p.coordY == position.coordY);
    let isVisited = false;
    for (var j = 0; j < visited.length; j ++) {
            if ((visited[j].coordX == position.coordX && visited[j].coordY == position.coordY)) {
                isVisited = true;
                break;
        }
    }
    return (position.coordY >= 0) && 
            (position.coordY < lines.length) && 
            (position.coordX >= 0) && 
            (position.coordX < lines[0].length) && 
            (checkPosition != undefined && checkPosition.element.elementType == ElementType.FIELD) && 
            !isVisited;
}

function findPath(origin: Coord, target: Coord, minDistance: number) {
    let queue = Array<MazeResult>();
    let validpaths = Array<Array<Coord>>();

    // Newly explored points:
    // storing the position and the previous steps taken
    // beginning with the start point and a path consisting solely of that point
     let tmpElement = new MazeResult(origin, [origin]);
    queue.push(tmpElement);

    while (queue.length > 0) {
        // retrieve next position to explore potential directions
        let pointToReach = queue.shift();
        let position = new Coord(0, 0);
        let path = new Array<Coord>();
        if(pointToReach != undefined){
            position = pointToReach.position;
            path = pointToReach.path;
        } 
        // evaluating all possible directions
        let direction = [ 
                            [ position.coordX, position.coordY - 1 ],
                            [ position.coordX, position.coordY + 1 ],
                            [ position.coordX - 1, position.coordY ],
                            [ position.coordX + 1, position.coordY ]
                        ];
        for(var i = 0; i < direction.length; i++) { 
            let newTarget = new Coord(direction[i][0], direction[i][1]);
            // checking if the point is free
            if (isValid(path, newTarget)) {
                //
                let newPath = path.slice(0);
                newPath.push(newTarget);

                if ((validpaths.length > 0 && validpaths.sort(_p => _p.length)[0].length < newPath.length) || 
                    (minDistance > 0 && newPath.length > minDistance))
                    continue;

                // verifying if it reaches the destination
                if (newTarget.coordX != target.coordX || newTarget.coordY != target.coordY) {
                    // storing the position along with the associated path
                    tmpElement = new MazeResult(newTarget, newPath);                    
                    queue.push(tmpElement);
                } else {
                    // recording the shortest path found
                    validpaths.push(newPath);
                    // stop here for only one shortest path
                }
            }
        }
    }

    validpaths = validpaths.sort(sortByArrayPosition);
    let result = validpaths.shift();

    return result;
}

I have introduced a third parameter minDistance for comparing calculations of paths to different points, although its relevance may be minimal in this case.

How can I enhance the efficiency of this algorithm?

Answer №1

If you're in need of guidance on pathfinding algorithms, look no further than Dijkstra. Check out the excellent open-source library at Javascript-algorithms. To get started, you'll need to create a weighted graph representation (familiarity with Graph theory is key). Assign Euclidean distance as the weight between points and designate a unique identifier for each point (for example, a MAC Address in my case). Make sure to use the appropriate keyword for each point in your scenario.

Answer №2

If you're interested, you can learn more about Dijkstra's algorithm. It appears that your implementation is somewhat similar but more intricate. Keeping track of the minimum distance to each position is sufficient without storing the entire path. To find the shortest path, you simply move to the neighboring cell with the lowest distance value.

Update: Looks like someone else mentioned this idea ahead of me!

Answer №3

Thank you for the helpful suggestions.

After careful consideration, I devised the following solution:

let finalPath: Array<MazeLocation>;
let visitedLocations: Array<Coordinate>;
function calculateShortestPath(startingPoint: Coordinate, destination: Coordinate) {
    finalPath = new Array<MazeLocation>();
    visitedLocations = new Array<Coordinate>();
    possiblePaths = new Array<MazeLocation>();
    let tmpMazeLocation = new MazeLocation(startingPoint, null);
    finalPath.push(tmpMazeLocation);
    while(finalPath.length > 0) {
        let currentLocation = finalPath.shift();
        if (currentLocation != undefined && 
            currentLocation.position.isEqual(destination)) {
                return currentLocation;
        }
        if (currentLocation != undefined && 
            visitedLocations.find(_v => _v.isEqual(currentLocation.position)) == undefined) {
            let neighbourMazeLocation: MazeLocation;
            let xCoord: Array<number>;
            let yCoord: Array<number>;
            xCoord = [0, -1, 1, 0];
            yCoord = [-1, 0, 0, 1];
            for (let idx = 0; idx < 4; idx++) {
                neighbourMazeLocation = new MazeLocation(new Coordinate(currentLocation.position.x + xCoord[idx], currentLocation.position.y + yCoord[idx]), currentLocation);
                if (isValid(visitedLocations, neighbourMazeLocation.position)) {
                    if (visitedLocations.find(_v => _v.isEqual(currentLocation.position)) == undefined) {
                        visitedLocations.push(currentLocation.position);
                    }
                    finalPath.push(neighbourMazeLocation);
                }
            }
        }
    }

    return null;
}

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

Displaying Dynamic Content in React Table Rows Based on Conditions

I'm populating a table with multiple rows using props. If a returned prop is an empty string "" , I want to exclude that row from rendering. <Table.Body> <Table.Row> <Table.Cell>Producer</Table.Cell> ...

Ways to resolve TypeScript type issues that are functioning correctly with one type but encountering errors when used with functions

When the route function encounters the middlewares parameter type, it always throws an error. However, no error occurs if the type is used directly, as seen in lines 72 and 75. Errors will occur on lines 107 and 98. abstract class BaseMiddleware< In ...

Updating FormGroup Value in Angular When Value Changes

I am working on a project where I need to dynamically set a value for a formControl within a formGroup based on changes to another formControl in the same formGroup. However, when I attempted to implement this, I encountered an error stating: maximum call ...

ng-repeat and $scope problem

I am having an issue with my page where I display 3 images in a row using Ng-repeat. When I click on any image, it only shows the first image that was displayed in that particular row. Template: <div id="galscrolldiv" class="row" ng-repeat="image in i ...

The message states that the variable "Chart" has not been defined

I have been attempting to integrate ChartJS with Angular2, but I keep encountering an error message stating that 'Chart is not defined'. I made sure to install the ChartJS typings and referenced them accordingly. Additionally, I included the char ...

Exploring the wonders of Lightbox when dealing with content loaded via AJAX

Using Bootstrap 5 along with the Lightbox library from , I encountered an issue. The Lightbox feature functions properly on regular page loads, but fails to load on content loaded via AJAX. I attempted to resolve this by implementing the following code: ...

Executing a keystroke in Selenium Webdriver using JavaScript

I've been writing a test using Selenium WebDriverJS, and now I need to simulate pressing a key on the keyboard. Is it possible to do this with Selenium WebDriverJS? If so, how can it be done? In Java, we achieve this as follows: driver.findElement(Lo ...

Rendering HTML is not supported by AngularJS on Android 19 with version 4.4.4 and Safari 8.0.5

I have been working on an AngularJS app that is being displayed in a Webview on Android. Everything was functioning properly until yesterday when I started encountering issues with Angular not rendering the DOM correctly. I have tested the app on various v ...

Ways to extract a return from an Observable

Do you know how to retrieve the _value from the following code snippet: Here is the function I am referring to: jobsLength(){ const jobslength:any; jobslength=this.searchLogic.items$ console.log(jobslength) }; ...

How are "new" and "prototype.constructor" related in the realm of Javascript?

Many people have discussed this issue, but unfortunately, I haven't been able to find a solution yet. Here is a snippet of Javascript code regarding inheritance from a book: function Car() { var self = this; self.type = "Car" self.go = funct ...

Is there a way to create a list of languages spoken using Angular?

I am in search of a solution to create a <select> that contains all the language names from around the world. The challenge is, I need this list to be available in multiple languages as well. Currently, I am working with Angular 8 and ngx-translate, ...

Angular 2's updated router feature, routerCanReuse, provides improved functionality

I'm curious about the changes in the Angular 2 router, particularly the removal of the CanReuse interface. Is there another feature in the router that can achieve the same functionality of forcing a component reload? ...

deduce the parameter types of a function using the keys of an object

In the following code snippet, my goal is to have the argument type of fn inferred based on the values provided in args. I aim for good to be automatically inferred as boolean, num as a number and bad to trigger an error. Currently, all of them are consi ...

The div containing the AJAX POST success message suddenly vanishes within moments of being uploaded

Encountering an issue following a successful AJAX post, where the updated div disappears shortly after Here are the jquery/PHP/POST data in sequence. Button On Click Function: function Delete_ID(clickBtnValue,clickBtnID,clickBtnName) { var my_data = {& ...

Setting the height of columns in a Bootstrap panel to 100%

Is there a way to achieve 100% height for all three columns even without content? Check out this JSFiddle: <div class="row"> <div class="col-md-12"> <div class="shadow panel panel-default"> <div class="blue white-bord ...

Is `activeClassName` not being recognized by React?

I've been trying to figure out what's wrong with this code, but I can't seem to find a solution anywhere online. Can someone please help me? This code works fine in my other application, so I'm not sure why it's causing issues here ...

Converting floating point numbers to fixed floating point numbers in JavaScript

Consider this scenario: I need to calculate 3 divided by 6, which equals 0.5 as a floating number. However, when I used the javascript toFixed(6) method to round it to 6 decimal points, it returned '0.500000' as a string instead of a floating num ...

Tips on transitioning between two tables

Recently, I created an HTML page entirely in French. Now, I am attempting to incorporate a language translation feature on the website that allows users to switch between French and English (represented by two flag icons). My concept involves using a tabl ...

What is the best way to create a scrollable tbody in an HTML table using React?

In my current project, I am using React, Node, Express, and Postgres to fetch data from a database. The issue I'm facing involves creating a scrollable table within a div that spans the entire screen width. Initially, I had to apply display: block to ...

Can you clarify the meaning of "int" in this code snippet?

What does the ?: and <I extends any[] = any[]> signify in this context, and how is it utilized? export interface QueryConfig<I extends any[] = any[]> { name?: string; text: string; values?: I; types?: CustomTypesConfig; } ...