Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 4110140
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T21:53:43+00:00 2026-05-20T21:53:43+00:00

assume that i have two sequential methods, methodA and methodB ( methodB is called

  • 0

assume that i have two sequential methods, methodA and methodB (methodB is called at the end of methodA) and i need to finish completely with the process of methodA before starting methodB :

-(void)methodA {

    //do some very heavy computation here
    [self methodB];
}

-(void)methodB {

    //this method performs some animation

}

methodA requires alot of processing power and takes time to finish while methodB has animations. The animations are starting laggy at first and im guessing this has to do with the overhead of method A. So how can i make the second method start only after the first has finished completely?


this is the actual code:

the code is very messy and unorganized. there is alot of code that has been commented out so please ingore that. I test some things sometimes and then comment them out incase i need them later.

here is what is happening: it starts with (void)checkMoves method. This method calls either one of two similar methods which are

-(void)getMovesForJourney:(int)journey withRolls:(NSArray *)rolls or

-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls

these methods are wrappers for a long recursive process (which is most probably where the multithreading is happening).

at the end of (void)checkMoves another method -(void)analyseMoves is called. This is also a heavy process.
and finally, at the end of -(void)analyseMoves the animation method -(void)move: is called. this last method is starting with a lag.

finally at the end of -(void)move: the process will start again until no more ‘moves’ are available.

the methods below are not in order so please refer to the description above to know whats going on.

-(void) checkMoves {

    GameScene *game = [GameScene sharedGameScene];

    CCLOG(@"start");
    for (Stone *stone in stones) {

        if (!stone.onBoard) {

            if ([game EntryAvailable]) {
                [self getEntryMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];

                }
        }

        else {


            [self getMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];

        }
    }

    CCLOG(@"finish");

    [self analyseMoves];

}

-(NSMutableArray *) otherPlayerLocations {

    GameScene *game = [GameScene sharedGameScene];
    Board *board = [game board];
    Player *otherPlayer = [game playerOne];
    NSMutableArray *locations = [[[NSMutableArray alloc] init] autorelease];
    for (Stone *stone  in otherPlayer.stones) {

        if (stone.journey < 77) {
            int location;
            if (stone.onBoard)
                location = [[board tileForATag:[self convertJourneyToTileTag:stone.journey]] bTag];
            else
                location = 0;

            [locations addObject:[NSNumber numberWithInt:location]];
        }
    }

    return locations;
}

-(void) analyseMoves {

    if (moves.count > 0) {

        NSMutableArray *killMoves = [[[NSMutableArray alloc] init] autorelease];
        NSMutableArray *safeMoves = [[[NSMutableArray alloc] init] autorelease];

        int mostThreatened;
        float highestThreat = -1.0;
        float lowestThreat = 100.0;
        AIMove *safestMove;

        //get kill and safe moves in seperate arrays
        for (AIMove *move in moves) {

            if (move.moveType == killMoveType)
                [killMoves addObject:move];

            else if (move.moveType == safeMoveType)
                [safeMoves addObject:move];

            // get highest threatened stone

            //if (move.potThreat > highestThreat) {

             //   mostThreatened = move.journey;
             //   highestThreat = move.potThreat;

                if (move.initThreat < lowestThreat) {
                    lowestThreat = move.initThreat;
                    safestMove = [move copy];
                    CCLOG(@"safest move assigned");
                }
            //}
        }

        //MOVE SELECTION:
        //___________________________________

        //choose best kill move
        int killJourney;
        if (killMoves.count > 0) {

            //leave one move in killMoves with highest journey
            killJourney = [[killMoves objectAtIndex:0] tileTag];
            for (AIMove *killMove in killMoves) {
                if (killMove.tileTag < killJourney)
                    [killMoves removeObject:killMove];
                else
                    killJourney = killMove.tileTag;
            }
        }


        //select correct move
        if (killMoves.count > 0) {

            [self move:[killMoves objectAtIndex:0]];
            CCLOG(@"Kill move chosen");
        }

        else {
            CCLOG(@"this is called!!!!");
            CCLOG(@"safest move with initThreat: %i, potThreat: %i",safestMove.journey, safestMove.tileTag);
            [self move:safestMove];
            CCLOG(@"Success");

        }
        /*

        else if (safeMoves.count > 0) {

            [self move:[safeMoves objectAtIndex:0]];
            CCLOG(@"safe move chosen");
        }

        else {

            //temp random move generation
            randomMove = CCRANDOM_0_1()*[moves count];

            AIMove *move = [moves objectAtIndex:randomMove];
            [self move:move];
            CCLOG(@"Random move chosen");
        }
         */

    }
}


-(void) assignThreatLevel:(AIMove *)move {

    NSArray *otherPlayerStones = [self otherPlayerLocations];
    NSMutableArray *initThreats = [[NSMutableArray alloc] init];
    NSMutableArray *potThreats = [[NSMutableArray alloc] initWithCapacity:4];



    for (NSNumber *location in otherPlayerStones) {

        //get threat levels for potential moves
        if (move.tileTag > [location intValue]) {

            int dif = move.tileTag - [location intValue];
            CCLOG(@"dif: %i",dif);
            //threat level conditions:
            // 1 >> 5 =   70% of journey
            // 6 >> 9 =   40% of journey
            // 10 & 11 =  50% of journey
            // 12 >> 24 = 20% of journey
            // 25 && 26 = 50% of journey
            // 27+ =      20% of journey

            if (move.tileTag < 9) {
                [initThreats addObject:[NSNumber numberWithFloat:0.0f]];
            }

            else if (dif >= 1 && dif <= 5) {
                [initThreats addObject:[NSNumber numberWithFloat:k1to5]];


            }

            else if (dif >= 6 && dif <= 9) {
                [initThreats addObject:[NSNumber numberWithFloat:k6to9]];



            }

            else if (dif == 10 || dif == 11) {
                [initThreats addObject:[NSNumber numberWithFloat:k10to11]];



            }

            else if (dif >= 12  && dif <= 24) {
                [initThreats addObject:[NSNumber numberWithFloat:k12to24]];



            }

            else if (dif == 25 || dif == 26) {
                [initThreats addObject:[NSNumber numberWithFloat:k25to26]];



            }

            else if (dif > 26) {
                [initThreats addObject:[NSNumber numberWithFloat:k27plus]];


            }

            //-------------------------------------
        }

        //get Threat levels for current positions
        if (move.tileTag > [location intValue]) {

            int dif = move.tileTag - [location intValue];

            //threat level conditions:
            // 1 >> 5 =   70% of journey
            // 6 >> 9 =   40% of journey
            // 10 & 11 =  50% of journey
            // 12 >> 24 = 20% of journey
            // 25 && 26 = 50% of journey
            // 27+ =      20% of journey

            if (move.journey < 8 || move.journey > 75)
                [potThreats addObject:[NSNumber numberWithFloat:0.0f]];

            else if (dif >= 1 && dif <= 5)
                [potThreats addObject:[NSNumber numberWithFloat:k1to5]];

            else if (dif >= 6 && dif <= 9)
                [potThreats addObject:[NSNumber numberWithFloat:k6to9]];

            else if (dif == 10 || dif == 11)
                [potThreats addObject:[NSNumber numberWithFloat:k10to11]];

            else if (dif >= 12  && dif <= 24)
                [potThreats addObject:[NSNumber numberWithFloat:k12to24]];

            else if (dif == 25 || dif == 26)
                [potThreats addObject:[NSNumber numberWithFloat:k25to26]];

            else if (dif > 26)
                [potThreats addObject:[NSNumber numberWithFloat:k27plus]];

            //-------------------------------------
        }


    }

    float initThreat = 0.0f;
    float potThreat = 0.0f;
    for (NSNumber *number in initThreats) {

        if ([number floatValue] > initThreat) 
            initThreat = [number floatValue];
    }


    for (NSNumber *number in potThreats) {

        if ([number floatValue] > potThreat)
            potThreat = [number floatValue];
    }

    move.initThreat = initThreat;
    move.potThreat = potThreat;
    [initThreats release];

}




-(void) move:(AIMove *)move {

    CCLOG(@"Moves count: %i",[moves count]);
    if ([moves count] > 0) {

        BOOL isOtherStoneOnPreviousTile = NO;

        int total;
        if (move.tileTag > 8)
            total = move.tileTag - move.journey;
        else if (move.tileTag < 9 && move.journey > 8)
            total = ((9-move.tileTag)+75) - move.journey;
        else if (move.tileTag < 9)
            total = move.tileTag - move.journey;
        CCLOG(@"Total: %i",total);

        GameScene *game = [GameScene sharedGameScene];
        Board *board = [game board];
        BoardTile *tile = [[game board] tileForBTag:move.tileTag];
        CCSequence *sequence;
        NSMutableArray *actions = [[[NSMutableArray alloc] init] autorelease];
        id delay = [CCDelayTime actionWithDuration:0.5];
        [actions addObject:delay];

        if (move.journey > 0) {

            for (int i = 1; i < total+1; i++) {
                if (move.journey+i < 76)
                    tile = [board tileForBTag:move.journey+i];
                else 
                    tile = [board tileForBTag:9-((move.journey+i)-75)];
                id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
                [actions addObject:moveAction];
            }
        }

        else {
            id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
            [actions addObject:moveAction];
        }


       // id moveFunc = [CCCallFunc actionWithTarget:self selector:@selector(moveMotion)]; 

        //id moveAction = [CCMoveTo actionWithDuration:0.3 position:tile.position];
        id killFunc = [CCCallFuncND actionWithTarget:self selector:@selector(killStonesForTile:data:) data:tile];
        //id callfunc = [CCCallFunc actionWithTarget:self selector:@selector(move)];
        [actions addObject:killFunc];
        //[actions addObject:callfunc];
        sequence = [CCSequence actionMutableArray:actions];
        [actions removeAllObjects];

        CGPoint exitPos = ccp(exitPosition.x-(completeStones*30),exitPosition.y-(completeStones*30));

        id move2 = [CCMoveTo actionWithDuration:0.2f position:exitPos];
        id sequence2 = [CCSequence actions:move2, nil];

        Stone *stone = [self getStoneForJourney:move.journey];

        //-

        //------------------------------------------
        //clean tracks

        for (Stone *stone in stones) {

            if (stone.journey == (move.tileTag - move.journey))
                isOtherStoneOnPreviousTile = YES;
        }

        if (!isOtherStoneOnPreviousTile) {

            BoardTile *prevTile = [board tileForBTag:[self convertJourneyToTileTag:move.journey]];
            prevTile.occupiedBy = 0;
        }

        //===========================================

        //-------------------------------------------
        //set stone status

        if (move.tileTag < 9 && stone.crossedEntry)
            stone.journey = (9 - move.tileTag) + 75;
        else 
            stone.journey = move.tileTag;
        stone.onBoard = YES;
        tile.occupiedBy = player2;

        if (stone.journey > 8 && !stone.crossedEntry)
            stone.crossedEntry = YES;

        //============================================


        if (stone.journey < 84)
            [stone runAction:sequence];

        else {

            [stone runAction:sequence2];
            completeStones++;
            stone.isJourneyComplete = YES;
        }

        CCLOG(@"Stone Journey:%i",stone.journey);
        NSArray *rollTypesArray = [move rollTypes];
        [self removeRollTypes:rollTypesArray];

        [moves removeAllObjects];
        [game updateRollResults];
        [self updateMoveAvailability];

    }

    else {
        GameScene *game = [GameScene sharedGameScene];
        [moves removeAllObjects];
        [game nextTurn];
        [game updateRollResults];

    }




}


-(Stone *)getStoneForJourney:(int)journey {

    Stone *theStone;
    for (Stone *stone in stones) {

        if (stone.journey == journey) 
            theStone = stone;
    }

    return theStone;
}

-(void)dealloc {

    [moves release];
    [rollTypes release];
    [results release];
    [super dealloc];

}


-(void)killStonesForTile:(id)sender data:(BoardTile *)tile {

    GameScene *game = [GameScene sharedGameScene];

    int tileTag;
    Player *otherPlayer;

    if (playerNumber == player1) {
        tileTag = tile.aTag;
        otherPlayer = [game playerTwo];
    }
    else {
        tileTag = tile.bTag;
        otherPlayer = [game playerOne];
    }

    CCArray *currentStones = [otherPlayer stones];

    for (Stone *stone in currentStones) {

        if (!stone.isJourneyComplete) {

            int journey = stone.journey;

            if (tileTag == tile.aTag) {

                if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.bTag) {

                    CCLOG(@"blue stone killed");

                    [self returnStoneToOrigin:stone];

                }

            }

            if (tileTag == tile.bTag) {

                if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.aTag) {

                    CCLOG(@"gold stone killed");

                    [self returnStoneToOrigin:stone];

                }           
            }
        }
    }
}

