Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411516 Posts in 69380 Topics- by 58436 Members - Latest Member: GlitchyPSI

May 01, 2024, 05:54:34 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Undefined terms in an array
Pages: [1]
Print
Author Topic: Undefined terms in an array  (Read 2120 times)
Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« on: July 22, 2010, 07:02:31 PM »

Okay, so I'm working on some procedural dungeon generation code. I have a createTunnel function that randomly selects a starting point (randomY , randomX), then loops a set number of times through a routine that (1) creates an array with the four cardinal directions, (2) goes through and culls directions that lead to an already-existing room or off the end of the array, (3) randomly selects from the remaining directions, and (4) adds a room there, resetting randomX and randomY to the new coordinates for the next cycle.

Here's the problem: whenever Flash checks a direction that would lead off the end of the array as part of step 2 of the routine, it throws this error at me: Error #1010: A term is undefined and has no properties.

Here is the relevant code:

Code:
var tunnelDir:Array = ["left" , "right" , "up" , "down"];	//create array of possible directions

var newY:int = randomY + 1; //check below;
if ( floorArray[newY][randomX] != 0 || newY > floorArray.length ) { //if the space is a room or off the map
tunnelDir.splice( 3 , 1 ); //splice it from the array
}

newY = randomY - 1; //check above;
if ( floorArray[newY][randomX] != 0  || newY < 0 ) { //if the space is a room or off the map
tunnelDir.splice( 2 , 1 ); //splice it from the array
}

var newX:int = randomX + 1; //check right;
if ( floorArray[randomY][newX] != 0 || newX > floorArray[0].length ) { //if the space is a room or off the map
tunnelDir.splice( 1 , 1 ); //splice it from the array
}

newX = randomX - 1; //check left;
if ( floorArray[randomY][newX] != 0  || newX < 0 ) { //if the space is a room or off the map
tunnelDir.splice( 0 , 1 ); //splice it from the array
}

I tried recoding it so it won't try to return a value for newY or newX that extend past the edges of the array, but I still get the same error anyway:

Code:
var newY:int = randomY + 1;						//check below;
if ( newY > floorArray.length ) { //if the space is off the map
tunnelDir.splice( 3 , 1 ); //splice it from the array
}
else if ( floorArray[newY][randomX] != 0 ) { //if the space is a room
tunnelDir.splice( 3 , 1 ); //splice it from the array
}

newY = randomY - 1; //check above;
if ( newY < 0 ) { //if the space is off the map
tunnelDir.splice( 2 , 1 ); //splice it from the array
}
else if ( floorArray[newY][randomX] != 0 ) { //if the space is a room
tunnelDir.splice( 2 , 1 ); //splice it from the array
}

//etc.

I assume that there's some principle here I'm missing. Does anyone know how I can get around this problem?
Logged

eugeneius
Level 0
**



View Profile WWW
« Reply #1 on: July 22, 2010, 07:42:27 PM »

You should be using >= instead of > to check if an index is after the end of an array - any time you take the "opposite" of an inequality sign you need to add/remove the equals. I'm pretty sure that's your main problem.

You can write your if statements the way you have them in the first code snippet, you just have to reverse the order of the conditions. The way most languages check if statements is short-circuit evaluation - basically once enough conditions have been checked to decide whether to enter the block or not the evaluation stops, so you can write later conditions that depend on earlier ones.

Code:
var tunnelDir:Array = ["left" , "right" , "up" , "down"];

var newY:int = randomY + 1;
if ( newY >= floorArray.length || floorArray[newY][randomX] != 0 ) {
tunnelDir.splice( 3 , 1 );
}

newY = randomY - 1;
if ( newY < 0 || floorArray[newY][randomX] != 0 ) {
tunnelDir.splice( 2 , 1 );
}

var newX:int = randomX + 1;
if ( newX >= floorArray[0].length || floorArray[randomY][newX] != 0 ) {
tunnelDir.splice( 1 , 1 );
}

