How to use a double array in objective c? - objective-c

I'm trying to use a double array to make a ccp. So I'm looping through my array called grid1x for the X axis and grid1y for the Y axis like so:
for (int i = 0; i < [grid1x count]; i++)
{
p = ccp(x*sw/768,sh-y*sh/1024);
grab = [[Grab alloc] initWithPosition:p];
[grabs addObject:grab];
[batch1 addChild:grab z:5];
[grab release];
}
The line
p = ccp(x*sw/768,sh-y*sh/1024);
Works perfect when I provide x and y individually, but I cannot figure out how to use them at the index position of the array. I do know to use [grid1x objectAtIndex:i]; but cannot get it to work either.

Related

Using malloc to create a 2d C style array of my class

(Edit: put possible solution at end)
I'm a C/C++ programmer who is learning Objective C to develop iPhone apps. The programs that I will be writing will deal with large 2d arrays of objects. I've read about using NSArray's of NSArray's and have some working code, but I'm trying to understand how to use C style arrays to save overhead and to learn what you can and can't do.
In this fragment MapClass only contains two properties, int x and int y. I have the following code fragment working with a statically defined array of 10x10.
MapClass *arr[10][10];
arr[2][3] = [[MapClass alloc] init];
arr[2][3].x = 2;
arr[2][3].y = 3;
NSLog(#"The location is %i %i", arr[2][3].x, arr[2][3].y);
// Output: "The location is 2 3"
This is an example of doing it with a one dimensional array and calculating where the cell is based on the X and Y:
MapClass **arr = (MapClass**) malloc(10 * 10 * sizeof(MapClass *));
arr[3 * 10 + 2] = [[MapClass alloc] init];
arr[3*10 + 2].x = 2;
arr[3*10 + 2].y = 3;
NSLog(#"The location is %i %i", arr[3*10 + 2].x, arr[3*10 + 2].y);
// Output: "The location is 2 3"
My question is this: How can I malloc my array as a two dimensional array so that I can use arr[2][3] style notation to access it?
Everything I'm trying is generating various errors such as "Subscript requires the size of [your class], which is not constant in non-fragile ABI".
Can anyone give me a snippit on how to do this? I've been reading and experimenting and can't figure it out. Does my one dimensional array example do anything wrong?
Answer?
After fooling around with xzgyb's answer, I have the following block working. Anything wrong with it? Thanks!
int dimX = 20;
int dimY = 35;
MapClass ***arr = (MapClass***) malloc( dimX * sizeof(MapClass **));
for (int x = 0; x < dimX; ++x)
{
arr[x] = (MapClass **) malloc( dimY * sizeof(MapClass*));
}
for (int x = 0; x < dimX; ++x)
{
for (int y = 0; y < dimY; ++y)
{
arr[x][y] = [[MapClass alloc] init];
arr[x][y].x = x;
arr[x][y].y = y;
}
}
for (int x = 0; x < dimX; ++x)
{
for (int y = 0; y < dimY; ++y)
{
NSLog(#"%i %i is %i %i", x, y, arr[x][y].x, arr[x][y].y);
}
}
// Cleanup
for (int x = 0; x < dimX; ++x) {
for (int y = 0; y < dimY; ++y) {
[arr[x][y] release];
}
}
for (int x = 0; x < dimX; ++x)
{
free(arr[x]);
}
free(arr);
Try the followed code:
MapClass ***arr = (MapClass***) malloc(10 * 10 * sizeof(MapClass *));
for ( int row = 0; row < 10; ++row ) {
arr[ row ] = (MapClass **)&arr[ row * 10 ];
}
arr[0][1] = [[MapClass alloc] init];
arr[1][2] = [[MapClass alloc] init];
Tested and it works fine using NSMutableString class and a variety of string methods.
I'd probably recommend using the standard message sending brackets than using the newer dot operator syntax just to simplify to the compiler what you are actually trying to accomplish.
The sizeof(ClassName ) should be the same as sizeof([ClassName class]) (and int or id for that matter) if I understand your meaning. The code you posted should not give an error like that as all pointers will be the same size. Now if you tried something like sizeof(*someInstanceOfAClass) then you're running into some issues because you're attempting to malloc enough memory to fit 10*10*(the actual size of your object) which is not what you're intending to do. (And sounds like what your warning is intended for.)

Nested for loop array initialization

I want to initialize a 2-d array gameBoard and display the result on screen. Will the following nested for loops work? I'm having trouble displaying it on the screen so I can't tell if this is working correctly or not.
for (NSInteger x = 0; x <= 2; x++)
{
for (NSInteger y = 0; y <=2; y++)
{
gameBoard [x][y] = 0;
NSLog(#"%ld"), gameBoard [x][y];
}
}
Your NSLog line is wrong, but other than that you're ok (assuming your array is appropriately sized, that is). Change the log line to:
NSLog(#"%ld", gameBoard[x][y]);
to get some actual output. Now that I look again, I think your example won't even compile cleanly the way it is.

Shuffling an array of NSNumbers & converting back to ints

I have an NSMutableArray urlArray of size n, I want to randomly choose 4 of these URLs from the total number of elements in the array.
However I don't want to shuffle urlArray directly, I'd prefer to make an "indexArray" [0 ... (n-1)] & shuffle these, & then use the first 4 elements of the shuffled indexArray to decide which elements I choose from urlArray.
First off I created the indexArray as follows:
for (int i = 0; i < numberOfStems; i++) {
[indexArray addObject:[NSNumber numberWithInteger:i]];
}
This allowed me to shuffle my indexArray, so far so good. Because I used the
[NSNumber numberWithInteger:i] method, the elements in the shuffled indexArray are NSNumbers.
Is there a way to convert the NSNumber objects in indexArray into ints?
I attempted to use the intValue function but this didn't appear to be what I needed.
I also tried creating a c style array but that wasn't so successful either - I'd like to stick with objective-c syntax if possible.
Any ideas? any hints appreciated :)
Why don't you just create a normal c array, shuffle that and then use the first four integers in the array as the for random index?
something like
int* index = malloc(numberOfStems*sizeof(int));
for (int i = 0; i < numberOfStems; ++i)
{
index[i] = i;
}
for (int i = numberOfStems - 1; i > 0; --i)
{
int randomIndex = arc4random() % i;
int tmp = index[i];
index[i] = index[randomIndex];
index[randomIndex] = tmp;
}
now use index to access the URL's
EDITED: updated algorithm (although not really related to OP question)
For a temporary array that stores only integers and gets thrown away after a relatively short task I would definitely prefer a C-style array: this would avoid a great deal of overhead, and is also simple to read.
int *array = (int*)malloc(sizeof(int)*numberOfStems);
for (int i = 0 ; i != numberOfStems ; i++) {
array[i] = i;
}
// Do the shuffle
// Pick first four, and do whatever you need to do
// ...
// Now that you are done with the array, do not forget to free it:
free(array);

How to cycle through an array of CGPoints

I have created an array of 16 CGpoints representing 16 positions on a game board. This is how i set up the array CGPoint cgpointarray[16]; I would like to create a for loop to cycle through each item in the array and check if the touch is within x distance of a position (i have the position as a CGPoint. I don't have much experiance with xcode or objective c. I know the python equivalent would be
for (i in cgpointarray){
//Stuff to do
}
How would i accomplish this? Thanks
for (int i = 0; i < 16; i++){
CGPoint p = cgpointarray[i];
//do something
}
Or if you want to use the NSArray Class:
NSMutableArray *points = [NSMutableArray array];
[points addObject:[ NSValue valueWithCGPoint:CGPointMake(1,2)]];
for(NSValue *v in points) {
CGPoint p = v.CGPointValue;
//do something
}
( not tested in XCode )
This should do it:
for (NSUInteger i=0; i < sizeof(cgpointarray)/sizeof(CGPoint); i++) {
CGPoint point = cgpointarray[i];
// Do stuff with point
}
I would normally go for the NSValue approach above but sometimes you are working with an API where you can't change the output. #Andrews approach is cool but I prefer the simplicity of .count:
NSArray* arrayOfStructyThings = [someAPI giveMeAnNSArrayOfStructs];
for (NSUInteger i = 0; i < arrayOfStructyThings.count; ++i) {
SomeOldStruct tr = arrayOfStructyThings[i];
.... do your worst here ...
}

Initi and write array in objective-c

In my h file I declare a var that later should be an array:
#interface myClass : CCNode {
CGPoint *mVertices;
}
#end
In my init method:
mVertices = malloc(size * size * sizeof(CGPoint));
mVertices[0][0] = ccp(0,0);
At this last line I get an error Subscripted value is neither array nor pointer.
Why do I get this error and how to solve that problem?
mVertices is a pointer, but you treat it like a two-dimensional array which is not allowed (you may treat it like a one-dimensional array, though).
Creating a dynamic multi-dimensional array in (Objective)-C is tricky insofar as the compiler would need to know the size of all but the first dimension to actually compile where in memory the element is situated.
But you can do the calculation yourself:
mVertices[(row * size) + column] = ccp(row, column);
You might want to define a macro for that:
#define VERTICE_ACCESS(row,colum) mVertices[(row * size) + column]
Your array is not two dimensional. It's just a list of vertices.
If you want to allocate space for a dynamic two dimensional array in C you could do:
CGPoint** mVertices;
NSInteger nrows = 10;
NSInteger ncolumns = 5;
mVertices = calloc(sizeof(CGPoint*), nrows);
if(mVertices == NULL){NSLog(#"Not enough memory to allocate array.");}
for(NSUInteger i = 0; i < nrows; i++)
{
mVertices[i] = calloc(sizeof(CGPoint), ncolumns);
if(mVertices[i] == NULL){NSLog(#"Not enough memory to allocate array.");}
}
mVertices[0][5] = CGPointMake(12.0, 24.0);
mVertices[1][5] = CGPointMake(22.0, 24.0);
mVertices[2][5] = CGPointMake(32.0, 24.0);
mVertices[2][1] = CGPointMake(32.0, 24.0);
for(NSUInteger i = 0; i < nrows; i++)
{
for (int k = 0; k < ncolumns; k++)
{
NSLog(#"Point %#", NSStringFromPoint(NSPointFromCGPoint(mVertices[i][k])));
}
}
I used calloc instead of malloc to get CGPoints initialized with 0.0.