0

I've created a class method that returns a random position as an NSValue object. I want to store the returned positions in a mutable array so the next time the class method gets called it checks the positions in the mutable array and if it finds one that is too close to the one stored it generates a new one.

What I can't seem to figure out is how to allocate and initialize my mutable array to use with my class method. I've tried allocating it in the class method. but that won't work because it will get initialized on each call therefor the previously stored values are... erased?

then I want to use the generated position to place a number of circles on the view (without them overlapping). right now the randomly generated positions work, but they overlap because of the mutable array not being implemented correctly in my randomposition class.

I'm still a beginner in objective c...and programming in general...

@implementation randomPosition

NSMutableArray *positionsArrayPlayer1;


    +(NSValue *) givePosition:(int)player forRadius: (CGFloat) radius

    {

        if (player == 1)
        {
            //set range for arc4random
            int fromNumberY = 550;
            int toNumberY = 950;

            //set range for arc4random
            int fromNumberX = 0;
            int toNumberX = 700;


            BOOL far_enough_away = NO;
            CGPoint newpoint;

            while(!far_enough_away)
            {

                newpoint = CGPointMake((arc4random()%(toNumberX-fromNumberX+1))+fromNumberX, 
                                       (arc4random()%(toNumberY-fromNumberY+1))+fromNumberY);
                far_enough_away = YES;


                for(NSValue *existing in positionsArrayPlayer1)
                {
                    NSLog(@"test");

                    CGPoint pointb = [existing CGPointValue];
                    CGFloat deltay = pointb.y-newpoint.y;
                    CGFloat deltax = pointb.x-newpoint.x;
                    CGFloat distance = sqrt(pow(deltax,2) + pow(deltay,2));

                    //fail if closer than desired radius
                    if(distance < radius )
                    {
                        far_enough_away = NO;

                        NSLog(@"test");
                        break;
                    }
                    [positionsArrayPlayer1 addObject:[NSValue valueWithCGPoint:newpoint]];

                }
                NSLog(@"%@",positionsArrayPlayer1);
            }

            return [NSValue valueWithCGPoint:newpoint];

        } else if (player == 2 ){



             //more stuff to come here....



        } else {


            NSLog(@"player invalid");

        }

        return nil;
    }

here's the method I use in my viewcontroller. I also store the circle object that is placed on the view in a separate array for other manipulations.

- (void) positionCirclesPlayer1 
{

    radius = 70;
    CGRect position;

    for (int i = 0; i < [colors count];i++)
    {

    CGRect positionCircleInCenter = CGRectMake(self.view.frame.size.width/2-35, self.view.frame.size.height/2-35, radius, radius);

    Circle *myCircle = [[Circle alloc] initWithFrame:positionCircleInCenter radius:radius color:[colors objectAtIndex:i]];
    myCircle.label.text = [NSString stringWithFormat:@"%i", i];
    myCircle.alpha = 0;
    myCircle.userInteractionEnabled = NO;


    theNewPointPlayer1 =   [randomPosition givePosition:1 forRadius:radius];

    position = CGRectMake(theNewPointPlayer1.CGPointValue.x, theNewPointPlayer1.CGPointValue.y, 70, 70);


    [UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationCurveEaseIn animations:^{
            myCircle.frame = position; myCircle.alpha = 1;} completion:nil];

    [playerOneCircles addObject:myCircle];
    [self.view addSubview:myCircle];

    }


}
Ramin Afshar
  • 989
  • 2
  • 18
  • 34

1 Answers1

1

Before learning Obj-C, you should probably learn something about C :)


+(NSValue*)givePosition:(int)player forRadius:(CGFloat)radius {
  //this is executed when the method is called for the first time
  static NSMutableArray *positionsArrayPlayer1 = nil;

  if (positionsArrayPlayer1 == nil) { //checking if this is the first time execution
     positionsArrayPlayer1 = [[NSMutableArray alloc] init];
  }

}

or



//global variable accessible only from this file
static NSMutableArray *positionsArrayPlayer1;

@implementation randomPosition

//this method is called when the class is loaded.
+(void)initialize {
   positionsArrayPlayer1 = [[NSMutableArray alloc] init];
}

+(NSValue*)givePosition:(int)player forRadius:(CGFloat)radius {
   //do something with the array
}

@end

Note that implementing this functionality using class methods is probably not a very good architecture.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • thank you for the example. why isn't this a very good architecture? and more importantly, what would be a good architecture? – Ramin Afshar Apr 12 '12 at 19:29
  • You have no reason to make this static. You'll have problems if you want to reset the array (another class method?). A dedicated class (`PositionGenerator`) would be better. You can probably share the access to the class then. – Sulthan Apr 13 '12 at 07:53