-(void)removeRollTypes:(NSArray *)theRollTypes {

    GameScene *game = [GameScene sharedGameScene];
    NSMutableArray *rolls = [game rolls];

        for (NSNumber *roll in theRollTypes) {

            NSUInteger index = [rolls indexOfObject:[game convertIntToRoll:roll]];
            CCLOG(@"rolltypes count: %i",[theRollTypes count]);
            CCLOG(@"roll integer: %i",[roll intValue]);
            [rolls removeObjectAtIndex:index];
        }
}

#pragma mark -
#pragma mark enumerations

- (NSArray*)getSums:(NSArray*)numbers {

    NSMutableArray *result = [self getSumsHelper:numbers startingFrom:0];
    [result removeObjectAtIndex:0];
    return result;
}

- (NSMutableArray*)getSumsHelper:(NSArray*)numbers startingFrom:(NSUInteger)index {
    /* (1) */
    if (index >= [numbers count])
        return [NSMutableArray arrayWithObject:[NSNumber numberWithFloat:0]];

    /* (2) Generate all the subsets where the `index`th element is not included */
    NSMutableArray* result = [self getSumsHelper:numbers startingFrom:index+1];

    //  NSSortDescriptor *mySorter = [[NSSortDescriptor alloc] initWithKey:@"floatValue" ascending:YES];
    //  [result sortUsingDescriptors:[NSArray arrayWithObject:mySorter]];
    /* (3) Add all the cases where the `index`th element is included */

    NSUInteger i, n = [result count];

    float element = [[numbers objectAtIndex:index] floatValue];
    for (i = 0; i < n; i++) {
        float element2 = [[result objectAtIndex:i] floatValue];
        float sum = element+element2;
        BOOL numberPresent = NO;
        for (NSNumber *number in result) {
            if ([number floatValue] == sum)
                numberPresent = YES;
        }
        if (!numberPresent)
            [result addObject:[NSNumber numberWithFloat:sum]];

    }
    return result;
}

