1

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.

1
  • Thanks for all the help guys, everyone contributed a little piece to showing me the best way to solve this. It turned out a lot of the problem was crappy algorithms in the tutorial the professor had us follow that made it hard to change anything without a re-write. But one re-write later everything works :-D I basically just had to change all the references to the array instead of the objects in the array, which wouldn't allow array shuffling. Commented Feb 29, 2012 at 3:30

3 Answers 3

5

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];
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome thank you for the randomization algorithm, I was building something much more complex using a swap and whatnot.
1

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 (:

1 Comment

Thank you for that, it made it click in my head. The assignment had me build the puzzle app from a tutorial the professor wrote, and then I'm trying to "improve" on it and I definitely think that the way she had the origin locations declared as CGRects wrapped in NSValues wrapped in an NSMutableArray threw me off, because a lot of the code references the CGRects instead of the arrays, took me some time to realize I need to change the references to use the array in order to make this work
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.