xRa7eN

JavaScript nested array stumper

Recommended Posts

Hi hi guys, I do hope I am posting in the correct area. I written a couple clicker games for myself mostly too lean the language. So now I've been tricked out on a more complex game. And of course with complexity comes new methods of writing when using different aspects of the code. Which is why I like writing games.

Also, I want to do this in JavaScript, not jQuery. Just a personal preference.

 

The section of game is this: 20 mobs. Each of those mobs attack the player in nine waves. Inside of those waves are the criteria needed to beat that wave. 

I want to be able to access the data as follows:

To initialize:

Mob(1) = mobname

Mob(1).wave(1).hp = 100

....

Mob(19) = mobname

Mob(19).wave(1).hp = 100

Mob(mobxCnt).wave(currwavecnt).hp etc.

Unfortunately, I am at work so I cannot post the various codes I've tried. Most of them work but only 2 deep. I am used to programming in PHP which this is extremely simple tasks to do. However, I'm having difficulties with JavaScript and it's arrays.

How do I get the third set get the various criteria is inside that wave?

I'll be home in a few hours, if this is still a little blurry I'll post some of the codes I've tried.

 

Thanks for your assistance

Share this post


Link to post
Share on other sites

sure you want to stick to array? Object could also be an option.

requested Array JS

var mobxCnt = 100;
var currwavecnt = 80;
var Mob = []; // init 1st dimension of array

for (var i = 0; i < mobxCnt; i++) {
    for (var j = 0; j < currwavecnt; j++) {
        if (j === 0) {
            Mob = []; // init 2nd dimension of array
        }
        Mob[j] = 100; // set hp
    }
}

// access
console.log('Health: '+ Mob[42][23]);

---------------------

if you want more then just hp

var mobxCnt = 100;
var currwavecnt = 80;
var setHP = 100;
var setSpeed = 0.3;
var Mob = []; // init 1st dimension of array

for (var i = 0; i < mobxCnt; i++) {
    for (var j = 0; j < currwavecnt; j++) {
        if (j === 0) {
            Mob = []; // init 2nd dimension of array
        }
        Mob[j] = [setHP, setSpeed]; // set hp and speed as single vals in an array
    }
}

// access
console.log('Health: '+ Mob[42][23][0]);
console.log('Speed: '+ Mob[42][23][1]);

Share this post


Link to post
Share on other sites

another way is to make the 3rd layer an object. Sometimes it's nicer to access them by names = Object.keys

var mobxCnt = 100;
var currwavecnt = 80;
var setHP = 100;
var setSpeed = 0.3;
var Mob = [];

for (var i = 0; i < mobxCnt; i++) {
    for (var j = 0; j < currwavecnt; j++) {
        if (j === 0) {
            Mob = []; // init 2nd dimension of array
        }
        Mob[j] = {}; // init object as 3rd "layer"
        Mob[j].hp = setHP;
        Mob[j].speed = setSpeed;
    }
}

// access
console.log('Health: '+ Mob[42][23].hp);
console.log('Speed: '+ Mob[42][23].speed);

Share this post


Link to post
Share on other sites

I just wanted to hop on and say thank you for your suggestions. object is probably better, and I like referencing things by name for simplicity. I have some huge IRL jobs going on, but will take a look at this and maybe post a modified code of mine using one of your examples. thank you very much again.!

Share this post


Link to post
Share on other sites

OK, I think i have  "BASIC" understanding.. Let me know if this is correct:

So a "bracket" is used to make the basic traditional array

game [] which will give game[0], game[1] etc... correct?

Braces will give an object?

game{}, so game {name: coolplayer, hp:10}

which yeilds game.name // coolplayer?

then to combine, make your arrya first? then put in anything you want, but if you want another array, you use brackets again - like so?

game [ player[{name:'george', hp:25}]]

then I can pull it as such:   game[3].player[2].name // george

So do I have the gist of that? Seems to work when I test it. Totally not like arrays I am used to LOL, but unique and more flexable

 

 

So... when i get to this:

weapon = [
    {
        name, rank:[ {damagePerClk, cost} ]
    }
];

 


works fine if i manually insert data, but if I loop as shown below:

 

function initGame() {
    var wLength = weaponList.length;
    var sLength = spell.length;
    
    for(let i = 0; i < 14; i++) {
    
        weapon[i].name = weaponList[i];
        //spell[i].name = spellList[i];
        console.log(weapon[i].name);
    }
    
}

crashes. Says "i" is not defined, but that is not the issue. and stops at 1. (example, log shows 0,1 crash).   "i" is fine, and if i loop through a list - (spellist for example) it list all my spells as they are.  I am guessing it is how I have weapon defined (declared). Right?

 

 

Share this post


Link to post
Share on other sites

[] = array
{} = object
That's right and important ;)

this here works. I'm doing hard finding the prb without weaponsList.

var weapons = [
	{
		name: "Knife",
		rank: {
			damagePerClk: 2,
			cost: 1,
		},
	},
	{
		name: "BFG",
		rank: {
			damagePerClk: 9999,
			cost: 500,
		},
	},
];

for (var i = 0; i < weapons.length; i++) {
	console.log("Name: "+ weapons[i].name);
	console.log("damagePerClk: "+ weapons[i].rank.damagePerClk);
	console.log("Cost: "+ weapons[i].rank.cost);
}

 