-(NSArray *) getCombsforNumbers:(NSArray *)numbers withTarget:(int)target{

    NSMutableArray *partial = [[NSMutableArray alloc] init];
    [partial addObject:[NSNumber numberWithInt:0]];
    [results removeAllObjects];
    NSArray *result = [self getCombsHelper:numbers target:target partial:partial];

    NSUInteger minCount = [[result objectAtIndex:0] count];
    NSUInteger index = 0;
    NSMutableArray *combArray = [result objectAtIndex:0];
    for (NSMutableArray *array in result) {

        if ([array count] < minCount) {
            minCount = [array count];
            index = [result indexOfObject:array];
            combArray = array;
        }
    }

    //remove number 0 from array
    [combArray removeObject:[NSNumber numberWithInt:0]];
    return combArray;
}

-(NSMutableArray *) getCombsHelper:(NSArray *)numbers target:(int)target partial:(NSMutableArray *)partial {

    int s = 0;
    for (NSNumber *number in partial) {
        s += [number intValue];
    }

    if (s == target) {

        [results addObject:partial];


    }

    if (s >= target) {

        return results;
    }

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

        NSMutableArray *remaining = [[[NSMutableArray alloc] init] autorelease];
        int n = [[numbers objectAtIndex:i] intValue];
        for (int j = i+1; j<[numbers count]; j++) {
            [remaining addObject:[numbers objectAtIndex:j]];
        }

        NSMutableArray *partialRec = [[[NSMutableArray alloc] init] autorelease];
        [partialRec addObjectsFromArray:partial];

        [partialRec addObject:[NSNumber numberWithInt:n]];

        [self getCombsHelper:remaining target:target partial:partialRec];
    }

    return results;

}


