jamzsabb
jamzsabb

Reputation: 1154

How to swap values (not indexes) in NSMutableArray

I'm taking waaaayyy more classes than I normally do this semester and just haven't had the time to play with objective c and make it my own, this all still feels very foreign to me and I'm having a lot of trouble doing something that I know should be fairly simple.

But basically what i have is a 6 piece mosaic puzzle that the pieces go back to the same place when the puzzle is restarted. I'm trying to swap the origin of each piece with that of another piece in a random way every time the puzzle is restarted. So I'm trying to randomize the CGRect values assigned to NSValue objects in an array, declared as such:

@synthesize topLeft;
@synthesize topMiddle;
@synthesize topRight;
@synthesize bottomLeft;
@synthesize bottomMiddle;
@synthesize bottomRight;
@synthesize scoreLabel;

topLeftRectOrigin=[NSValue valueWithCGRect: topLeft.frame];
topMiddleRectOrigin=[NSValue valueWithCGRect: topMiddle.frame];
topRightRectOrigin=[NSValue valueWithCGRect: topRight.frame];
bottomLeftRectOrigin=[NSValue valueWithCGRect: bottomLeft.frame];
bottomMiddleRectOrigin=[NSValue valueWithCGRect: bottomMiddle.frame];
bottomRightRectOrigin=[NSValue valueWithCGRect: bottomRight.frame];

puzzlePieces=[[NSMutableArray alloc]initWithObjects:topLeft, topMiddle, topRight, bottomLeft, bottomMiddle, bottomRight, nil];
puzzleOrigins=[[NSMutableArray alloc]initWithObjects:topLeftRectOrigin, topMiddleRectOrigin, topRightRectOrigin, bottomLeftRectOrigin, bottomMiddleRectOrigin, bottomRightRectOrigin, nil];

topLeftRectGrid=CGRectMake(145, 95, 30, 30);
topMiddleRectGrid=CGRectMake(235, 95, 30, 30);
topRightRectGrid=CGRectMake(325, 95, 30, 30);
bottomLeftRectGrid=CGRectMake(145, 185, 30, 30);
bottomMiddleRectGrid=CGRectMake(235, 185, 30, 30);
bottomRightRectGrid=CGRectMake(325, 185, 30, 30);

I'm really having trouble getting my brain around this, can you guys recommend how I should go about doing this? Much thanks for the help.

Upvotes: 1

Views: 908

Answers (3)

Caleb
Caleb

Reputation: 125007

Forget about keeping a separate array of the origins, and get rid of the six properties that all point to the individual puzzle pieces.

Instead, give each puzzle piece some sort of value that identifies its proper position. An easy way to do this would be to use UIView's tag property to store the index in the array that each piece should have when the puzzle is properly completed. The top left piece should end up with index 0, the top middle should have index 1, and so on to the bottom right piece with index 5.

Next, randomize the array. ElJay's method is a great example of how to do this using -exchangeObjectAtIndex:withObjectAtIndex:. Position your pieces according to their indexes in the array. Add some code so that the use can swap pieces by dragging, or whatever.

Finally, add some code that decides when the puzzle is complete. This is easy -- just compare the actual index of each piece to its tag. If each piece's tag matches its index in the array, the puzzle is complete.

Upvotes: 1

iFeli
iFeli

Reputation: 395

Update: You might wanna reformulate your question. I understood it as you wanting to change the origin of two objects inside your array without changing their positions in the array, ElJay gave a great solution in case you want to swap the array positions. Clarification might help just so we know what to help with! :D

I encountered a similar situation in a recent project of mine.

You have an NSMutableArray with 6 elements in it, now obviously you don't want to change the order of the items but instead their origin. Here's a solution I think will help you for your case:

  1. Generate two random numbers from 0-5 (your array indexes) to represent 2 different items (pieces) of your array.
  2. Via a switch statement, acquire the origin each piece corresponding to the randomly generated indexes.
  3. Once again via a switch statement, set the new origins you acquired for the pieces corresponding to the randomly generated indexes.

This is what I did, I basically had to animate swapping the position of a few images randomly. I just acquired 2 different numbers randomly, retrieved the center corresponding to each of these items and then inverted the centers on each.

I got a smooth animation and it's all randomly generated at runtime :)

Hope this helps, feel free to ask more questions or comments (:

Upvotes: 1

LJ Wilson
LJ Wilson

Reputation: 14427

Not tested, but this should work:

(NSMutableArray *)randmomizeMutableArrayWithArray:(NSMutableArray)mutableArray {
    NSUInteger count = [mutableArray count];
    for (NSUInteger i = 0; i < count; ++i) {
        // Select a random object in the array
        int numObjects = count - i;
        int n = (random() % numObjects) + i;
        [mutableArray exchangeObjectAtIndex:i withObjectAtIndex:n];
    }

    return mutableArray
}

My suggestion is make a copy of puzzleOrigins (that doesn't need to be a MutubleArray BTW) and then work with that copy:

NSMutableArray *copyOfPuzzleOrigins = [[NSMutableArray alloc] initWithArray:puzzleOrigins];
copyOfPuzzleOrigins = [self randmomizeMutableArrayWithArray:copyOfPuzzleOrigins];

Upvotes: 5

Related Questions