For loop variable always evaluating to true - objective-c

Annoying newbie problem here. This variable isPlayerTouchingAnotherPlayer is being set to true as soon as I touch the piece. I'm almost positive I know why but I can't find a way to display this in log to confirm. I could probably do it by setting different flag numbers for each of the objects but I was hoping there is another way.
The problem is that piece is an object that is also located in p1Array so as soon as I touch it it hits itself and isPlayerTouchingAnotherPlayer is evaluated to true.
Is there a way I could print out the view or image name of the objects touching somehow to confirm this? And furthermore, is there a way to somehow avoid this annoying conflict.
for (int i = 0; i <[p1Array count]; i++) {
UIImageView *tempP1;
tempP1 =[p1Array objectAtIndex:i];
if (CGRectIntersectsRect(piece.frame, tempP1.frame)) {
NSLog(#"selected piece: %#, touched piece: %# ", piece, tempP1);
isPlayerTouchingAnotherPlayer = TRUE;
}
}

why not use fast enumeration and skip the image view you are not interested in checking.
for (UIImageView *imageView in p1Array) {
if (imageView == piece)
continue;
if (CGRectIntersectsRect(imageView.frame, piece.frame)) {
// do whatever
}
}
it seems like you are already printing out the names of the objects touching in the code sample you have provided. if you want to print out specific properties of the objects you can do that to.

as soon as i touch it it hits itself and isPlayerTouchingAnotherPlayer
is evaluated to true.
Then you should get a log message that shows the same object for the selected piece and the touched piece. If that's what's happening, then just add a condition to your if to prevent it:
if (piece != tempP1 && CGRectIntersectsRect(piece.frame, tempP1.frame)) {

Simply
NSLog(#"%# %#", piece, tempP1);
or
NSLog(#"%ld %ld", (NSInteger) piece, (NSInteger) tempP1);
The first will show you the description of the object, the second the address in memory, if it's same address, it's the same object.
You can simply check if it's the same object (pointer) with a simple equal check to exclude the same object :
if (piece != tempP1) {
if (CGRectIntersectsRect(piece.frame, tempP1.frame)) {
...
}

Furthermore, you would like to write this:
for ( int i = 0;
( ( i < [p1Array count] )
&& ( ! isPlayerTouchingAnotherPlayer )
);
i++
) {
...
}

Related

Sudoku Backtracking Algorithm Failure

I'm trying to generate a sudoku board, and although I can generate a solution, I now need to remove squares that a user can then fill in. In order to do this, I'd like to use backtracking to check each time that I remove a square, the board is
1. still solvable and 2. has only one solution.
The Problem
When I test my backtracking algorithm on this board (where the zeroes are empty squares), it returns this solution. Obviously I would prefer not to end up with several 9s in the first row, for example.
My Code
- (BOOL) solveArray: (NSArray*) numArray {
NSMutableArray* board = [numArray mutableCopy];
for (int i=0; i<9; i++) { //make all of the arrays mutable as well (since it's 2D)
[board replaceObjectAtIndex:i withObject:[board[i] mutableCopy]];
}
//if everything is filled in, it's done
if (![self findUnassignedLocation:board]) {
NSLog(#"\n%#", [SudokuBoard sudokuBoardWithArray:board]);
return TRUE;
}
NSArray* poss = [[SudokuBoard sudokuBoardWithArray:board] possibleNumbersForRow:self.arow Col:self.acol];
//if there are no options for a location, this didn't work.
if ([poss count] == 0) {
return FALSE;
}
//otherwise, continue recursively until we find a solution
else {
for (int i=0; i<[poss count]; i++) {
//make a tentative assignment
board[self.arow][self.acol] = poss[i];
//return, if successful, done
if ([self solveArray:board]) {
return TRUE;
}
//if that didn't work, unmake it and retry with other options
board[self.arow][self.acol] = [NSNumber numberWithInt:0];
}
}
return FALSE;
}
Any thoughts on where I might be going wrong?
Each level of recursion needs its own row and column variables. That is, row and column should be inputs to solveArray and outputs of findUnassignedLocation instead of being member variables. As it is, when there is backtracking the row and column of the failed level get reused by the caller.
Given that some assigned locations are being overwritten, maybe findUnassignedLocation also contains an error.
Given that the result is invalid, maybe possibleNumbersForRow also contains an error.

IBAction to display next object of array

I'm trying to do something I thought was going to be very simple but I can't figure it out. I'm filling an array with objects like this in TableViewController:
if (indexPath.row == 0) {
detailController.textArray = [[NSMutableArray alloc] initWithObjects:#"Text1", #"Text2", #"Text3", #"Text4", #"Text5", nil];
}
Then in the DetailController I added this action to make the label display the next object of the textArray:
- (IBAction)nexTextButtonPressed:(id)sender {
int i = 0;
if (i<[textArray count])
i++;
textLabel.text = [textArray objectAtIndex:i];
}
I connected the button in ib to the action with option Touch Down (tried some of the others too). Something isn't working, the button jumps to the second object of the array but then it doesn't work any more. What could be causing this and how to fix it?
int i = 0; is initialized inside the method, it will always be reinitialized to zero on every call which will not let you move forward from second object
Well every time you hit the button i is getting reset to 0 so when it hits the if statement yes it goes into the statement as the condition is correct, but then you are incrementing i by 1 so i becomes 1 then you retrieve the array index 1 every time. You aren't actually doing anything else. No loop to print through the array or anything.

Recursivity in methods, Algorithm and NSValue issue

-(BOOL)isInArray:(CGPoint)point{
if ([valid count]==0) {
return NO;
}
for (NSValue *value in valid) {
CGPoint er=[value CGPointValue];
if( CGPointEqualToPoint(point,er)) return NO;
}
return YES;
}
-(void)check:(CGPoint)next{
if (!next.y==0) {
int ics=(int) next.x;
int igrec=(int)next.y;
if (mat[ics][igrec]==mat[ics-1][igrec]){
if (![self isInArray:next]) {
[valid addObject:[NSValue valueWithCGPoint:next]];
NSLog(#"valid y!=0 : %#",valid);
[self check:CGPointMake(ics-1, igrec)];
}
}
}
}
y are columns , x are rows , mat is a C matrix
what i'm trying to do here is this:i get a point, next, in a matrix,mat (i'll use struct but for the scope of testing i use CGPoint..it's basicaly the same thing), and for that point i check if it's on the first row and if it's not i check if the value is equal to the value of the row above .If it is, i add the coord of the point into an array and move to the value above (recursively). I have ifs for left,right, and below too...but the idea is the same.
My issues:
For some reason it doesn't work as it should, even with a mat full of 1 values
The NSMutableArray i use to store the points is always null (note that the NSLog gets called so it should've added an object already)
Does recursivity work with methods?
If you have a better idea how to do this...i'm listening
The "valid" array is nil because you haven't allocated it. (You can send an addObject: message, or any message, to a nil pointer--it just doesn't do anything.) Make sure you've got
valid = [[NSMutableArray alloc] init];
somewhere before you're calling this code.
Also, "!next.y==0" is questionable. It might turn out to be identical to "next.y != 0" even if ! has a higher precedence that ==, but I wouldn't guarantee it. That's all I spot for now, without really grokking what this code is trying to do..
Oh, another quick note: Instead of writing your own isInArray, just use NSArray's containsObject:. The inner part of the check method (second indent) is then
NSValue* pointVal = [NSValue valueWithCGPoint:next];
if ( ![valid containsObject:pointVal] )
{
[valid addObject:next];
[self check:CGPointMake(ics-1, igrec)];
}
Or, if you don't care about the order of the points in the valid array you could use an NSMutableSet instead and not worry about checking if the point is already in the collection.
And yes, recursion in methods is fine. They're really the same as C functions, just with a couple hidden arguments (the self pointer and the method name) and called through a dispatch function.

How can I use multiple items in one if statement?

in this case, i'm using:
- (IBAction)reset:(id) sender {
if ((boxHide1.hidden = YES) && (boxHide2.hidden = YES)) {
resetHide.hidden = NO;
}
}
How can I do this? I have 12 items all together I need in the statement. Thanks!
You could use the solution #Joe posted but as you can tell the code for hiding / unhiding could get very messy and hard to read.
If you want to keep your code clean and easy to understand / maintain, I'd put all these buttons into a NSMutableArray and iterate through it to determine whether you want to show the reset button or not.
BOOL showResetButton = YES;
for (UIButton *button in buttonsArray)
{
if (button.hidden == NO) // If any of the buttons is not hidden do not show the reset button
showResetButton = NO;
}
resetButton.hidden = showResetButton;
Make sure you use == to compare values but since they are already booleans you do not need to compare against YES. If all the comparisons are AND(&&) that is correct and you can drop the parenthesis, otherwise if there are any OR(||) operations then you would need to group the appropriate operations.
if (boxHide1.hidden &&
boxHide2.hidden &&
... &&
boxHide12.hidden)
{
resetHide.hidden = NO;
}

seeing if an object exists at index[i] in NSMUtableArray

People I'd like to see if an element at index[i] is not present in a different (or current ) array.
So for instance if my array looked somewhat like this
[wer, wer4 , wer5 , werp , klo ...
Then I would like to see if aExerciseRef.IDE ( which is "sdf" for instance ) does or does not exist at index[i].
I assume I'd have to use some sort of iterator ..
for( int i = 0; i < 20; i++ )
{
if([instruct objectAtIndex:index2 + i] != [instruct containsObject:aExerciseRef.IDE] )
NSLog(#"object doesn't exist at this index %i, i );
else
NSLog(#"well does exist")
}
I know this doesn't work , it's just to elaborate what I'd like to achieve.
edit:
I'm going to try to elaborate it a little more and be more specific.
1) First of all aExerciseRef.IDE changes everytime it get's called so one time it is "ret" another time it's "werd".
2) Imagine an array being filled with aExerciseRef.IDE's then I would like to compare if the elements in this array exist in the instruct array.
So I would like to see if the element at let's say position 2 (wtrk)
[wer, wtrk, wer , sla ...
exists in the array which was being filled with the aExerciseRef.IDE's.
I hope I've been more clear this time.
Sir Lord Mighty is partially correct. Yes, your comparison is wrong. No, his solution won't work.
Here's one that will:
if (index < [anArray count] && [[anArray objectAtIndex:index] isEqual:anObject]) {
NSLog(#"Got it!");
} else {
NSLog(#"Don't have it.");
}
Alternatively, you can use the containsObject: method to achieve the same thing:
if ([anArray containsObject:aExerciseRef.IDE]) {
NSLog(#"Got it!");
} else {
NSLog(#"Don't have it.");
}
The second option will not give you the index of the object, but that is easily rectified using:
NSInteger index = NSNotFound;
if ([anArray containsObject:aExerciseRef.IDE]) {
index = [anArray indexOfObject:aExerciseRef.IDE];
...
}
Your example makes no sense at all, and does nothing to clarify the question. You are doing a comparison between an expression with type (id)
[instruct objectAtIndex:index2 + i]
and one with type BOOL
[instruct containsObject:aExerciseRef.IDE]
And if the object you are looking for is at index x in an array, then it goes without saying that containsObject on the array will return YES for that object.
If what you want to accomplish is simply what you state in the title, then it's as easy as:
if ([[anArray objectAtIndex:index] == anObject])
NSLog (#"Got it!");
else
NSLog (#"Don't have it.");