-(void) getMovesForJourney:(int)journey withRolls:(NSArray *)rolls {

    GameScene *game = [GameScene sharedGameScene];
    Board *board = [game board];

    NSArray *sums = [self getSums:rolls];
    for (NSNumber *number in sums) {

        if ([number intValue]+journey <= 84) {

            BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
            if (tile.isSafeTile) {
                if (tile.occupiedBy != player1) {
                    AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
                    NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];

                    //Checking rolltypes, remove later
                    NSLog(@"%i = ",[number intValue]);
                    for (NSNumber *comb in theRollTypes) {
                        NSLog(@"%i",[comb intValue]);
                    }
                    NSLog(@"-----------");
                    //----------------------------------
                    move.moveType = safeMoveType;
                    move.initThreat = 0.0;

                    CCLOG(@"move initThreat: %f",move.initThreat);


                    [move setRollTypes:theRollTypes];
                    [moves addObject:move];

                }
            }
            else {
                AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
                NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];

                //Checking rolltypes, remove later
                NSLog(@"%i = ",[number intValue]);
                for (NSNumber *comb in theRollTypes) {
                    NSLog(@"%i",[comb intValue]);
                }
                NSLog(@"-----------");
                //-----------------------------------

                [move setRollTypes:theRollTypes];


                //assing threat level
                [self assignThreatLevel:move];

                CCLOG(@"move initThreat: %f",move.initThreat);



                //check for kill move
                NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
                for (NSNumber *location in otherPlayerPositions) {

                    if (move.tileTag == [location intValue])
                        move.moveType = killMoveType;

                }

                [moves addObject:move];
            }
        }
        //int i = [number intValue];
        //NSArray *combs = [self getCombsforNumbers:numbers withTarget:i];

    }
}


