As3 Best solution about arrays - arrays

Let me cut to the main issue, I have a grid which is 50 by 50. And I need a way of having a true or false variable for each cell in the grid and the default value would be false, every time the method is called.
I need the array so I can see which cells I have visited so I don't need to revisited them for my path finding system that I'm working on .
But currently I have a double array[] [] which I need to loop every time I use this method. (up to 3 times a second but mostly never) which means looping 2500 value. Which doesn't sound very good. What would be the best solution, is this the best solution or am I missing something stupid.
Hope you can help and point me into the right direction.

Another possible improvement is using a single-dimensional vector, maybe wrapped into a class, that will contain 2500 elements and its indexes would mean (width*50+height). Like this:
private var _visited:Vector.<Boolean>;
function checkVisited(x:int,y:int):Boolean {
return _visited(x*50+y); // x and y are in 0-49 range
}
Vectors can be two-dimensional should you need them, you declare vector of vectors like this:
var _visited:Vector.<Vector.<Boolean>>;
Initialize with pushing the filled Vector.<Boolean> once, then just change the elements as you do with a normal array.
The main advantage of vectors is that they are solid, that is, if there are 50 elements in a vector, you are sure that there exists a value at any index from 0 to 49 (even if null, or NaN in case of Numbers), this also makes internal processing of vectors easier, as the Flash engine can calculate proper memory location by just using the index and the link to the vector, which is faster than first referencing the array about whether there is a value at that index, if yes, get its memory location, then reference.

From my experience of making tile based games with different grids I usually have a Tile class, that will contain all your necessary values, most typical would be:
posX:int
posY:int
isChecked:Boolean
You can add as many as you need for your app.
Then I have a Grid class that will create you grid and have some useful methods like giving neighbor tiles.
In the Grid class I make the grid this way:
public var tileLineArray:Vector.<Tile>;
public var tile2dArray:Vector.<Vector.<Tile>>;
public function makeGrid(w:int, h:int):void
{
tileLineArray = new Vector.<Tile>();
tile2dArray = new Vector.<Vector.<Tile>>();
for (var i:int = 0; i < gridWidth; i++)
{
var rowArray:Vector.<Tile> = new Vector.<Tile>();
for (var j:int = 0; j < gridHeight; j++)
{
var t:Tile = new Tile();
t.posX = i;
t.posY = j;
tileLineArray.push(t);
rowArray.push(t);
}
tile2dArray.push(rowArray);
}
}
What it will give you is that you can access tiles in a single line to by coordinates x,y;
var myTile:Tile = tileLineArray[lineID];
var myTile:Tile = tile2dArray[targetX][targetY];
I use Vectors in this example as they outperform Arrays and you keep the type of the stored object intact.
It is not a problem for Flash to loop through the array; if you want improve performance, break the loop if you've done all what you wanted with it, continue the loop if the tile does not meet the requirements and you don't need to process it.
Also, having a 2d array can improve performance, since you can process only the area of the array that you need.
One more advice is not to be afraid to make X more smaller arrays to store some data from the bigger array and loop trough the small ones. As the data of the arrays is not a primitive (int, uint etc.) but a Class, it will hold a pointer/reference to the object, so you're not actually making copies of the objects every time.

Related

Operate multiple arrays simultaneously

