All Data Structures Files Functions Variables Enumerations Enumerator Properties Defines
/Projects/Cogito/src/GameObjects/CogitoAgents/ShortestRouteAgent.m
Go to the documentation of this file.
00001 //
00002 //  ShortestRouteAgent.m
00003 //  Author: Thomas Taylor
00004 //
00005 //  Handles the machine learning using a shortest 
00006 //  route policy
00007 //
00008 //  18/02/2012: Created class
00009 //
00010 
00011 #import "ShortestRouteAgent.h"
00012 
00013 @interface ShortestRouteAgent()
00014 
00015 -(void)setOptimumRoute;
00016 -(Action)getOptimumAction;
00017 
00018 @end
00019 
00020 @implementation ShortestRouteAgent
00021 
00022 #pragma mark -
00023 #pragma mark Memory Allocation
00024 
00028 -(void)dealloc
00029 {
00030     [routes release]; 
00031     [currentRoute release];
00032     
00033     [super dealloc];
00034 }
00035 
00036 #pragma mark -
00037 #pragma mark Initialisation
00038 
00043 -(id)init
00044 {
00045     self = [super init];
00046     
00047     if (self != nil) 
00048     {
00049         routes = [[CCArray alloc] init];
00050         currentRoute = [[Route alloc] init];
00051         optimumRouteIndex = 0;
00052     }
00053     return self;
00054 }
00055 
00056 #pragma mark -
00057 
00063 -(Action)selectAction:(State*)_state
00064 {
00065     Action action = -1;
00066 
00067     // get  list of the available action
00068     CCArray* options = [self calculateAvailableActions:_state];
00069    
00070     // if the Agent's died/won
00071     BOOL endConditionReached = (self.state == kStateDead || [_state getGameObject].gameObjectType == kObjectExit);
00072     
00073     // choose action
00074     if(!endConditionReached)
00075     {
00076         // uses the Constant to randomise actions  
00077         int randomNumber = [Utils generateRandomNumberFrom:0 to:(int)(1/kLearningRandomProbability)];
00078         BOOL chooseRandom = (randomNumber == 0) ? chooseRandom = YES : NO;
00079         if(kLearningRandomProbability == 0.0f) chooseRandom = NO;
00080                 
00081         // if still learning, randomly choose action
00082         if(learningMode || chooseRandom) action = [self chooseRandomAction:options];  
00083         // not learning, choose the optimum action
00084         else
00085         {
00086             action = [self getOptimumAction];
00087             // no optimum has been found. Choose random action
00088             if(action == -1) action = [self chooseRandomAction:options];  
00089         }
00090     }
00091     
00092     // Update the current route
00093     if(learningMode) 
00094     {
00095         [currentRoute addState:_state withAction:action];
00096         
00097         if(endConditionReached) 
00098         {
00099             // set the end condition
00100             if([_state getGameObject].gameObjectType == kObjectExit) [currentRoute setSurvived:YES];
00101             else if(self.state != kStateDead) [currentRoute setSurvived:NO];
00102             
00103             // add the route to routes
00104             [routes addObject:currentRoute];
00105                         
00106             // starting new route
00107             currentRoute = [[Route alloc] init];
00108         }
00109     }
00110         
00111     return action;
00112 }
00113 
00118 -(void)setOptimumRoute
00119 {
00120     for (int i = 0; i < [routes count]; i++) 
00121     {
00122         Route* route = [routes objectAtIndex:i];
00123                 
00124         // if route's shorter (and we survived), set the shortest route
00125         if([route survived] && (optimumRoute == nil || [[route getNodes] count] < [[optimumRoute getNodes] count])) 
00126             optimumRoute = route;
00127     }
00128 }
00129 
00133 -(Action)getOptimumAction
00134 {
00135     Action action = -1;
00136     
00137     if(optimumRoute != nil)
00138     {
00139         action = [[[[optimumRoute getNodes] objectAtIndex:optimumRouteIndex] objectAtIndex:1] intValue];
00140         optimumRouteIndex++;
00141     }
00142     return action;
00143 }
00144 
00145 #pragma mark -
00146 #pragma mark Overrides
00147 
00152 -(void)onEndConditionReached
00153 {            
00154     if(learningMode && respawns < 2) [self setOptimumRoute];
00155     [super onEndConditionReached];
00156 }
00157 
00161 -(void)updateDebugLabel
00162 {    
00163     [super updateDebugLabel];
00164     
00165     if(!(learningMode || self.state == kStateDead || self.state == kStateWin))
00166     {
00167         [debugLabel setString:([[optimumRoute getNodes] count] > 0) ? @"!" : @"?"];
00168     }
00169 }
00170 
00171 @end