A brief background:
I'm working on a game prototype for a simple strategy game. After I created a number of possible jobs I wanted to create something to manage them. This is the first time I've attempted something like this so code review would be helpful.
I created a set of methods that adds Jobs to a Job Queue and assigns them to Dwarves if they don't currently have a job. That way, the player can add a number of jobs, and as long as the job is valid, it will be added to the Queue.
First the relevant enum:
typedef enum {
MiningJob = 0,
LadderJob,
BottomBuildJob,
WallBuildJob,
RoomBuildJob
}JobType;
Here is the main code for the Job Queue:
#pragma mark - Job Queue
-(void) addJobToQueueOfType:(int)jobType forFloor:(int)floorNumber {
if ([self checkIfFloor:floorNumber isValidForJob:jobType]) {
DTJob *tempJob = [[DTJob alloc]init];
tempJob.jobType = jobType;
tempJob.floorNumber = floorNumber;
[_jobQueue insertObject:tempJob atIndex:0];
}
}
-(BOOL) checkIfFloor:(int)floorNumber isValidForJob:(int)jobType {
NSNumber *floorNum = [NSNumber numberWithInt:floorNumber];
DTTowerFloor *tempFloor = [self.gameTower.towerDict objectForKey:floorNum];
switch (jobType) {
case MiningJob:
if (tempFloor.hasLadder && tempFloor.isRevealed && tempFloor.blockPercentageRemaining > 0) {
return YES;
}
break;
case LadderJob:
if (!tempFloor.hasLadder && tempFloor.isRevealed && self.currentCommonResources >= _ladderCost && !tempFloor.hasActiveWorker) {
return YES;
}
break;
case BottomBuildJob:
if (tempFloor.isRevealed && tempFloor.hasLadder && tempFloor.blockPercentageRemaining <= 0 && !tempFloor.hasBottom && self.currentCommonResources >= _bottomCost && !tempFloor.hasActiveWorker) {
return YES;
}
break;
case WallBuildJob:
if (tempFloor.isRevealed && tempFloor.hasBottom && !tempFloor.hasWalls && self.currentCommonResources >= _wallCost && !tempFloor.hasActiveWorker) {
return YES;
}
break;
case RoomBuildJob:
if (tempFloor.isRevealed && tempFloor.hasBottom && tempFloor.hasWalls && self.currentCommonResources >= _roomCost && !tempFloor.hasActiveWorker) {
return YES;
}
break;
default:
break;
}
return NO;
}
-(void) assignJob:(DTJob *)job toDwarf:(DTDwarf *)dwarf {
switch (job.jobType) {
case MiningJob:
[self assignMiningJobToDwarf:dwarf forFloor:job.floorNumber];
break;
case LadderJob:
[self assignLadderJobToDwarf:dwarf forFloor:job.floorNumber];
break;
case BottomBuildJob:
[self assignBottomBuildJobToDwarf:dwarf forFloor:job.floorNumber];
break;
case WallBuildJob:
[self assignWallBuildJobToDwarf:dwarf forFloor:job.floorNumber];
break;
case RoomBuildJob:
[self assignRoomBuildJobToDwarf:dwarf forFloor:job.floorNumber];
break;
default:
break;
}
}
//this is called from the update loop
-(BOOL) isDwarfAvailable {
for (DTDwarf *tempDwarf in self.dwarves) {
if (!tempDwarf.hasJobAssigned && !tempDwarf.isMoving) {
_nextDwarf = tempDwarf;
return YES;
}
}
return NO;
}
Here is the call from the Update loop which runs every 0.25 seconds according to the time step of the SKScene:
-(void) checkAssignJobToDwarfFromQueue {
if ([self isDwarfAvailable] && _jobQueue.count > 0) {
DTJob *tempJob = [_jobQueue lastObject];
[_jobQueue removeLastObject];
if (_nextDwarf != nil && !_nextDwarf.hasJobAssigned) {
[self assignJob:tempJob toDwarf:_nextDwarf];
}
}
}
Forgot to post the last part. This is how the SKScene sends the Job to the Queue. There are two different menus, so I couldn't see how to use the enum for the names here.
#pragma mark - Interaction with the Game
-(void) doSimpleJob:(int)jobNumber forFloor:(int)floorNumber {
switch (jobNumber) {
case 0:
//mining job
[_game addJobToQueueOfType:MiningJob forFloor:floorNumber];
break;
case 1:
//ladder job
[_game addJobToQueueOfType:LadderJob forFloor:floorNumber];
break;
case 2:
[self buildBuildingSelectionBoxForFloor:floorNumber];
_buildingSelectionBoxIsOpen = YES;
break;
default:
break;
}
}
-(void) doBuildJob:(int)jobNumber{
switch (jobNumber) {
case 0:
//bottom build job
[_game addJobToQueueOfType:BottomBuildJob forFloor:_selectedFloor];
break;
case 1:
//wall build job
[_game addJobToQueueOfType:WallBuildJob forFloor:_selectedFloor];
break;
case 2:
//room build job
[_game addJobToQueueOfType:RoomBuildJob forFloor:_selectedFloor];
break;
default:
break;
}
}