HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Board Evaluator for Bejeweled Clone

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
bejeweledevaluatorforcloneboard

Problem

I've been prototyping a Match 3 game (Bejeweled clone) because I have an interesting concept for one, and because it is good practice. One key aspect of my version is that the matches must contain one of the swapped orbs. Therefore matches elsewhere on the board do not get destroyed (and for now there are no combos).

To solve this, I devised a special algorithm that searches for matches starting with the positions of the swapped orbs.

Since this is a naive implementation of Match 3, I am sure that there are lots of problems with the code and especially with the algorithm.

Here is the initial evaluation that happens when a player tries to swap two orbs:

-(BOOL) swapOrb:(DMOrb *)firstOrb withOrb:(DMOrb *)secondOrb {

    //if its the same orb, fail
    if ([firstOrb isEqual:secondOrb]) {
        return  NO;
   }
   //check and make sure that the orbs are next to each other
    if (![self orbAdjacent:firstOrb toOrb:secondOrb]) {
        return NO;
    }

    //potentially check and make sure they are not the same color here

    //makes a copy of the board inside the eval class
    _boardEval.board = self.board;

    //actually moves the pieces, but will only save the new board if there is a match
    if ([_boardEval swapHasMatchesForOrb:firstOrb withOrb:secondOrb]) {
        [_boardEval resolveSwapBetweenPosition:firstOrb.boardPosition position:secondOrb.boardPosition];
        self.board = _boardEval.board;
        return YES;
    }

    return NO;
}


And here is the board evaluator class. It is possible that all of this class should simply be in the GameBoard class, but I am unsure. Right now the Game class has both the GameBoard and the BoardEvaluator, and processes the moves of the game sent by the UI.

DMBoardEval.h

```
#import
#import "DMGameBoard.h"

@interface DMBoardEval : NSObject

@property (nonatomic) DMGameBoard *board;

-(BOOL) swapHasMatchesForOrb:(DMOrb )firstOrb withOrb:(DMOrb )secondOrb;
-(void) resolveSwapBetweenPosition:(C

Solution

This can be 100% eliminated:

-(void) setBoard:(DMGameBoard *)board {
    _board = [DMGameBoard boardWithBoard:board];
}


And instead, change the property declaration to look like this:

@property (copy) DMGameBoard *board;


I'd rewrite this method:

-(BOOL) findMatchesForOrb:(DMOrb *)orb {
    if ([self searchRowForMatchesWithOrb:orb]) {
        return YES;
    }
    if ([self searchColumnForMatchesWithOrb:orb]) {
        return YES;
    }
    return NO;
}


As this (notice I'm also renaming... "find matches" implies we'll return matches):

- (BOOL)hasMatchesForOrb:(DMOrb *)orb {
    return [self searchRowForMatchesWithOrb:orb] || 
        [self searchColumnForMatchesWithOrb:orb];
}


for (int i = orb.boardPosition.x; i = 3) {
    return YES;
}


This is just a subsection of one of your methods, but it's a little confusing. Let' see if we can clear it up and make it a little more efficient.

for (int i = orb.boardPosition.x; i = 3) {
            return YES;
        }
    } else {
        break;
    }
}


This pattern can be applied in 3 other places. This pattern eliminates the otherColorFound variable and saves us a lot of iterations. Consider if your row is say 20 orbs wide, and I move an orb into the 20th spot. Your original implementation will iterate 20 times no matter what. With this implementation, we stop as soon as we find a different .type or as soon as we find 3 in a row.

Code Snippets

-(void) setBoard:(DMGameBoard *)board {
    _board = [DMGameBoard boardWithBoard:board];
}
@property (copy) DMGameBoard *board;
-(BOOL) findMatchesForOrb:(DMOrb *)orb {
    if ([self searchRowForMatchesWithOrb:orb]) {
        return YES;
    }
    if ([self searchColumnForMatchesWithOrb:orb]) {
        return YES;
    }
    return NO;
}
- (BOOL)hasMatchesForOrb:(DMOrb *)orb {
    return [self searchRowForMatchesWithOrb:orb] || 
        [self searchColumnForMatchesWithOrb:orb];
}
for (int i = orb.boardPosition.x; i < kNumOrbsPerRow; i++) {
    if (!otherColorFound) {
        if (orb.type == ((DMOrb *)row.orbs[i]).type) {
            numberOfOrbs++;
        } else {
            otherColorFound = YES;
        }
    }
}
if (numberOfOrbs >= 3) {
    return YES;
}

Context

StackExchange Code Review Q#74221, answer score: 8

Revisions (0)

No revisions yet.