it looks like you want to init your weapons in the initGame function. several way to do that.

var weapon = [];
var weaponList = ['Knife', 'BFG'];
var spell = ['Light', 'Fireball'];

function initGame() {
    var wLength = weaponList.length;
    var sLength = spell.length;
    
    for(let i = 0; i < wLength; i++) {
		weapon[i] = {}; // this is important, creates an object in weapon array
        weapon[i].name = weaponList[i];
        //spell[i].name = spellList[i];
        console.log(weapon[i].name);
    }
}

function initGame2() {
    var wLength = weaponList.length;
    var sLength = spell.length;
    
    for(let i = 0; i < wLength; i++) {
		// push the full object
		weapon.push({
			name: weaponList[i],
			anotherKey: 0.666}
		);
        console.log(weapon[i].name);
    }
}

function initGame3() {
    var wLength = weaponList.length;
    var sLength = spell.length;
    
    for(let i = 0; i < wLength; i++) {
		var tmp = {};
		tmp.name = weaponList[i];
		tmp.foo = "bar";
		weapon.push( tmp );
        console.log(weapon[i].name);
    }
}

hope this helps you.

Share this post


Link to post
Share on other sites

Let me soak some of this up.. I have been non-stop searching, reading and you tube and it slowly coming into focus

I have a QB64 code that is working. but it handles arrays differently (and no objects, instead I use TYPE but from the looks of it, that could be used as objects in JS)

but the other thing I see, is yes, I did try the above and it worked, the issue came in when I was trying to dynamically increase the array/object and have it auto put in new values for cost and dps  instead of doing all by hand.

As I kept experimenting, I found that it might be easier to break it down to the names in their own array. (its just for looks, and plays no role)

the items/ spells or weapons, in their own array with cost, dps

 gear[ {cost, dps}]

then i could use gear[gearlevel].cost,  gear[gearlevel].dps

then the other tracking level, gold, etc.. can be in a player object.

so that made sense to me, and simple, I could do that, but 20 items each having 10 upgrades and each with cost, dps or dpc can get redundant.

thats where I ran into the bump.

many languages I work with can do a  for x loop => gear[x].cost = xyz and gear[x].dps = xyz, loop, but when I did it, it got some goofy error of gear[x] not defined after the first iteration.

so if I read your code correctly, inserting the  gear = {} inside the loop should fix that, so that the cost,dps will then be inserted without error?

 

ps

I usually have lots of probs with code since I know quite a few languages, sometimes, the code syntax is correct, but not for the language I am working with LOL!!

 

 

Share this post


Link to post
Share on other sites

yes, init of the new object in the array is important.
It's important because later you want to access gear.something and gear has not yet been created.

That's where the error is coming from.

JS can not DIM an array from begin like it is possible in other languages.
You can DIM with var myArray = new Array(20) but this just creates empty entries and not objects, so you cant set the property "cost".

Have look here: https://www.w3schools.com/js/js_arrays.asp

var myArray = [];
Dim(myArray, 20);

// maybe you like this more than the for i=0;i<myArray.length;i++ loop
for (key in myArray) {
	myArray[key].cost = 20;
}

// another way to fill it
myArray.forEach(setDmg);

console.log(myArray); // shows filled array

function Dim(arr, size) {
	for (let i = 0; i < size; i++) {
		myArray.push({});
	}
}

function setDmg(entry) {
	entry.dmg = 10;
}

Working with the good old arrays is absolute no problem and a clean way to do that.
Try to make it easy for you to understand that code again if you dig it out in some years.

Share this post


Link to post
Share on other sites

OK

Here is what i was able to come up with, research arrays.

var weaponLevelNfo = Array.from({length:14}, () => Array.from({length:9}, () => [0, 0]));

Very simple, and allows instant assigning off array at any level. The clean up part, will be to make it an object so I can read it better example

 

weaopnLevelNfo[x][y].cost vs weaponLevelNfo[x][y][z]. 

Currently not an issue, as there are only two indexes to be concerned about.

Share this post


Link to post
Share on other sites
var arr2d = [
  [ {hp: '00'}, {hp: '01'} ],
  [ {hp: '10'}, {hp: '11'} ]
]

Does this help?

Now you have nested arrays, which you can access like `arr2d[0][1]` and get back an object?

i.e.

console.log(arr2d[0][0])
// {hp: '00'}

console.log(arr2d[0][0].hp)
// '00'

Technically you could perform some weird mapping, i.e.

[ hp, someOtherVariable ]

But, honestly, its just a pain. I'm not even totally convinced it becomes more memory efficient (it looks like it should be, but, JS is weird, I wouldn't bet on it, in any case, the saving would be tiny and you could maybe lose access performance, again, hard to tell).

Generally, rather than accessing directly each 'cell' inside your nested array structure, you might make things a little more readable by doing:

// Don't do this
arr2d[0][0].hp

// Try this, more readable
var entity = arr2d[0][0]
entity.hp

// Even better, but, more abstraction
function get (x, y, data) {
  return data[y][x]
}

var entity = get(0, 0, arr2d)
entity.hp

Note that `get` is a helper function and note the positions of `x` and `y` very carefully, this is not a typo.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.