newX = randomX - 1;
if ( newX < 0 || floorArray[randomY][newX] != 0 ) {
tunnelDir.splice( 0 , 1 );
}

A clearer way to write the whole thing could be to start with an empty array of directions, check each one and only add those that are valid:

Code:
var tunnelDir:Array = [];

var newY:int = randomY + 1;
if ( newY < floorArray.length && floorArray[newY][randomX] == 0 ) { // if the tile is within bounds and not a room
tunnelDir.push( "down" );
}

[...]
Logged

Flash Dump <- ActionScript noobery
Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #2 on: July 22, 2010, 07:48:20 PM »

Oh, jeez! How stupid! I can't believe I didn't notice that. Thanks for the help, and sorry for wasting your time with a stupid question.
Logged

Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #3 on: July 23, 2010, 11:14:29 AM »

Actually, I retract my previous post--I'm getting undefined term errors when newY or newX are < 0. Huh?
Logged

eugeneius
Level 0
**



View Profile WWW
« Reply #4 on: July 23, 2010, 02:45:11 PM »

If newY or newX are < 0 then you shouldn't use them, since they're pointing outside of your array bounds. Do you mean that you check that they're at least 0, but then you get an error when accessing the array?

You may have dealt with this already, but you do realise that at some point no direction will be valid, and the tunnelDir array will be empty? Unless your code to randomly select a new direction is written in a way that can handle this you could get the same error there as well.

Feel free to post your code again if you still can't figure it out. It's exciting to see a problem on here that I can help with for once Durr...?
Logged

Flash Dump <- ActionScript noobery
st33d
Guest
« Reply #5 on: July 23, 2010, 02:53:30 PM »

If you dig your dungeon on a bitmap, you won't get any errors for going out of bounds and you'll be able to look at an illustration of your entire dungeon. You can always convert the bitmap to game content after your algorithm is done (and you can test iterations much quicker).
Logged
Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #6 on: July 23, 2010, 03:03:25 PM »

@eugeneius: I just check to see that they are not below zero--Flash spits back an error at me if they are.

You may have dealt with this already, but you do realise that at some point no direction will be valid, and the tunnelDir array will be empty? Unless your code to randomly select a new direction is written in a way that can handle this you could get the same error there as well.

Yeah, I've dealt with that already--this is the code that follows the checks posted above, where the game randomly chooses a direction to dig from the array. If all directions are struck out of the array, it selects "same" and just keeps digging the same square until the while loop is done with:

Code:
if (tunnelDir.length > 0) {
var randomInt:int = Math.floor(Math.random() * tunnelDir.length);
var randomDir:String = tunnelDir[randomInt];
}
else {
randomDir = "same";
}

If you dig your dungeon on a bitmap, you won't get any errors for going out of bounds and you'll be able to look at an illustration of your entire dungeon. You can always convert the bitmap to game content after your algorithm is done (and you can test iterations much quicker).

I'm not sure what you're talking about here. Dig it on a bitmap? Like, draw little squares with code rather than creating an array?
Logged

agj
Level 10
*****



View Profile WWW
« Reply #7 on: July 24, 2010, 10:07:51 AM »

Actually, I retract my previous post--I'm getting undefined term errors when newY or newX are < 0. Huh?

Could you post the new code and indicate which line causes that error?

I'm not sure what you're talking about here. Dig it on a bitmap? Like, draw little squares with code rather than creating an array?

I think he means to consider each pixel a room.
Logged

Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #8 on: July 24, 2010, 11:13:07 PM »

Could you post the new code and indicate which line causes that error?

Yes:

Code:
var tunnelDir:Array = ["left" , "right" , "up" , "down"];	//create array of possible directions

var newY:int = randomY + 1; //check below;
if ( floorArray[newY][randomX] != 0 || newY >= floorArray.length ) { //if the space is a room or off the map
tunnelDir.splice( 3 , 1 ); //splice it from the array
}