I am using as3 in adobe animate to create a video game.
I have created multiple arrays with movie clips e.g.
var A:Array [mc1, mc2, mc3]
var B:Array [mc4, mc5, mc6]
var C:Array [mc7, mc8, mc9]
var anObject:DisplayObject;
How can I operate all movie clips in all arrays simultaneously?
I have tried this:
mc_Player.addEventListener(MouseEvent.CLICK, Change_Position);
function Change_Position (event:MouseEvent):void
{
{for each (anObject in A) & (anObject in B) & (anObject in C) // how can I get this right?
{anObject.x -= 100;
}}
}
I am also trying to understand if there is a way to operate all movie clips in my project simultaneously without using arrays.
e.g.
mc_Player.addEventListener(MouseEvent.CLICK, Change_Position);
function Change_Position (event:MouseEvent):void
{
{all movie_clips // how can I get this right?
{anObject.x -= 100;
}}
}
Thank you.
There's no such thing as simultaneous in programming (well, unless you are multi-threading with the perfect sync, which is not an AS3 story at all).
There are to ways to get close to that simultaneous thing:
Put all the objects into a single container. You will be able to change x and y of that container so all the in-laid objects will change their visible positions at once. The downside is that you cannot rotate or scale them individually (think of them as clipped to a board and imagine you rotate the whole board), or you won't be able to move half of them.
Arrays and loops. You iterate through all the items one by one, very fast. It looks simultaneous from the outside, but it never is.
All that said, in order to achieve the things you want you need to figure a way to put all the objects you want to process simultaneously into a single Array and then do the thing you want on them.
Case №1: many Arrays to one.
// This methods takes a mixed list of items and Arrays
// and returns a single flattened list of items.
function flatten(...args:Array):Array
{
var i:int = 0;
// Iterate over the arguments from the first and on.
while (i < args.length)
{
if (args[i] is Array)
{
// These commands cut the reference to the Array
// and put the whole list of its elements instead.
aRay = [i,1].concat(args[i]);
args.splice.apply(args, aRay);
}
else
{
// The element is not an Array so let's just leave it be.
i++;
}
}
return args;
}
Then all you need to do is to get a single list out of your several Arrays:
var ABC:Array = flatten(A, B, C);
for each (var anObject:DisplayObject in ABC)
{
anObject.x -= 100;
}
Performance-wise, it is a good idea to pre-organize, if logically possible, these Arrays so you don't have to compile them each time you need to process all the objects. Simply, if sometimes you would need A + B, and sometimes B + C, and sometimes A + B + C, just create them and have them ready. If you know what you are going to deal with, you won't even need that complicated flatten method:
var AB:Array = A.concat(B);
var BC:Array = B.concat(C);
var ABC:Array = A.concat(B).concat(C);
Case №2: all the children at once. As I already explained in my answer to one of your previous questions, you can iterate over all the children of a certain container, and you can put them into — guess what — Array for later use. Also, you can filter the objects while doing so and put only those ones you actually want to be there.
var ALL:Array = new Array;
// Iterate over the amount of children of "this" container.
for (var i:int = 0; i < numChildren; i++)
{
// Obtain a reference to the child at the depth "i".
var anObject:DisplayObject = getChildAt(i);
// Here go possible criteria for enlisting.
// This will ignore texts and buttons.
// if (anObject is MovieClip)
// This will take only those with names starting with "mc".
if (anObject.name.substr(0, 2) == "mc")
{
ALL.push(anObject);
}
}
// Viola! You have all the objects you want in a single Array
// so you can bulk-process them now, which is ALMOST simultaneous.

Actionscript/Animate - Fill in next array spot if this one is already filled

