Looking for a way to conduct a recursive search in a Javascript object that fits your specific requirements?

Hello there,

I'm currently developing a text-based game using Javascript. In my code, I have a variable called map which is an object containing information about different rooms in the game. I found an algorithm that I would like to modify for my specific needs, but I'm unsure how to do so.

Here is a snippet of my variable:

/**
 *       [003]-[004]
 *         |     |
 * [001]-[002] [007]
 *         |     |
 *       [005]-[006]
 **/     
var map = {
    "001" : {
        "Id" : "001",
        "Name" : "Room 001",
        "Directions" : {
            "N" : "",
            "S" : "",
            "E" : "002",
            "W" : ""
        }
    }, // Other room objects omitted for brevity
};


function findSteps( id, map, array ) {
    if ( ! ( map && "object" === typeof map ) ) { return; }
    if ( map.Id === id ) { return map; }

    for ( var x in map ) {
        if ( Object.hasOwnProperty.call( map, x ) ) {
            map.Id && array.push( map.Id ); //used to exclude undefined
            var result = findSteps( id, map[ x ], array );

            if ( result !== undefined ) {
                return [ result, array ];
            }
        }
    }
}

console.dir( findSteps( "004", map, [] ) );

<p>I want the function to return an array of arrays containing all possible paths in the game. This will help me determine the closest available path later on.</p>

<p>The desired output would look something like this:</p>

<pre><code>output = [
    [ "001", "002", "003", "004" ],
    [ "001", "002", "005", "006", "007", "004" ]
]

I also need the function to accept a starting Id and stop the recursion after a certain number of iterations if no path is found.

If you have any hints or tips, they would be much appreciated.

Thank you for your help!

http://jsfiddle.net/GxZYX/

Edit:

After considering everything, I believe I only need to find the shortest path.

Edit:

http://jsfiddle.net/GxZYX/1/ is where I tested implementing breadth-first search (currently buggy).

Answer №1

I am seeking a function that will generate an array of arrays containing all potential paths. These paths will be evaluated later to identify the most efficient route.

Using this approach may not be the most effective way to conduct pathfinding. There are algorithms specifically designed for determining the shortest paths in graphs, and for most 2D games, the preferred method is often the A* algorithm. A* algorithm incorporates a heuristic distance function (h*(x)) to avoid visiting every individual node (room), resulting in significantly lower running time compared to considering every possible path, which could have a time complexity as poor as O( n! ).

For those interested, an implementation in JavaScript is available, but I recommend gaining a solid understanding of the theory behind it before attempting to implement it yourself.

Answer №2

If you want to determine the most efficient route between two points in an undirected graph similar to yours, you can simply utilize a Breadth-first-search algorithm.

function findShortestPathTo(destination, currentLocation){
    var path = [];
    while(true){
        path.push(currentLocation);
        if(currentLocation == destination[currentLocation]) break;
        currentLocation = destination[currentLocation];
    }
    return path;
}       

var breadthFirstSearch = function( graph, startNode, endNode ) {

    var destination = {};
    destination[endNode] = endNode;

    var currentLevel = [ graph[endNode] ];

    while( currentLevel.length ) {

        var nextLevel = [];

        for(var i=0; i<currentLevel.length; i++) {
            var currentNode = currentLevel[i];

            if ( currentNode.Id == startNode ) {
                return findShortestPathTo(destination, startNode);
            }

            for( var direction in currentNode.Directions ) {
                var neighborNode = currentNode.Directions[direction]; 
                if( !destination[neighborNode] ) {
                    destination[neighborNode] = currentNode.Id;
                    nextLevel.push( graph[neighborNode] );
                }
            }
        }

        currentLevel = nextLevel;
    }

    return null;
};

var graph = {
    "001" : {
        "Id" : "001",
        "Name" : "Room 001",
        "Directions" : {
            "E" : "002"
        }
    },
    "002" : {
        "Id" : "002",
        "Name" : "Room 002",
        "Directions" : {
            "N" : "003",
            "S" : "005",
            "W" : "001"
        }
    },
    "003" : {
        "Id" : "003",
        "Name" : "Room 003",
        "Directions" : {
            "S" : "002",
            "E" : "004"
        }
    },
    "004" : {
        "Id" : "004",
        "Name" : "Room 004",
        "Directions" : {
            "S" : "007",
            "W" : "003"
        }
    },
    "005" : {
        "Id" : "005",
        "Name" : "Room 005",
        "Directions" : {
            "N" : "002",
            "E" : "006"
        }
    },
    "006" : {
        "Id" : "006",
        "Name" : "Room 006",
        "Directions" : {
            "N" : "007",
            "W" : "005"
        }
    },
    "007" : {
        "Id" : "007",
        "Name" : "Room 007",
        "Directions" : {
            "N" : "004",
            "S" : "006"
        }
    }
};

console.log('shortest path',  breadthFirstSearch( graph, "001", "004" ) );

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

Employing promises for fetching data via XHR results in a promise that is still pending