-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls {

    GameScene *game = [GameScene sharedGameScene];
    Board *board = [game board];

    NSArray *sums = [self getSums:rolls];
    for (NSNumber *number in sums) {

        if ([number intValue]+journey <= 84) {

            BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
            if (tile.isSafeTile) {
                if (tile.occupiedBy != player1) {
                    NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];


                    BOOL containsEntry = NO;
                    for (NSNumber *rollType in theRollTypes) {
                        if ([rollType intValue] == 1) {
                            containsEntry = YES;
                        }
                    }

                    if (containsEntry) {

                        AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];

                        //Checking rolltypes, remove later
                        NSLog(@"%i = ",[number intValue]);
                        for (NSNumber *comb in theRollTypes) {
                            NSLog(@"%i",[comb intValue]);
                        }
                        NSLog(@"-----------");

                        move.moveType = safeMoveType;

                        move.initThreat = 0.0;

                        CCLOG(@"move initThreat: %f",move.initThreat);


                        [move setRollTypes:theRollTypes];
                        [moves addObject:move];
                        //----------------------------------
                    }
                }
            }
            else {
                NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
                BOOL containsEntry = NO;
                for (NSNumber *rollType in theRollTypes) {
                    if ([rollType intValue] == 1) {
                        containsEntry = YES;
                    }
                }

                if (containsEntry) {

                    AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
                    [move setRollTypes:theRollTypes];

                    //check for kill move
                    NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
                    for (NSNumber *location in otherPlayerPositions) {

                        if (move.tileTag == [location intValue])
                            move.moveType = killMoveType;

                    }

                    //assing threat level
                    [self assignThreatLevel:move];

                    [moves addObject:move];


                    //Checking rolltypes, remove later
                    NSLog(@"%i = ",[number intValue]);
                    for (NSNumber *comb in theRollTypes) {
                        NSLog(@"%i",[comb intValue]);
                    }
                    NSLog(@"-----------");

                    CCLOG(@"move initThreat: %f",move.initThreat);

                    [move setRollTypes:theRollTypes];
                    [moves addObject:move];
                    //----------------------------------
                }
            }
        }

    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T21:53:43+00:00Added an answer on May 20, 2026 at 9:53 pm

    Technically, methodB is called after methodA is finished. In methodA you are apparently doing things that are backgrounded, meaning that the method finishes while some tasks are performed on another thread (or scheduled on the runloop). There’s nothing we can say about this unless you do share the inner workings of methodA.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.