so I am working on a graphical calculator (bit more of a challenge than the basic windows one), and I want to be able to do the entire "math" in one textfield, just like typing in "5+3-5*11/3" and it gives you the solution when you press '='
I decided to make it with arrays of numbers and symbols, but I have no idea how to make it to fill the next array if this one already is used:
var numbers:Array = new Array("","","","","","","","","","","","","","","","");
var actions:Array = new Array("","","","","","","","","","","","","","","","");
I am using split to split the numbers I input with symbols, and I want the numbers to be placed in the arrays. Example: I type in 555+666 and then I need to have something like
if (numbers[0] = "") {numbers[0] = 555}
else if (numbers[1] = "") {numbers[1] = 555}
else if.....
Know what I mean?
Pretty hard to describe...
something like... When I type in a number, if the numbers[0] is already filled, go fill in numbers[1], if numbers[1] is filled, go to numbers[2] etc
Even if I agree with #Nbooo and the Reverse Polish Notation
However Vectors may have a fixed length.
This is not an answer but just an example (if the length of Your Array must be defined):
//Just for information..
var numbs:Vector.<Number> = new Vector.<Number>(10,true);
var count:uint = 1;
for (var i in numbs){
numbs[i] = count++
}
trace(numbs);
// If You try to add an element to a Vector,
// You will get the following Error at compile time :
/*
RangeError: Error #1126: Cannot change the length of a fixed Vector.
at Vector$double/http://adobe.com/AS3/2006/builtin::push()
at Untitled_fla::MainTimeline/frame1()
*/
numbs.push(11);
// Will throw an Error #1126
trace(numbs);
If You use this code to update a fixed Vector, this will not throw an ERROR :
numbs[4]=11;
trace(numbs);
Output :
1,2,3,4,5,6,7,8,9,10
1,2,3,4,11,6,7,8,9,10
// length is 10, so no issue...
If You consider the performance between Arrays and vectors check this reference : Vector class versus Array class
I hope this may be helpful.
[EDIT]
I suggest you to check at those links too :
ActionScript 3 fundamentals: Arrays
ActionScript 3 fundamentals: Associative arrays, maps, and dictionaries
ActionScript 3 fundamentals: Vectors and ByteArrays
[/EDIT]
Best regards.
Nicolas.
What you want to implement is the Reverse Polish Notation. In actionscript3 arrays are dynamic, not fixed size, that means you can add elements to the array without concern about capacity (at least in your case).
const array:Array = new Array();
trace(array.length); // prints 0
array.push(1);
array.push(2);
trace(array.length); // prints 2
I suggest using "push" and "pop" methods of Array/Vector, since it's much more natural for such task. Using those methods will simplify your implementation, since you'll get rid of unnecessary checks like
if (numbers[1] == "") {...}
and replace it just with:
numbers.push(value);
and then to take a value from the top:
const value:String = numbers.pop();

Usage of empty array allocation for custom class

Say, we have a class Car
classdef Car < handle
properties
wheels = 4;
end
methods
function obj = Car()
end
end
end
We can create ten cars like so
cars = Car.empty();
for ii = 1:10
cars(end+1) = Car;
end
However, one can make an empty array of cars first
>> cars = Car.empty(0,10)
cars =
0x10 Car array with properties:
wheels
What I do not understand: If one now puts a single car in it, the array seems to shrink to a single element
>> cars(1) = Car
cars =
Car with properties:
wheels: 4
So, does allocating such an empty array make any sense? What are the use cases?
First of all, note that your question is not directly related to custom classes - you can do this with any MATLAB variable type. For example,
>> a = double.empty(0,10)
a =
Empty matrix: 0-by-10
So your questions are
What I do not understand: If one now puts a single car in it, the array seems to shrink to a single element
Well no, it has grown to a single element. I guess there is an ambiguity here, in that you might expect it to grow not to a 1x1 array but to a 1x10 array, with the other nine elements that weren't directly assigned being set to default (i.e. zero in the case of doubles or other numbers, or to a default element in the case of a custom class). However, I think the only thing to say there is that that's not what MATLAB does.
does allocating such an empty array make any sense? What are the use cases?
The use cases are very few in general, really just edge cases. The capability of having arrays of with zero-length dimensions is obviously required to be there for consistency, but an array of 0x10 is rarely much different in behaviour from an array of 0x0.
If I have an array that may vary in height but will always be 10 wide, I might predefine it as 0x10 rather than 0x0, just to leave myself a reminder in the code of that fact.
Also note that there are differences in behaviour between [] and double.empty(0,0). For example
>> a = rand(4,2)
a =
0.83625 0.19468
0.58508 0.12698
0.44332 0.8509
0.51858 0.3673
>> a(2,:) = []
a =
0.83625 0.19468
0.44332 0.8509
0.51858 0.3673
>> a(2,:) = double.empty(0,0)
Subscripted assignment dimension mismatch.
>> a(2,:) = double.empty(0,2)
Improper assignment with rectangular empty matrix.
This is because = [] is a special piece of MATLAB syntax that is used for deleting rows, rather than literally constructing the empty array and then assigning it. So there's another use case there, i.e. preventing accidental deletion of rows.
This is not a problem related to object programming but a normal behavior which is more general in Matlab.
For instance:
>> a = NaN(0,10);
>> a(1) = 5;
>> a
a =
5
When you define an array of size 0xn Matlab does not allocate any memory to it, since there is no element. So a call to empty(0,10) should not be considered as a pre-allocation.
When you define the first element of the array, you force a resizing, and during resizing Matlab always adopts the minimal possible size for the array.
The empty syntax is useful to define an array that will be filled by aggregation in a loop with the end+1 syntax, for instance:
a = NaN(0,2);
for i = 1:10
a(end+1,:) = [i i^2];
end
Best,