Currently, I am experimenting with promises to handle asynchronous requests using XHR. Interestingly, I noticed that when I try to log the result within the .then function, it works perfectly fine. However, if I attempt to log it outside of this scope, it ...

Is there a way to insert a value into the input field using JQuery or JavaScript?

After reading my previous post on posting values into an input box, a commenter suggested using JQuery or Javascript. For more code and information, please refer to the link provided above. <label>Date</label>:&nbsp&nbsp <input sty ...

Identifying text within a paragraph using JavaScript regex, excluding any URLs mentioned

How can I use JavaScript on the client side to find a search term in a paragraph while excluding any matches that are part of a URL? I attempted to use the following regex but encountered an error: "A quantifier inside a lookbehind makes it non-fixed widt ...

Is it possible to link click and onchange events?

My code includes a function that updates an empty array and displays content in two separate HTML elements each time a radio button is selected from a select list. The content is displayed in a div and a ul element. Additionally, I want to display more rad ...

Delete the file containing Mongoose references

I'm facing an issue with deleting questions when a survey is deleted in the Survey model. Even after deleting the survey, the question remains intact in the database. Survey Schema: let surveyModel = mongoose.Schema( { Title: String, T ...

What is the formula for determining the REAL innerWidth and innerHeight?

I am currently working on a responsive website using Bootstrap and I am looking to create an element that perfectly fits the screen size. When I set the height/width to 100%, the browser includes the toolbar, other tabs, and the Windows taskbar in the cal ...

Encountering an issue with JQuery when attempting to create a double dropdown SelectList. Upon submitting the POST request, the output received is always

Two dropdownlists have been created, where one acts as a filter for the other. When selecting a customer from the dropdown Customer, only a limited set of ClientUsers is displayed in the dropdown ClientUser. This functionality is achieved using a jQuery fu ...

Does the concept of abstraction come into play when utilizing Javascript array functions that do not change the original data but instead create a new array?

I would appreciate it if you could verify this for me: Apart from carrying out their specific functions, is the primary advantage of .map() and .filter() that they offer a level of abstraction? It seems like abstraction in action when they create new arr ...

absence of an export called

I am facing an issue with importing a simple component in my React project. I am unable to locate the component causing this error. The error message I am receiving while importing the component is as follows: ./src/App.js 61:28-32 './componentes/ ...

Loading an Angular app causes Chrome devtools to freeze

Currently, I am facing some unusual behavior in my rather large Angular (1.5) application. When I have Chrome DevTools open while loading the app, the CPU usage of that particular tab shoots up to 100%, causing the app to take a minute or more to load. Add ...

Confirm the dimensions of an image prior to uploading using Node, Express, and Multer

Currently, I am developing a project using Nodejs with the express framework and ejs as the view engine. I have encountered an issue while working on image uploads. I am utilizing Multer for this task, but I need to implement a requirement where images wil ...

Having trouble getting my parallax slideshow to work with jquery preventDefault

-UPDATE- After countless hours of online courses, tutorials, and programming, I finally completed my website! Check it out here: The site is almost where I want it to be, but there are a few remaining challenges: 1) AJAX: I'm struggling to get the ...

What is the best way to retrieve a string from a URL?

Is there a way to extract only a specific string from a URL provided by an API? For instance: I'm interested in extracting only: photo_xxx-xxx-xxx.png Any suggestions on how to split the URL starting at photo and ending at png? ...

Tips for displaying a loading spinner during the rendering of a backbone view

I'm looking for some assistance in rendering a Backbone view that contains a large amount of information. Ideally, I would like to incorporate an animation (spinner) while the information is being rendered. Can anyone offer guidance or help with this ...

Having difficulty sending emails with Nodemailer

This is a simple example showcasing the usage of Nodemailer library. var http = require('http'); var port = process.env.PORT || 8080; var async = require('async'); var nodemailer = require('nodemailer'); // Creating a transp ...

What methods can I use to prevent a number from becoming negative?

I am currently developing a game where players collect resources, spend them to create more resources, and engage in various activities. However, I'm facing an issue where the resource count goes into negative numbers when too much of a certain item i ...

I am facing an issue with the Angular signup page that is using ui-router, as it is unable

I have been working on an Angular sign-up page and here is the project directory structure: signUpPage-Angular bin bower_components model mongodbApp.js node_modules **partials fail.html main.html succe ...

Preventing a JavaScript timer function from executing multiple times when triggered by an 'in viewport' function

I am trying to create a website feature where a timer starts counting up once a specific div is scrolled into view. However, I am encountering an issue where scrolling away restarts the timer, and I would like the final value that the timer reaches to rema ...

Assign the "this" keyword of App.vue to the Vuex state

I have discovered a workaround for accessing vue-router and other services that only works within a Vue component. By saving the "this" of the Vue app in the state of Vuex within the created option of App.vue. Is this a good approach or could it potential ...

transform pixel coordinates to latitude and longitude dimensions

Seeking clarification on how the geo referencing process functions for images. Is there a method to accurately extract latitude and longitude information from this specific line of code? imageBounds = [map.unproject([0, 0], 20), map.unproject([1716,1178], ...