There are many ways I can think of to do this, which one is best depends entirely on your specific problem. I'll suggest two:
The first is to jump out of OOP entirely. Object Oriented programming is all about coupling data with functionality, but in this case there really isn't any data to speak of: a Card
is just a function applied to your game state. You can make an NSArray
of blocks
, and pick a function to execute at random.
typedef void (^EventCard)(NSArray* buildings, Map* map);
EventCard earthQuake = [^ void {
//show an alertview saying its an earthquake so the user knows what is going on
//apply earthquake to the buildings and map
} copy];
The disadvantage of this is that you probably will end up writing a lot of duplicate code, and won't be able to easily add new event cards.
The next solution is similar to what you have now, but more extensible. Your Card
class becomes a set of dictionaries, whose keys correspond to properties of your building and map objects, or are triggers for logic in the applyEventCardMethod
. You can (and should) read those dictionaries in from plist files or JSON text which are opened and used to make a instance of Card
. So your Card.h
looks like this
@interface Card : NSObject
@property (strong) NSDictionary* attributesToAffect;
@property (strong) NSArray* targetFilters;
and the earthquake example might have targetFilters of @[@"all_buildings"]
and the attributesToAffect would be @{currHp: @-100}
, if your building class has a currHp property. ApplyEventCard now looks like this
-(void) applyEventCard
{
//pick a random Event card
//get all targets based on the "targets" key
//loop through targets
//loop through the rest of the keys
NSInteger previousValue = [[currBuilding valueForKey: currKey] integerValue];
NSInteger valueToApply = eventCardToApply.attributeDict[currAttribute];
[currBuilding setValue: previousValue - valueToApply forKey: currKey];
}
The advantage of this approach is that it is incredibly easy to add new cards, and there is no code required. However, you are potentially seriously constrained in the effects your cards can have. If a lot of your cards need custom logic of some sort there may not be any way to avoid a monstrous switch statement.