Multidimensional array of texture in Unity3d

I have some textures those i need to show in diffrent scrollviews dynamically.
for naming convention i am using below approach
texturename24
texturename - This prefix is associated with every texture.
2- This represents a particular category of texture i.e. dot. stripes , etc.
4 - This is for serial number of texture
with below lines of code i am fetching textures from resource folder
var textures : Object[];
textures = Resources.LoadAll("TextureFolder");
i need to make array for every pattern suppose texturename00,01,02,03 should be in one array and texturename10,11,12,13 should be other array, here i need to crate dynamic array on the basis of patterns count.
I've been thinking about this for the past few days and basically I can't think of a single use case for what you're doing that wouldn't be better solved by implementing a simple sprite sheet solution. You could also acquire any of the hundreds of available solutions out there that implement sheet-based solutions to this problem.
Loading a texture is not a trivial task for the engine and whenever possible you want to limit your inode access. Using a single Atlas texture that has all of your sub-images placed at regular intervals would be one easy solution. You would then iterate over the map and assign mainTextureOffsets for each material that uses the same image. You can also use irregular placement but for that you'll need some kind of transient medium to store the offset values.
Rather than storing the texture2d in memory in this solution; you will instead be storing Vector2 structs which are far less memory intense. If you have a use case that falls outside the parameters of what you can do with sprite sheets (Atlas maps) you'll have to detail it fully here so we can help you further but I'm fairly certain this will get you to a solution in the most efficacious manner.
FIDDLE DEMO
var outer_array = [];
var inner_array = [];
for (var i = 0; i < 35; i++) {
inner_array.push(i);
if (inner_array.length == 4) {
outer_array.push(inner_array);//push the array[0,1,2,3] and so on in to outer array.
inner_array = [];//this will empty my array
i = i + 6;//to jump from 4 to 10,14 to 20 and so on..
}
}
console.log(outer_array)
I find a way to do this.
Declare a 2d array and set row and column to 100 and use below lines of code.
noOfPattern and noOfColors are integers to get the count of row and columns of 2d array.
var arrAll = new Texture2D[100,100];
for(var p=0 ; p<100 ; p++){
TextureP = Resources.Load("FolderName/"+"ImageName"+p+0);
if(TextureP !=null){
for(var q=0 ; q<100 ; q++){
TextureQ = Resources.Load("FolderName/"+"ImageName"+p+q);
if(TextureQ !=null){
arrAll[p,q] = TextureQ;
noOfColors = q;
}
}
noOfPattern = p;
}
}

C++ What is the best data structure for a two dimensional array of object "piles"?

The size of the grid will be known at the start (but will be different each time the program starts). However, the DEPTH of each cell is not a mere value, but rather a population of objects that will vary constantly during runtime.
Q: What is the most recommended (efficient and easy to maintain; less prone to user error) way of implementing this ?
Is this some kind of a standard 2D array of vector pointers ?
Is it a 3D Vector array ?
Is it a 2D array of linked lists, or binary trees (I am thinking binary trees will add complexity overhead because of continuous deletion and insertion node-gymnastics)
Is it some other custom data structure ?
Use a 1D array for best cache locality. A vector would be fine for this.
std::vector<int> histdata( width * height );
If you need to index the rows quickly, then make something to point into it:
std::vector<int*> histogram( height );
histogram[0] = &histdata[0];
for( int i = 1; i < height; i++ ) {
histogram[i] = histogram[i-1] + width;
}
Now you have a 2D histogram stored in a 1D vector. You can access it like this:
histogram[row][col]++;
If you wrap all this up in a simple class, you're less likely to do something silly with the pointers. You can also make a clear() function to set the histogram data to zero (which just rips through the histdata vector and zeros it).

Resources