newY = randomY - 1; //check above;
if ( floorArray[newY][randomX] != 0  || newY < 0 ) { //if the space is a room or off the map
tunnelDir.splice( 2 , 1 ); //splice it from the array
}

var newX:int = randomX + 1; //check right;
if ( floorArray[randomY][newX] != 0 || newX >= floorArray[0].length ) { //if the space is a room or off the map
tunnelDir.splice( 1 , 1 ); //splice it from the array
}

newX = randomX - 1; //check left;
if ( floorArray[randomY][newX] != 0  || newX < 0 ) { //if the space is a room or off the map
tunnelDir.splice( 0 , 1 ); //splice it from the array
}

I'm getting errors from these lines whenever newX or newY is less than zero:

if ( floorArray[newY][randomX] != 0  || newY < 0 ) {
if ( floorArray[randomY][newX] != 0  || newX < 0 ) {


EDIT: I just tried eugeneius's suggestion, with a minor variation so Flash would never ever be checking the value of the array when there isn't an array entry there, and it works!

Code:
var tunnelDir:Array = new Array ();	//create array of possible directions

var newY:int = randomY + 1; //check below;
if ( newY < floorArray.length ) { //if the space is on the map
if ( floorArray[newY][randomX] == 0 ) { //and not a room
tunnelDir.push( "down" ); //add it to the array
}
}

newY = randomY - 1; //check above;
if ( newY >= 0 ) { //if the space is on the map
if ( floorArray[newY][randomX] == 0 ) { //and not a room
tunnelDir.push( "up" ); //add it to the array
}
}

var newX:int = randomX + 1; //check right;
if ( newX < floorArray[0].length ) { //if the space is on the map
if ( floorArray[randomY][newX] == 0 ) { //and not a room
tunnelDir.push( "right" ); //add it to the array
}
}

newX = randomX - 1; //check left;
if ( newX >= 0 ) { //if the space is on the map
if ( floorArray[randomY][newX] == 0 ) { //and not a room
tunnelDir.push( "left" ); //add it to the array
}
}

Thanks for the  help. Smiley
« Last Edit: July 24, 2010, 11:25:47 PM by Craig Stern » Logged

agj
Level 10
*****



View Profile WWW
« Reply #9 on: July 25, 2010, 11:00:54 AM »

Right, you're supposed to check if the value is within bounds before you access the array.
Logged

roboprez
Level 1
*


Got to love them pixels


View Profile WWW
« Reply #10 on: July 28, 2010, 04:01:43 AM »

Interesting, i'm currently working on a dungeon game in AS3 that generates tunnels and rooms...

I just made my Array REALLY BIG so there was no chance that a room would try to create itself outside of the world.
Now one really annoying problem I had with array's is when I was auto tiling the map. To fix this I wrapped the map in two coatings of OUT tiles. Then when checking the 9 tiles on every side of every tile (auto-tiling was frustrating) just don't run the check when it's on the side
  • or the end [map.length-1].

...I ranted a bit there didn't I?
Anyway do you have a devlog for your game? I would really like to see what you do...
Logged

frederiksen
Guest
« Reply #11 on: July 28, 2010, 04:39:27 AM »

I'm not sure what you're talking about here. Dig it on a bitmap? Like, draw little squares with code rather than creating an array?


i think what st33d means is, create a bitmapdata with the dimensions of your array, and than use the getPixel and setPixel values, if it's out of bounds it will just return zero(i think). Like he said the upside is you quickly have a nice little minimap to see what your dungeons look like. 
Logged
Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #12 on: July 28, 2010, 05:26:48 AM »

Anyway do you have a devlog for your game? I would really like to see what you do...

Thanks! I haven't been devlogging it, unfortunately, as it's mostly something I've been writing in little 30-minute snippets on the train ride to and from work, when I have no extra time or internet connection to do so. If I decide to finish the thing, though, and people are interested, I might do a little post-mortem where I talk about the  process of designing the game engine.
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic