Calling methods with specific values - iphone

For this code example below, usually I would use [self fall]; instead of the code at *, but I need the value of i to be sent to the fall method as well. How do I do this?
- (void)main {
for (int i=0; i <= 100; i++) {
[image[i] fall]; *
}
}
- (void)fall {
// manipulate image[i]; separately from the for loop
}
EDIT: I will accept the oldest answer as all are correct. Thanks!

You need to do -
- (void)fall:(int)i {
// manipulate image[i]; separately from the for loop
}
and call like -
- (void)main {
for (int i=0; i <= 100; i++) {
[image fall:i];
}
}
EDIT -
If you want to pass index-
- (void)fall:(int)i {
// manipulate image[i]; separately from the for loop
}
and call like -
- (void)main {
for (int i=0; i <= 100; i++) {
[self fall:i]; // Now from here you can either pass index
}
}
If you want to pass some image -
- (void)fall:(UIImage)i {
// manipulate image[i]; separately from the for loop
}
and call like -
- (void)main {
for (int i=0; i <= 100; i++) {
[self fall:imageI]; // Now from here you need to pass image, if that image is stored in array, then fetch from array. Or you need to manipulate in the way in which you are storing.
}
}

Maybe you mean:
- (void)main {
for (int i=0; i <= 100; i++) {
[image[i] fall:i];
}
}
- (void)fall:(int)i {
// manipulate image[i]; separately from the for loop
}
Or, maybe you mean:
- (void)main {
for (int i=0; i <= 100; i++) {
[self fall:image[i]];
}
}
- (void)fall:(NSImage *)image {
// manipulate image[i]; separately from the for loop
}
If not, you need to clarify your question.

Related

how to synchronise removal of b2bodies when firing in game

