I built a simple class to handle skill increases for the workers in a strategy game for iOS. The basic idea is that whenever a worker finishes a job, their skill (which starts at 0) will increase by 1. Whenever the skill reaches a multiple of 10, this increases the skill multiplier by 0.10. This multiplier is multiplied with the starting amount of time required to finish a job to calculate the new amount of time required to finish a job. The minimum amount of time to finish is 1. The result is an integer because it is currently counting down ticks of the game rather than actual seconds.
Here is the header for the skill class (every worker has one of these):
#import <Foundation/Foundation.h>
@interface DTDwarfSkills : NSObject
-(void) skillUpMining;
-(void) skillUpBuilding;
-(void) skillUpWorkRoom;
-(void) skillUpFighting;
-(void) skillUpCleaning;
-(void) skillUpHauling;
-(NSMutableDictionary *) skillMultipliers;
-(void) logCurrentSkills;
@end
Here is the implementation:
#import "DTDwarfSkills.h"
@implementation DTDwarfSkills {
int _miningSkill;
int _buildingSkill;
int _workRoomSkill;
int _fightingSkill;
int _cleaningSkill;
int _haulingSkill;
NSMutableDictionary *_skillMultipliers;
}
static const NSString* miningSkillMultiplier = @"miningSkillMultiplier";
static const NSString* buildingSkillMultiplier = @"buildingSkillMultiplier";
static const NSString* workRoomSkillMultiplier = @"workRoomSkillMultiplier";
static const NSString* fightingSkillMultiplier = @"fightingSkillMultiplier";
static const NSString* cleaningSkillMultiplier = @"cleaningSkillMultiplier";
static const NSString* haulingSkillMultiplier = @"haulingSkillMultiplier";
#pragma mark - Initialization
-(id) init {
self = [super init];
if (self) {
_miningSkill = 0;
_buildingSkill = 0;
_workRoomSkill = 0;
_fightingSkill = 0;
_cleaningSkill = 0;
_haulingSkill = 0;
[self buildSkillMultipliers];
}
return self;
}
-(void) buildSkillMultipliers {
NSMutableDictionary *tempDictionary = [[NSMutableDictionary alloc]init];
[tempDictionary setObject:[NSNumber numberWithFloat:0] forKey:miningSkillMultiplier];
[tempDictionary setObject:[NSNumber numberWithFloat:0] forKey:buildingSkillMultiplier];
[tempDictionary setObject:[NSNumber numberWithFloat:0] forKey:workRoomSkillMultiplier];
[tempDictionary setObject:[NSNumber numberWithFloat:0] forKey:fightingSkillMultiplier];
[tempDictionary setObject:[NSNumber numberWithFloat:0] forKey:cleaningSkillMultiplier];
[tempDictionary setObject:[NSNumber numberWithFloat:0] forKey:haulingSkillMultiplier];
_skillMultipliers = [[NSMutableDictionary alloc]initWithDictionary:tempDictionary];
}
#pragma mark - Skill Increases
-(void) skillUpMining {
_miningSkill++;
}
-(void) skillUpBuilding {
_buildingSkill++;
}
-(void) skillUpWorkRoom {
_workRoomSkill++;
}
-(void) skillUpFighting {
_fightingSkill++;
}
-(void) skillUpCleaning {
_cleaningSkill++;
}
-(void) skillUpHauling {
_haulingSkill++;
}
#pragma mark - Compute Skill Multipliers
-(NSMutableDictionary *) skillMultipliers {
[self computeSkillMultipliers];
return _skillMultipliers;
}
-(void) computeSkillMultipliers {
if (_miningSkill % 10 == 0 && _miningSkill <= 100) {
NSNumber *tempNumber = [_skillMultipliers objectForKey:miningSkillMultiplier];
int multiplier = _miningSkill / 10;
tempNumber = [NSNumber numberWithFloat: multiplier * 0.10];
[_skillMultipliers setObject:tempNumber forKey:miningSkillMultiplier];
}
if (_buildingSkill % 10 == 0 && _buildingSkill <= 100) {
NSNumber *tempNumber = [_skillMultipliers objectForKey:buildingSkillMultiplier];
int multiplier = _buildingSkill / 10;
tempNumber = [NSNumber numberWithFloat: multiplier * 0.10];
[_skillMultipliers setObject:tempNumber forKey:buildingSkillMultiplier];
}
if (_workRoomSkill % 10 == 0 && _workRoomSkill <= 100) {
NSNumber *tempNumber = [_skillMultipliers objectForKey:workRoomSkillMultiplier];
int multiplier = _workRoomSkill / 10;
tempNumber = [NSNumber numberWithFloat: multiplier * 0.10];
[_skillMultipliers setObject:tempNumber forKey:workRoomSkillMultiplier];
}
if (_fightingSkill % 10 == 0 && _fightingSkill <= 100) {
NSNumber *tempNumber = [_skillMultipliers objectForKey:fightingSkillMultiplier];
int multiplier = _fightingSkill / 10;
tempNumber = [NSNumber numberWithFloat: multiplier * 0.10];
[_skillMultipliers setObject:tempNumber forKey:fightingSkillMultiplier];
}
if (_cleaningSkill % 10 == 0 && _cleaningSkill <= 100) {
NSNumber *tempNumber = [_skillMultipliers objectForKey:cleaningSkillMultiplier];
int multiplier = _cleaningSkill / 10;
tempNumber = [NSNumber numberWithFloat: multiplier * 0.10];
[_skillMultipliers setObject:tempNumber forKey:cleaningSkillMultiplier];
}
if (_haulingSkill % 10 == 0 && _haulingSkill <= 100) {
NSNumber *tempNumber = [_skillMultipliers objectForKey:haulingSkillMultiplier];
int multiplier = _haulingSkill / 10;
tempNumber = [NSNumber numberWithFloat: multiplier * 0.10];
[_skillMultipliers setObject:tempNumber forKey:haulingSkillMultiplier];
}
}
#pragma mark - Logging for Testing
-(void) logCurrentSkills {
NSLog(@"M=%i, B=%i, W=%i, F=%i, C=%i, H=%i", _miningSkill, _buildingSkill, _workRoomSkill, _fightingSkill, _cleaningSkill, _haulingSkill);
[self computeSkillMultipliers];
[self logSkillMultipliers];
}
-(void) logSkillMultipliers {
NSLog(@"M=%@, B=%@, W=%@, F=%@, C=%@, H=%@", [_skillMultipliers objectForKey:miningSkillMultiplier], [_skillMultipliers objectForKey:buildingSkillMultiplier], [_skillMultipliers objectForKey:workRoomSkillMultiplier], [_skillMultipliers objectForKey:fightingSkillMultiplier], [_skillMultipliers objectForKey:cleaningSkillMultiplier], [_skillMultipliers objectForKey:haulingSkillMultiplier]);
}
@end
Now the relevant code inside the worker class. First I need the constants:
static const NSString* miningSkillMultiplier = @"miningSkillMultiplier";
static const NSString* buildingSkillMultiplier = @"buildingSkillMultiplier";
static const NSString* workRoomSkillMultiplier = @"workRoomSkillMultiplier";
static const NSString* fightingSkillMultiplier = @"fightingSkillMultiplier";
static const NSString* cleaningSkillMultiplier = @"cleaningSkillMultiplier";
static const NSString* haulingSkillMultiplier = @"haulingSkillMultiplier";
static const int startingMiningCount = 8;
static const int startingBuildCount = 8;
static const int startingWorkRoomCount = 20;
static const int startingFightCount = 10;
static const int startingCleanCount = 30;
static const int startingHaulCount = 4;
Then this is the method called when the worker updates:
-(void) checkSkills {
NSMutableDictionary *tempDictionary = [_dwarfSkills skillMultipliers];
NSNumber *miningMultiplier = [tempDictionary objectForKey:miningSkillMultiplier];
_miningDelayCount = [self computeSkillForSkillMultiplier:miningMultiplier andSkillValue:startingMiningCount];
NSNumber *buildingMultiplier = [tempDictionary objectForKey:buildingSkillMultiplier];
_buildDelayCount = [self computeSkillForSkillMultiplier:buildingMultiplier andSkillValue:startingBuildCount];
NSNumber *workRoomMultiplier = [tempDictionary objectForKey:workRoomSkillMultiplier];
_roomUpgradeDelayCount = [self computeSkillForSkillMultiplier:workRoomMultiplier andSkillValue:startingWorkRoomCount];
NSNumber *fightingMultiplier = [tempDictionary objectForKey:fightingSkillMultiplier];
_fightDelayCount = [self computeSkillForSkillMultiplier:fightingMultiplier andSkillValue:startingFightCount];
NSNumber *cleaningMultiplier = [tempDictionary objectForKey:cleaningSkillMultiplier];
_cleanDelayCount = [self computeSkillForSkillMultiplier:cleaningMultiplier andSkillValue:startingCleanCount];
NSNumber *haulingMultiplier = [tempDictionary objectForKey:haulingSkillMultiplier];
_pickupItemDelayCount = [self computeSkillForSkillMultiplier:haulingMultiplier andSkillValue:startingHaulCount];
}
-(int) computeSkillForSkillMultiplier:(NSNumber *)multiplier andSkillValue:(int)skillValue {
int oldSkillValue = skillValue;
float numberToSubtract = [multiplier floatValue] * oldSkillValue;
int newSkillValue = oldSkillValue -= numberToSubtract;
if (newSkillValue < 1) {
newSkillValue = 1;
}
return newSkillValue;
}
I'm sure there are lots of ways to improve this, so please be as critical as you like. You won't hurt my feelings.