problem with collision of UIImageViews - iphone

-(void)moveTheImage{
for (NSUInteger i = 0; i < [views count]; i++) {
image = [views objectAtIndex:i];
X = [[XArray objectAtIndex:i] floatValue];
Y = [[YArray objectAtIndex:i] floatValue];
image.center=CGPointMake(image.center.x + X, image.center.y + Y);
if(!intersectFlag)
{
if(CGRectIntersectsRect(image.frame,centre.frame))
{
intersectFlag = YES;
label.text= [NSString stringWithFormat:#"%d", count];
++count;
}
}
else
{
if(!CGRectIntersectsRect(image.frame,centre.frame))
{
intersectFlag = NO;
}
}
}
I would like that every time "image" intersect with "centre" the count increase of 1 but when there is a collision the count grows very fast until "image" doesn't touch "centre". More precisely "image" moves an then pass through "centre" and the count grows and when "image" is not in contact with "centre" the counter stops.How cn I solve this please? sorry for my english I'm french :/

As I said on the last comment, I think your count problem comes because of the frame rate.
So you can use an NSMutableSet which will contain all the objects being in collision.
In the interface, you declare your new set:
NSMutableSet * collisionObjects;
In the init method:
collisionObjects = [[NSMutableSet alloc] init];
In the dealloc:
[collisionObjects release];
And your method becomes:
-(void)moveTheImage{
for (NSUInteger i = 0; i < [views count]; i++) {
image = [views objectAtIndex:i];
X = [[XArray objectAtIndex:i] floatValue];
Y = [[YArray objectAtIndex:i] floatValue];
image.center=CGPointMake(image.center.x + X, image.center.y + Y);
if (CGRectIntersectsRect(image.frame,centre.frame)) {
// If the object is in collision, we add it to our set
// If it was already in it, it does nothing
[collisionObjects addObject:image];
}
else {
// If the object is not in collision we remove it,
// just in case it was in collision last time.
// If it was not, it does nothing.
[collisionObjects removeObject:image];
}
}
// The intersectFlag is updated : YES if the set is empty, NO otherwise.
intersectFlag = [collisionObjects count] > 0;
// We display the count of objects in collision
label.text= [NSString stringWithFormat:#"%d", [collisionObjects count]];
}
And this way you always have the count of your objects in collision using [collisionObjects count].

Related

Shuffle NSString characters and arrange in blocks

I am trying to develop a puzzle game where we display a shuffled word in blocks and user has to tap in proper order to form the word.I have an array of around 3k words and I have shuffled the array and formed a jumbled array.Now I want to pick a word eventually string,shuffle it and display the shuffled arrangement in boxes,say for instance the word is cricket,it should appear something of the below format on the screen:
Here is how I shuffled the array and formed a jumbled one
srandom(time(NULL));
for (NSInteger x=0;x<[greWordsArray count];x++)
{
NSInteger randomNumber = (random() % ([greWordsArray count] - x)) + x;
[greWordsArray exchangeObjectAtIndex:x withObjectAtIndex:randomNumber];
}
I also forgot to say I have a "new" button where if user clicks it,new word should appear and as usual it should be in shuffled mode,then display in blocks.
Can some one please guide me on how to accomplish this,I wonder what to use for displaying characters in blocks,whether it is buttons,text field or some other object.I also need some assistance regarding changing number of blocks depending on word length.Also how to display the selected character on label.I do acknowledge we can take label and arrange characters on it,but what is the recommended way,should I take a label for each character or a single label,then allow spacing depending on character selection.If so how should I do this.
People would have wondered what I have tried,but please help me as I am new to these kind of puzzle games,at least provide me with some understandable source to get started.
Suppose you have wordsArray which consists of 3k words
int randomWordIndex = arc4random%[wordsArray count];
NSString *jumbledWord = [wordsArray objectAtIndex:randomWordIndex];
NSMutableArray *characterArray = [[NSMutableArray alloc]init];
// character array having all characters of array
for (int i = 0; i< = [jumbledWord length]); i++)
{
int randomCharacterIndex = arc4random%[jumbledWord length];
[characterArray insertObject:
[NSString stringWithFormat: #"%#",
[jumbledWord characterAtIndex:i]]
atIndex:randomCharacterIndex] ;
}
Now you can show it using label or tableview or anything
I found a lot more precise and logical answer to my problem,
As alpha mentioned,we need to shuffle the array and form a sorted one,we need to assign a random word to jumbledWord based on index,say for instance:
int randomWordIndex = (int)arc4random%[greWordsArray count];
self.jumbledWord = [greWordsArray objectAtIndex:randomWordIndex];
Now we are ready with creating buttons based on word length.Here it is:
-(void)buttonsCreation:(int)noOfButtons
{
NSMutableArray *charactersArray = [NSMutableArray array];
self.wordButtons = [[NSMutableArray alloc]initWithCapacity:20];
BOOL record = NO;
int randomNumber;
for (int i=0; [charactersArray count] < jumbledWord.length; i++) //Loop for generate different random values
{
randomNumber = arc4random() % jumbledWord.length;//generating random number
if(i==0)
{
[charactersArray addObject:[NSNumber numberWithInt:randomNumber]];
}
else
{
for (int j=0; j<= [charactersArray count]-1; j++)
{
if (randomNumber ==[[charactersArray objectAtIndex:j] intValue])
record = YES;
}
if (record == YES)
record = NO;
else
[charactersArray addObject:[NSNumber numberWithInt:randomNumber]];
}
}
int arrayValue;
float x = 100.0;
float y = 100.0;
for(int i=0;i<[jumbledWord length];i++)
{
if(i>=0 && i<10)
{
arrayValue = [[charactersArray objectAtIndex:i] intValue];
x = x + 33;
UIButton *characterButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
characterButton.frame = CGRectMake(x,175.0, 35.0, 35.0);
[wordButtons addObject:characterButton];
NSString *characterValue = [NSString stringWithFormat:#"%c",[jumbledWord characterAtIndex:arrayValue]];
[characterButton setTitle:characterValue forState:UIControlStateNormal];
[characterButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[characterButton setTag:arrayValue];
[self.view addSubview:characterButton];
}
else if(i>=10 && i<15)
{
y = y + 33;
UIButton *characterButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
characterButton.frame = CGRectMake(y,200.0, 35.0, 35.0);
[wordButtons addObject:characterButton];
NSString *characterValue = [NSString stringWithFormat:#"%c",[jumbledWord characterAtIndex:i]];
[characterButton setTitle:characterValue forState:UIControlStateNormal];
[characterButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[characterButton setTag:i];
[self.view addSubview:characterButton];
}
}
}
Please note that the x and y values may vary based on one's requirement.I have briefly set co-ordinate locations of x and y based on word length,You may change if you want,thanks :)
Hope it helps some one,happy coding!!

Objective C - Accessing Normal C Array

I am making a game that assigns a label a question from a regular C array.
- (void)viewDidLoad
{
[super viewDidLoad];
for (int i = 0; i < 45; i++) {
basketball_numbers1[i] = (arc4random()%999)+100;
basketball_numbers2[i] = (arc4random()%999)+100;
for (int j = 0; j < 30; j++) {
int first = basketball_numbers1[i];
int second = basketball_numbers2[i];
basketball_questions[j] = [[NSString stringWithFormat: #"%d + %d", first, second] retain];
basketball_answers[j] = [[NSString stringWithFormat: #"%d", basketball_numbers1[i] + basketball_numbers2[i]] retain];
}
}
This code works and printed the questions and answers to the console no problem before I commented them out.
But when I'm running the emulator and type in the correct answer, the same questions stays on the label, even though the count (variable used to increase the index of the array) increases, which I confirmed via NSLog.
Some other notes: when I had manually put in values for the array, it worked no problem. Also I added in the 'retain' to the end of the array after doing some research, which actually eliminated some problems I was having before this, but I'm not sure if retain/release are used in regular C arrays or just NSArray.
Here is the code that reads in the textfield upon a button click.
- (IBAction)basketball_click:(id)sender {
basketball_input = self.basketball_textfield.text;
NSLog(#"INPUT: %#", self.basketball_textfield.text);
if ([self.basketball_textfield.text isEqualToString:(basketball_answers[count])]) {
NSLog(#"THEY ARE EQUAL");
isCorrect = TRUE;
self.basketball_textfield.text = #"";
}
...
if(isCorrect) {
NSLog(#"Retain Count: %d", [basketball_questions[count] retainCount]);
correct.text = #"CORRECT!";
basketball_right++;
count++;
NSLog(#"COUNT: %d", count);
question_label.text = basketball_questions[count];
NSLog(#"NEW QUESTION: %#", basketball_questions[count]);
}
for (int i = 0; i < 45; i++) {
first = (arc4random()%999)+100;
last = (arc4random()%999)+100;
basketball_questions[i] = [[NSString stringWithFormat: #"%d + %d", first, second] retain];
basketball_answers[i] = [[NSString stringWithFormat: #"%d", first+last] retain];
}

Sort a NSMutableArray of location with my GPS position

I want to sort a NSMutableArray, where each row is a NSMutableDictionary, with my GPS position from CoreLocation framework.
This is an example of my array of POI
arrayCampi = (
{
cap = 28100;
"cell_phone" = "";
championship = "IBL 1D";
citta = Novara;
division = "";
email = "";
fax = 0321457933;
indirizzo = "Via Patti, 14";
latitude = "45.437174";
league = "";
longitude = "8.596029";
name = "Comunale M. Provini";
naz = Italy;
prov = NO;
reg = Piemonte;
sport = B;
surname = "Elettra Energia Novara 2000";
telefono = 03211816389;
webaddress = "http://www.novarabaseball.it/";
})
I need to sort this array with my location (lat and long) with field 'latitude' and 'longitude' of each row in ascending mode (first row is POI nearest to me).
I have tried this solution without success:
+ (NSMutableArray *)sortBallparkList:(NSMutableArray *)arrayCampi location:(CLLocation *)myLocation {
if ([arrayCampi count] == 0) {
return arrayCampi;
}
if (myLocation.coordinate.latitude == 0.00 &&
myLocation.coordinate.longitude == 0.00) {
return arrayCampi;
}
NSMutableArray *sortedArray = [NSMutableArray arrayWithArray:arrayCampi];
BOOL finito = FALSE;
NSDictionary *riga1, *riga2;
while (!finito) {
for (int i = 0; i < [sortedArray count] - 1; i++) {
finito = TRUE;
riga1 = [sortedArray objectAtIndex: i];
riga2 = [sortedArray objectAtIndex: i+1];
CLLocationDistance distanceA = [myLocation distanceFromLocation:
[[CLLocation alloc]initWithLatitude:[[riga1 valueForKey:#"latitude"] doubleValue]
longitude:[[riga1 valueForKey:#"longitude"] doubleValue]]];
CLLocationDistance distanceB = [myLocation distanceFromLocation:
[[CLLocation alloc]initWithLatitude:[[riga2 valueForKey:#"latitude"] doubleValue]
longitude:[[riga2 valueForKey:#"longitude"] doubleValue]]];
if (distanceA > distanceB) {
[riga1 retain];
[riga2 retain];
[sortedArray replaceObjectAtIndex:i+1 withObject:riga2];
[sortedArray replaceObjectAtIndex:i withObject:riga1];
[riga1 release];
[riga2 release];
finito = FALSE;
}
}
}
return sortedArray;
}
Can anyone help me, also with other solution?
Alex.
Sorting by lat and long will not give you the nearest location from any given coordinates. As an approximation*) you could use Pythagoras (you learned that in high school, remember?):
float distance = sqrtf(powf((origLat-destLat),2)+powf((origLon-destLon), 2));
Simply add that to your dictionary with key #"distance" and sort with
NSArray *sorted = [arrayOfDictionaries sortedArrayUsingDescriptors:
#[[NSSortDescriptor sortDescriptorWithKey:#"distance" ascending:YES]]];
*) It's an approximation because theoretically distance between two points is a curved line on the surface of an ellipsoid.
[arrayCampi sortedArrayUsingSelector:#selector(compare:)];
- (NSComparisonResult)compare:(NSDictionary *)otherObject {
if ([[self objectForKey:#"key"] isEqual:[otherObject objectForKey:#"key"]]) {
return NSOrderedSame;
}
else if (//condition) {
return NSOrderedAscending;
}
else {
return NSOrderedDescending;
}
}
Take a look at How to sort an NSMutableArray with custom objects in it?
I think there's no need to implement your own sorting algorithm. There are the ready ones out there :-) I would suggest to look at NSSortDescriptor.
And since you keep your geo coordinates in NSString format, and not the NSNumber, you probably would need to write your own NSPredicate for NSString objects comparison in your class. (I don't remember if #"123" is greater than #"1.23", I mean special symbol '.')

How to compare elements in int array to a integer?

I want to compare an array containing int values to a number
example [1,2,30,1,40,200,10,500] < 500 meaning if array contains elements less than 500.
How can i do dis?
Thank alot in advance
I did this bt it say invalid opernd:
if ([placeName count])
{
for (int i =0; i < [placeName count]; i++)
{
NSArray *sortedArray=[placeName sortedArrayUsingFunction:intSort context:NULL];
self.placeName = [NSMutableArray arrayWithArray:sortedArray];
NSMutableArray *tempArray = [sortedArray objectAtIndex:i];
NSDecimalNumber *Distance = [tempArray objectForKey:#"distance"];
NSMutableArray *intDistanse=[Distance intValue];
DLog(#"Distance%d", intDistanse);
NSMutableArray *intDistanse=[Distance intValue];
DLog(#"Distance%d", intDistanse);
for(int j = 0; j < [intDistanse count]; j++)
{
if ( intDistanse[j] < 500 ) //here its says error
{
DLog(#"success");
}
}
}
}
What kind of an array? NSArray or language array?
Easiest way is a loop. Without knowing the type of the array, this is pseudo code.
for(int i = 0; i < arrayCount; i++)
if ( array[i] < 500 )
.... got an element less than 500 ....
The code doesn't really make sense:
that code should be generating a ton of compiler warnings; every warning indicates a bug that should be fixed. Also, try "Build and Analyze".
you are sorting an array every time through the loop; waste of resources and doesn't make sense
everything being typed as NSMutableArray* doesn't make sense; do you really have an array of arrays of arrays?
... calling objectForKey: on anything but an NSDictionary doesn't work
intValue returns an (int), not an NSMutableArray*
if intDistance is an (int), then it should just be ( intDistance < 500 )
Overall, I would suggest you step back and review the Objective-C language guide and a bunch of working examples.
Typically, you loop over each element in the array, checking if each element is less than 500.
For example:
int i;
for (i=0; i < THE_SIZE_OF_THE_ARRAY; ++i)
{
if (array[i] < 500)
{
/* Do something */
}
}
If you want to see whether there is at least one item that matches your condition:
bool found = false;
for(int i = 0; i < sizeof(example)/sizeof(example[0]); ++i)
{
if(example[i] < 500)
{
found = true;
break;
}
}
And if you want to check whether all items match your condition:
bool found = true;
for(int i = 0; i < sizeof(example)/sizeof(example[0]); ++i)
{
if(example[i] >= 500)
{
found = false;
break;
}
}
Did find a solution to it type casting:
NSMutableArray *tempArray = [sortedArray objectAtIndex:i];
//DLog(#"sortedArray%#", sortedArray);8=
NSNumber *DistanceNum = [tempArray objectForKey:#"distance"];
NSLog(#"distance%#:::",DistanceNum);
NSInteger intDistance = (int)[DistanceNum floatValue];
if(intDistance<500)
{
NSLog(#"h:)");
NSString *notifications =#"Yes";
[[AppHelper mDataManager] setObject:notifications forKey:#"notifications"];
NSLog(#"notifications:%#",notifications);
RemindMeViewController *object = [[RemindMeViewController alloc] initWithNibName:#"RemindMeViewController" bundle:nil];
// RemindMeViewController *object=[[RemindMeViewController alloc]initWithNibName];
NSLog(#"notifications set");
[object scheduleNotification];
}
You can do this very easily by just implementing the observer to compare. Following is just an example to implement the custom observer to compare
#implementation NSArray (KVO)
- (void)addObserver:(NSObject *)observer toObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
{
NSUInteger idx=[indexes firstIndex];
while(idx!=NSNotFound)
{
[[self objectAtIndex:idx] addObserver:observer
forKeyPath:keyPath
options:options
context:context];
idx=[indexes indexGreaterThanIndex:idx];
}
}
- (void)removeObserver:(NSObject *)observer fromObjectsAtIndexes:(NSIndexSet *)indexes forKeyPath:(NSString *)keyPath
{
NSUInteger idx=[indexes firstIndex];
while(idx!=NSNotFound)
{
[[self objectAtIndex:idx] removeObserver:observer
forKeyPath:keyPath];
idx=[indexes indexGreaterThanIndex:idx];
}
}
-(void)addObserver:(id)observer forKeyPath:(NSString*)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context;
{
if([isa instanceMethodForSelector:_cmd]==[NSArray instanceMethodForSelector:_cmd])
NSRaiseException(NSInvalidArgumentException,self,_cmd,#"not supported for key path %# (observer was %#)", keyPath, observer);
else
[super addObserver:observer
forKeyPath:keyPath
options:options
context:context];
}
-(void)removeObserver:(id)observer forKeyPath:(NSString*)keyPath;
{
if([isa instanceMethodForSelector:_cmd]==[NSArray instanceMethodForSelector:_cmd])
NSRaiseException(NSInvalidArgumentException,self,_cmd,#"not supported for key path %# (observer was %#)", keyPath, observer);
else
[super removeObserver:observer
forKeyPath:keyPath];
}
#end

Why doesn't this for loop execute?

I have a picker view controller to select a chemical source and possibly a concentration. If the source doesn't have concentrations, it just presents a single picker. It gets populated by an NSDictionary with source type names as keys and a custom model object I made called Chemical that has four properties, two NSString, one float and one BOOL.
When I trigger this with dictionary that has 2 components, I want to extract the four values from the Chemical that is represented. Note that I populate the picker with values from the first two properties, but not the float or BOOL. I run through the array for the key that's selected in the first component and check the string from the second component against the chemConcentration property from each of the Chemicals in the key/value array. When the chemConcentration matches, I know I have the right Chemical and I can get its properties to send back.
Whew!
The problem is that even though I know I get to the for loop, it seems to get skipped. The NSLog right before it prints, but the one inside doesn't. sourceConstant and sourceIsLiquid stay 0.0 and NO
- (IBAction)selectedSourceButton {
NSLog(#"selectedSourceButton pressed");
NSInteger sourceRow = [picker selectedRowInComponent:kSourceComponent];
NSString *selectedSource = [self.sources objectAtIndex:sourceRow];
NSArray *selectedChemicalGroup = [dictionaryOfSources objectForKey:selectedSource];
NSInteger concentrationRow = [picker selectedRowInComponent:kConcentrationComponent];
NSString *selectedConcentration = [[NSString alloc] init];
float selectedConstant = 0.0;
BOOL selectedIsLiquid = NO;
if (numberOfComponents == 2) {
NSLog(#"numberOfComponents = 2 if/then chosen"); // <-- This prints.
selectedConcentration = [self.concentrations objectAtIndex:concentrationRow];
NSLog(#"begin selectedConcentration for loop. Number of loops = %d", [selectedChemicalGroup count]); // <-- And so does this.
for (int i; i<[selectedChemicalGroup count]; i++) { // <-- But this doesn't seem to fire!
NSLog(#"selectedConcentration = %#, from selectedChemicalGroup = %#", selectedConcentration, [[selectedChemicalGroup objectAtIndex:i] chemConcentration]); // <-- Because this doesn't print.
if ([selectedConcentration isEqualToString:[[selectedChemicalGroup objectAtIndex:i] chemConcentration]]) {
selectedConstant = [[selectedChemicalGroup objectAtIndex:i] chemConstant];
selectedIsLiquid = [[selectedChemicalGroup objectAtIndex:i] chemIsLiquid];
}
}
}
else {
selectedConcentration = #"";
selectedConstant = [[selectedChemicalGroup objectAtIndex:0] chemConstant];
selectedIsLiquid = [[selectedChemicalGroup objectAtIndex:0] chemIsLiquid];
}
NSLog(#"selectedSourceButton source to return = %#, concentration = %#, sourceConstant = %1.7f, isLiquid = %d", selectedSource, selectedConcentration, selectedConstant, selectedIsLiquid);
if ([self.delegate respondsToSelector:#selector (sourcePickerViewController:didSelectSource:andConcentration:andConstant:andIsLiquid:)]) {
[self.delegate sourcePickerViewController:self didSelectSource:selectedSource andConcentration:selectedConcentration andConstant:selectedConstant andIsLiquid:selectedIsLiquid];
}
}
You need to initialize your variable i: for (int i = 0; ...
But there's a better way to do this, using "fast enumeration":
for (MyChemicalGroupClass *group in selectedChemicalGroup) {
if ([selectedConcentration isEqualToString:[group chemConcentration]]) {
...
}
}
Initialize loop count i
for (int i = 0; i<[selectedChemicalGroup count]; i++)
Do the following and you will understand why:
int i;
NSLog(#"%d", i);