In my game i have some monsters and my hero. when i fire some bullets i remove bodies on collision either with monster or ground body, and also added a timer event to remove the bullet as
-(void) removeProjectile:(CCPhysicsSprite*)projectile{
dispatch_time_t removeProjectile = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1* NSEC_PER_SEC));
dispatch_after(removeProjectile, dispatch_get_main_queue(), ^(void){
int i;
for(i=0;i<deadBodyCount;i++)
{
if(deadBodies[i] == projectile.b2Body)
{
break;
}
}
if(i==deadBodyCount)
{
deadBodies[deadBodyCount]=projectile.b2Body;
deadBodyCount++;
}
});
}
but what happens my code crashes, don't know. please help me. If you have any approach to do this.
i am removing deadbodies in
-(void)removeDeadBodies{
for (int i=0; i<deadBodyCount; i++) {
if(deadBodies[i]){
if([self getPSTag:deadBodies[i]]==3){
CCPhysicsSprite *temp=(CCPhysicsSprite *)deadBodies[i]->GetUserData();
NSLog(#"%#",temp);
[[self getChildByTag:kTagParentNode]removeChild:temp cleanup:YES];
}
else if([self getPSTag:deadBodies[i]]==2){
for (int j=0; j<monsterCount; j++) {
if (monsters[j].b2Body==deadBodies[i]) {
[[self getChildByTag:kTagParentNode]removeChild:monsters[j] cleanup:YES];
monsters[j]=NULL;
}
}
}
_world->DestroyBody(deadBodies[i]);
deadBodies[i]=NULL;}
}
deadBodyCount=0;
}
-(int)getPSTag:(b2Body *)body{ //physics sprite tag value from a b2Body
CCPhysicsSprite *sprite=(CCPhysicsSprite*)body->GetUserData();
//Here is the error------------------------------------
if(sprite)
return (int)sprite.tag;
else
return 0;
}
and this is my begin contact method
-(void)beginContact:(b2Contact *)contact{
b2Body *bodyA=contact->GetFixtureA()->GetBody();
b2Body *bodyB=contact->GetFixtureB()->GetBody();
int collideCheck=[self checkForCollisionGroups:bodyA And:bodyB];
if(!collideCheck)
return;
switch (collideCheck) {
case 1:
for (int i=0; i<monsterCount; i++) {
if(monsters[i].isVisible){
//Checking if Projectile hitting the monster
//bodyA is monster and bodyB is projectile
if([self getPSTag:bodyA]==2&&[self getPSTag:bodyB]==3){
[monsters[i] monsterHit];
[self doExplosionAtPoint:monsters[i].position];
deadBodies[deadBodyCount++]=monsters[i].b2Body;
CCPhysicsSprite *x=(CCPhysicsSprite *)bodyB->GetUserData();
for (int i=0; i<10; i++) {
if(deadBodies[i]==x.b2Body)
return;
}
deadBodies[deadBodyCount++]=x.b2Body;
[self.top updateScore:100];
}//bodyA is Projectile and bodyB is Monster
else if([self getPSTag:bodyA]==3&&[self getPSTag:bodyB]==2){//if one of the body is projectile
[monsters[i] monsterHit];
[self doExplosionAtPoint:monsters[i].position];
CCPhysicsSprite *x=(CCPhysicsSprite *)bodyA->GetUserData();
for (int i=0; i<10; i++) {
if(deadBodies[i]==x.b2Body)
return;
}
deadBodies[deadBodyCount++]=x.b2Body;
deadBodies[deadBodyCount++]=monsters[i].b2Body;
[self.top updateScore:100];
}
}
}
break;
case 2:
if (jumping==YES) {
jumping=NO;
}
break;
case 3: //bullet hitting with any object
if([self getPSTag:bodyA]==3){//if one of the body is projectile
CCPhysicsSprite *x=(CCPhysicsSprite *)bodyA->GetUserData();
for (int i=0; i<10; i++) {
if(deadBodies[i]==x.b2Body)
return;
}
deadBodies[deadBodyCount++]=x.b2Body;
}
else if ([self getPSTag:bodyB]==3){
CCPhysicsSprite *x=(CCPhysicsSprite *)bodyB->GetUserData();
for (int i=0; i<10; i++) {
if(deadBodies[i]==x.b2Body)
return;
}
deadBodies[deadBodyCount++]=x.b2Body;
}
break;
case 4:
for (int i=0; i<monsterCount; i++) {
if(monsters[i].isVisible){
if( (bodyA==monsters[i].b2Body&&bodyB==_heroBody)||(bodyA==_heroBody&&bodyB==monsters[i].b2Body)) {
_heroBody->SetLinearVelocity(b2Vec2(-3*hero.scaleX, 5));
lifeCount=[_top updateHealthMeterWithDamage:10];
NSLog(#"collide");
moving=false;
}
}
}
break;
/*case 6:if([self getPSTag:bodyA]==33){
movingTile.position=((CCSprite*)bodyA->GetUserData()).position;
}
else
movingTile.position=((CCSprite*)bodyB->GetUserData()).position;*/
default:
break;
}
}
I looked at your code. I dont understand the use of removeProjectile: CCPhysicsSprite*)projectile{} method while you indirectly actually adding the projectiles to the deadBodies[] in the beginContact(). So i guess here you have two pointers pointing to same body. And when you run the removeDeadBodies() for loop, it actually first deletes the body and then in next iteration when again it gets the dangling pointer with no body then it crashes.
I commented the line [self removeProjectile:projectile]; in the createProjectileAt() method. And now everything is working fine.
I know it might be late to implement but a suggestion, to have better hold on your b2Bodies and safe deletion from world, you can take a struct datatype with data members as a Sprite and a BOOL variable say isDelete. And use this struct as the userdata of the body. So now you can just set this bool variable to YES inside beginContact() call back. And in you update: tick method after the world->step is over just iterate through the world of bodies and check the BOOL var that can be deleted. HEre you can safely delete the bodies. No need to maintain an array of deadBodies etc. Hence there will not be any synchronization issue.

Making background thread to wait until another background thread gets completed in iphone

How to make a backgroundthread not to work until another background thread gets completed and how to make it to start it's thread once the first backgroundthread gets completed
Use flag to handle such type of event as shown below...
BOOL isYourthreadexecuting = NO;
- (void)beginThread {
isYourthreadexecuting = YES;
[self performSelectorInBackground:#selector(backgroundThread) withObject:nil];
}
- (void)backgroundThread {
[myClass performLongTask];
// Done!
isYourthreadexecuting = NO;
}
- (void)waitForThread {
if (! isYourthreadexecuting) {
// Thread completed
[self callyourmethod];
}
}
Edited >> Addition according use comment
I suggest you to use NSOperationQueue for multithreading.
Hope, this will you...
As stated in my comment, you can use GCD's Serial Dispatch Queues. Here is a sample code to demonstrate:
- (IBAction)buttonSerialQ2Pressed:(id)sender
{
dispatch_queue_t serialdQueue;
serialdQueue = dispatch_queue_create("com.mydomain.testbed.serialQ2", NULL);
dispatch_async(serialdQueue, ^{
//your code here
[self method1];
});
dispatch_async(serialdQueue, ^{
//your code here
[self method2];
});
dispatch_async(serialdQueue, ^{
//your code here
[self method2];
});
dispatch_async(serialdQueue, ^{
//your code here
[self method3];
});
}
-(void)method1
{
for (int i=0; i<1000; i++)
{
NSLog(#"method1 i: %i", i);
}
}
-(void)method2
{
for (int i=0; i<10; i++)
{
NSLog(#"method2 i: %i", i);
}
}
-(void)method3
{
for (int i=0; i<100; i++)
{
NSLog(#"method3 i: %i", i);
}
}

Problem with Objective-C for loop

I have two methods, the generateRandomCard method gets called within the testMethod, where there is a for loop that runs 100 times. That way it works perfect, but if I set the for loop limit to 1000 or any other number greater than 100 it crashes. Can you see what's wrong??
- (void)testMethod {
Globals *myGlobals = [Globals sharedInstance];
int rankOfFirst = 0;
int rankOfSecond = 0;
int playerOneWin = 0;
int playerTwoWin = 0;
int ties = 0;
float firstPercent = 0;
float secondPercent = 0;
float tiePercent = 0;
FiveEval *evaluator = [FiveEval theEvaluator];
for (int i = 0; i < 100; i++) {
short fPF = [self generateRandomCard];
short fPS = [self generateRandomCard];
short sPF = [self generateRandomCard];
short sPS = [self generateRandomCard];
short fFlop = [self generateRandomCard];
short sFlop = [self generateRandomCard];
short tFlop = [self generateRandomCard];
short tur = [self generateRandomCard];
short riv = [self generateRandomCard];
rankOfFirst = [evaluator getRankOfSeven:fFlop
:sFlop
:tFlop
:tur
:riv
:fPF
:fPS];
rankOfSecond = [evaluator getRankOfSeven:fFlop
:sFlop
:tFlop
:tur
:riv
:sPF
:sPS];
if (rankOfFirst > rankOfSecond) {
playerOneWin++;
} else if (rankOfSecond > rankOfFirst) {
playerTwoWin++;
} else {
ties++;
}
[myGlobals.alreadyPickedCards removeAllObjects];
}
firstPercent = ((float)playerOneWin/(float)10000)*100;
secondPercent = ((float)playerTwoWin/(float)10000)*100;
tiePercent = ((float)ties/(float)10000)*100;
NSLog(#"First Player Equity: %f", firstPercent);
NSLog(#"Second Player Equity: %f", secondPercent);
NSLog(#"Tie Equity: %f", tiePercent);
}
- (short)generateRandomCard {
Globals *myGlobals = [Globals sharedInstance];
short i = arc4random()%51;
for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
[self generateRandomCard];
}
}
[myGlobals.alreadyPickedCards addObject:[NSNumber numberWithShort:i]];
return i;
}
You're probably overflowing your stack in the recursive call to -generateRandomCard. If you generate a card that's already been picked, you call yourself recursively (and ignore the result, which is a different bug). So, if your random number stream gave you an unlucky sequence that kept returning cards you've already picked, then you'll recurse infinitely until the stack overflows.
Change your card selection algorithm so that instead of using rejection sampling with the potential for infinite looping/recursion, it uses an algorithm with a bounded runtime such as the Fisher-Yates shuffle.
Not sure if this could in any way lead to the crash - It may be unrelated. However, it does look like you have a bug in the way you recursively call generateRandomCard when a card is found in the alreadyPickedCards array. Instead of
[self generateRandomCard];
I think you should have
return [self generateRandomCard];
You have in -testMethod:
[myGlobals.alreadyPickedCards removeAllObjects];
and in -generateRandomCard you have:
for (int j = 0; j < [myGlobals.alreadyPickedCards count]; j++) {
if (i == [[myGlobals.alreadyPickedCards objectAtIndex:j] shortValue]) {
[self generateRandomCard];
}
}
I can't bet for sure, but this looks like a situation where you removeAllObjects in 1 loop and access an out of bound index in another loop.
If you wanna play like this with arrays, I suggest you make copies of arrays and remove items from those copied arrays.

Rewrite C++ code into Objective C

I got some C++ Sourcecode that I would like to rewrite into Objective C.
It would help me alot if someone could write me a header file for this Code. When I get the Headerfile I would be able to rewrite the rest of the Sourcecode.
It would be very nice if someone could help me please.
Thanks
I will poste the sourcecode here:
#include <stdlib.h>
#include <iostream.h>
#define STATES 5
int transitionTable[STATES][STATES];
// function declarations:
double randfloat (void);
int chooseNextEventFromTable (int current, int table[STATES][STATES]);
int chooseNextEventFromTransitionTablee (int currentState);
void setTable (int value, int table[STATES][STATES]);
//////////////////////////////////////////////////////////////////////////
int main(void) {
int i;
// for demo purposes:
transitionTable[0][0] = 0;
transitionTable[0][1] = 20;
transitionTable[0][2] = 30;
transitionTable[0][3] = 50;
transitionTable[0][4] = 0;
transitionTable[1][0] = 35;
transitionTable[1][1] = 25;
transitionTable[1][2] = 20;
transitionTable[1][3] = 30;
transitionTable[1][4] = 0;
transitionTable[2][0] = 70;
transitionTable[2][1] = 0;
transitionTable[2][2] = 15;
transitionTable[2][3] = 0;
transitionTable[2][4] = 15;
transitionTable[3][0] = 0;
transitionTable[3][1] = 25;
transitionTable[3][2] = 25;
transitionTable[3][3] = 0;
transitionTable[3][4] = 50;
transitionTable[4][0] = 13;
transitionTable[4][1] = 17;
transitionTable[4][2] = 22;
transitionTable[4][3] = 48;
transitionTable[4][4] = 0;
int currentState = 0;
for (i=0; i<10; i++) {
std::cout << currentState << " ";
currentState = chooseNextEventFromTransitionTablee(currentState);
}
return 0;
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// chooseNextEventFromTransitionTable -- choose the next note.
//
int chooseNextEventFromTransitionTablee(int currentState) {
int targetSum = 0;
int sum = 0;
int targetNote = 0;
int totalevents = 0;
int i;
currentState = currentState % STATES; // remove any octave value
for (i=0; i<STATES; i++) {
totalevents += transitionTable[currentState][i];
}
targetSum = (int)(randfloat() * totalevents + 0.5);
while (targetNote < STATES &&
sum+transitionTable[currentState][targetNote] < targetSum) {
sum += transitionTable[currentState][targetNote];
targetNote++;
}
return targetNote;
}
//////////////////////////////
//
// randfloat -- returns a random number between 0.0 and 1.0.
//
double randfloat(void) {
return (double)rand()/RAND_MAX;
}
//////////////////////////////
//
// setTable -- set all values in the transition table to the given value.
//
void setTable(int value, int table[STATES][STATES]) {
int i, j;
for (i=0; i<STATES; i++) {
for (j=0; j<STATES; j++) {
table[i][j] = value;
}
}
}
Update
I'm not only compiling the header file there is another file i'm compiling too
SourceCode:
//
// markovThreadsChainsViewController.m
// markovThreadsChains
//
// Created by Philippe Mokrzycki on 15.01.11.
// Copyright 2011 TGM. All rights reserved.
//
#import "markovThreadsChainsViewController.h"
#import "markov.h"
//#import "markovChainOC.h"
#implementation markovThreadsChainsViewController
#synthesize mcValueLabel, threadStartGenerateButton, threadStopGenerateButton;
- (IBAction) startThreadGen:(UIButton *)sender{
threadStopGenerateButton.hidden=NO;
threadStartGenerateButton.hidden=YES;
mcValueLabel.text = #"0";
currentState=0;
// markovChainOC *mCobc = [[markovChainOC alloc]init];
// [mCobc setCurrentState:0];
[NSThread detachNewThreadSelector:#selector(startThreading) toTarget:self withObject:nil];
}
- (IBAction) stopThreadGen:(UIButton *)sender{
threadStopGenerateButton.hidden=YES;
threadStartGenerateButton.hidden=NO;
[NSThread detachNewThreadSelector:#selector(stopThreading) toTarget:self withObject:nil];
}
- (void) startThreading {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
[NSThread sleepForTimeInterval:3];
[self performSelectorOnMainThread:#selector(markovGen) withObject:nil waitUntilDone:NO];
[pool release];
}
- (void) stopThreading {
[NSThread cancelPreviousPerformRequestsWithTarget:self];
}
- (void)markovGen{
transitionTable[0][0] = 25;
transitionTable[0][1] = 25;
transitionTable[1][0] = 25;
transitionTable[1][1] = 25;
// int actualValue = [mCobc getCurrentState];
int actualValue = currentState;
mcValueLabel.text = [NSString stringWithFormat:#"%", actualValue];
currentState = chooseNextEventFromTransitionTablee(currentState);
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(markovGen) userInfo:nil repeats:NO];
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[mcValueLabel release];
[threadStartGenerateButton release];
[threadStopGenerateButton release];
// [mCobc release];
[super dealloc];
}
#end
This code has nothing object-oriented in it at all. Just change iostream.h to stdio.h, and cout to printf. Then it's a regular C program.
Just put these lines into a header file, and you should be able to include the header and call the functions from any other Objective-C or C source file.
(To support C++ also, you may need to put extern "C" { ... } around them, unless you are compiling everything as C++ or Objective-C++.)
#pragma once
#define STATES 5
int transitionTable[STATES][STATES];
// function declarations:
double randfloat (void);
int chooseNextEventFromTable (int current, int table[STATES][STATES]);
int chooseNextEventFromTransitionTablee (int currentState);
void setTable (int value, int table[STATES][STATES]);
More detail:
To use these functions from another class, you'll need the following files in your project:
markov.h (or whatever you decide to call it), containing the lines above.
markov.c (or whatever you decide to call it), containing the other stuff from your original source file, except for the main function, which you should remove
Then, your other files that use the functions should have an #include "markov.h" line, and then you should be able to call them.
If you are getting linker errors about missing functions, it means that you are not compiling markov.c as part of the project, or there are some options that are causing the function names to not match properly.

objective C for-loop break and continue

How can i use a 'break' statement within a for-loop which continues form a specified label?
ex;
outer: for(int i = 0;i<[arABFBmatches count];i++){
for(int i = 0;i<[arABFBmatches count];i++){
//
break _____;
}
}
How to break to outer?
Hard to say from your question. I'd interpret it that you want to skip the rest of the iterations of the inner loop and continue the outer loop?
for (int i = 0; i < [arABFBmatches count]; i++) {
for (int j = 0; j < [arABFBmatches count]; j++) {
if (should_skip_rest)
break; // let outer loop continue iterating
}
}
Note that I changed the name of your inner loop invariant; using i in both is inviting insanity.
If you want to break from both loops, I wouldn't use a goto. I'd do:
BOOL allDoneNow = NO;
for (int i = 0; i < [arABFBmatches count]; i++) {
for (int j = 0; j < [arABFBmatches count]; j++) {
if (should_skip_rest) {
allDoneNow = YES;
break;
}
}
if (allDoneNow) break;
}
Roughly:
for(int i = 0;i<[arABFBmatches count];i++){
for(int j = 0;j<[arABFBmatches count];j++){
//
goto outer_done;
}
}
outer_done:
Objective-C does not have labelled break.
From Apple's Objective-C docs:
Objective-C is defined as a small but powerful set of extensions to
the standard ANSI C language.
So break and continue can be used wherever they are permitted in C.
continue can be used in looping constructs (for, while and do/while loops).
break can be used in those same looping constructs as well as in switch statements.
BOOL done = NO;
for(int i = 0;i<[arABFBmatches count] && !done; i++)
{
for(int i = 0;i<[arABFBmatches count] && !done;i++)
{
if (termination condition)
{
// cleanup
done = YES;
}
}
}
'break' will only get you out of the innermost loop or switch. You can use 'return' to exit out of a function at any time.Please have a look at the this link.