![]() |
00001 // 00002 // CogitoAgent.m 00003 // Author: Thomas Taylor 00004 // 00005 // Base class for machine learning 00006 // 00007 // 20/02/2012: Created class 00008 // 00009 00010 #import "CogitoAgent.h" 00011 00012 @implementation CogitoAgent 00013 00014 #pragma mark - 00015 #pragma mark Initialisation 00016 00021 -(id)init 00022 { 00023 self = [super init]; 00024 00025 if (self != nil) 00026 { 00027 respawns = [[LemmingManager sharedLemmingManager] learningEpisodes]; 00028 learningMode = YES; 00029 } 00030 return self; 00031 } 00032 00033 #pragma mark - 00034 00040 -(Action)selectAction:(State*)_state 00041 { 00042 CCArray* actions = [self calculateAvailableActions:_state]; 00043 00044 // choose a random action 00045 Action action = -1; 00046 if(self.state != kStateDead && [_state getGameObject].gameObjectType != kObjectExit) 00047 action = [self chooseRandomAction:actions]; 00048 00049 return action; 00050 } 00051 00057 -(Action)chooseRandomAction:(CCArray*)_actions 00058 { 00059 Action action = -1; 00060 00061 int randomIndex = [Utils generateRandomNumberFrom:0 to:[_actions count]]; 00062 action = [[_actions objectAtIndex:randomIndex] intValue]; 00063 00064 return action; 00065 } 00066 00073 -(CCArray*)calculateAvailableActions:(State*)_state 00074 { 00075 GameObject* object = [_state getGameObject]; 00076 CCArray* actions = [CCArray arrayWithCapacity:0]; 00077 00078 [actions addObject:[NSNumber numberWithInt:kActionLeft]]; 00079 [actions addObject:[NSNumber numberWithInt:kActionRight]]; 00080 00081 if(helmetUses > 0) 00082 { 00083 [actions addObject:[NSNumber numberWithInt:kActionLeftHelmet]]; 00084 [actions addObject:[NSNumber numberWithInt:kActionRightHelmet]]; 00085 } 00086 00087 // add 'down' action if appropriate 00088 if(object.gameObjectType == kObjectTrapdoor) 00089 { 00090 [actions addObject:[NSNumber numberWithInt:kActionDown]]; 00091 if(umbrellaUses > 0) [actions addObject:[NSNumber numberWithInt:kActionDownUmbrella]]; 00092 } 00093 else if(object.gameObjectType == kObjectTerrainEnd && umbrellaUses > 0) 00094 [actions addObject:[NSNumber numberWithInt:kActionEquipUmbrella]]; 00095 00096 [_state setActions:actions]; 00097 return actions; 00098 } 00099 00105 -(State*)getStateForGameObject:(GameObject*)_object 00106 { 00107 return [[State alloc] initStateForObject:_object]; 00108 } 00109 00110 #pragma mark - 00111 #pragma mark Overrides 00112 00118 -(void)onObjectCollision:(GameObject*)_object 00119 { 00120 // need to know if the lemming's fall was fatal (has to be checked before call to super and fallCounter's reset) 00121 BOOL fatalFall = (fallCounter >= ((float)kLemmingFallTime*(float)kFrameRate) && self.state != kStateFloating) ? YES : NO; 00122 00123 // call the method in super 00124 [super onObjectCollision:_object]; 00125 00126 /* 00127 * only need to handle two types, 00128 * rest are dealt with by superclass 00129 */ 00130 switch([_object gameObjectType]) 00131 { 00132 case kObjectTerrainEnd: 00133 case kObjectTrapdoor: 00134 [self takePath:[self selectAction:[self getStateForGameObject:_object]]]; 00135 break; 00136 00137 case kObstacleWater: 00138 case kObstaclePit: 00139 case kObjectExit: 00140 [self selectAction:[self getStateForGameObject:_object]]; 00141 break; 00142 00143 case kObstacleStamper: 00144 if(self.state == kStateDead) [self selectAction:[self getStateForGameObject:_object]]; 00145 break; 00146 00147 case kObjectTerrain: 00148 if(fatalFall) [self selectAction:[self getStateForGameObject:_object]]; 00149 break; 00150 00151 default: 00152 break; 00153 } 00154 } 00155 00160 -(void)onEndConditionReached 00161 { 00162 // add the data to AgentStats 00163 int length = [[GameManager sharedGameManager] getGameTimeInSecs] - spawnTime; 00164 if(self.state != kStateDead) [[AgentStats sharedAgentStats] addEpisodeWithLength:length andActions:actionsTaken learningMode:learningMode]; 00165 else [[AgentStats sharedAgentStats] addEpisode]; 00166 00167 if(learningMode) 00168 { 00169 if(respawns > 1) [self changeState:kStateSpawning]; 00170 else 00171 { 00172 learningMode = NO; 00173 respawns = kLemmingRespawns; 00174 [self changeState:kStateSpawning]; 00175 } 00176 } 00177 else if(self.state == kStateDead && respawns > 0) [self changeState:kStateSpawning]; 00178 else [[LemmingManager sharedLemmingManager] removeLemming:self]; 00179 } 00180 00184 -(void)updateDebugLabel 00185 { 00186 [super updateDebugLabel]; 00187 [debugLabel setString:(learningMode || self.state == kStateDead || self.state == kStateWin) ? @"" : @"!"]; 00188 } 00189 00190 @end