All Data Structures Files Functions Variables Enumerations Enumerator Properties Defines
/Projects/Cogito/src/Singletons/KnowledgeBase.m
Go to the documentation of this file.
00001 //
00002 //  KnowledgeBase.m
00003 //  Author: Thomas Taylor
00004 //
00005 //  A shared knowledge base used by the lemmings
00006 //
00007 //  18/02/2011: Created class
00008 //
00009 
00010 #import "KnowledgeBase.h"
00011 
00012 @implementation KnowledgeBase
00013 
00014 static KnowledgeBase* _instance = nil;
00015 
00016 #pragma mark -
00017 #pragma mark Memory Allocation
00018 
00019 -(void)dealloc
00020 {
00021     [gameStates release];
00022     [routes release];
00023     
00024     [super dealloc];
00025 }
00026 
00031 +(id)alloc
00032 {    
00033     @synchronized([KnowledgeBase class])
00034     {
00035         // if the _instance already exists, stop
00036         NSAssert(_instance == nil, @"There should only ever be one instance of KnowledgeBase");
00037         _instance = [super alloc];
00038         return _instance;
00039     }
00040     
00041     return nil;
00042 }
00043 
00044 #pragma mark -
00045 #pragma mark Initialisation
00046 
00051 -(id)init 
00052 {        
00053     self = [super init];
00054     
00055     if (self != nil) 
00056     {
00057         [self clearKnowledgeBase];
00058     }
00059     
00060     return self;
00061 }
00062 
00063 #pragma mark -
00064 
00069 +(KnowledgeBase*)sharedKnowledgeBase
00070 {
00071     @synchronized([KnowledgeBase class])
00072     {
00073         if(!_instance) [[self alloc] init];
00074         return _instance;
00075     }
00076     
00077     return nil;
00078 }
00079 
00085 -(QState*)getStateForGameObject:(GameObject*)_object
00086 { 
00087     for (int i = 0; i < [gameStates count]; i++) 
00088     {
00089         QState* tempState = [gameStates objectAtIndex:i];
00090         if([tempState getGameObject] == _object) return tempState;
00091     }
00092     
00093     // state not found, make a new one    
00094     float reward = kQDefaultReward;
00095     
00096     // set the reward
00097     switch(_object.gameObjectType)
00098     {
00099         case kObjectExit:
00100             reward = kQWinReward;
00101             break;
00102             
00103         case kObstaclePit:
00104         case kObstacleWater:
00105         case kObstacleStamper:
00106             reward = kQDeathReward;
00107             break;            
00108             
00109         default:
00110             break;
00111     }
00112     
00113     QState* returnState = [[QState alloc] initStateForObject:_object withReward:reward];
00114     [gameStates addObject:returnState];
00115 
00116     return returnState;
00117 }
00118 
00122 -(void)exportKnowledgeBase
00123 {    
00124     // get the documents path
00125     NSString* documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
00126     NSString* filePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"KnowledgeBase_%@_%@.plist", [[GameManager sharedGameManager] currentLevel].name, [Utils getTimeStampWithFormat:@"yyyy_MM_dd-HHmm"]]];
00127     
00128     // the dictionary to export
00129     NSMutableDictionary* exportData = [[NSMutableDictionary alloc] init];
00130     
00131     // create a dictionary ontaining the states
00132     for (int i = 0; i < [gameStates count]; i++) 
00133     {
00134         NSMutableDictionary* stateData = [[NSMutableDictionary alloc] init];
00135         QState* tempState = [gameStates objectAtIndex:i];
00136         NSString* stateId = [NSString stringWithFormat:@"%@ (%i,%i)", [Utils getObjectAsString:[[tempState getGameObject] gameObjectType]], ((int)[tempState getGameObject].position.x), ((int)[tempState getGameObject].position.y)];
00137         
00138         // no need adding states with no Q-values
00139         if([[tempState getGameObject] gameObjectType] == kObjectExit) continue;
00140         if([[tempState getGameObject] class] == [Obstacle class]) continue;
00141        
00142         // for each state, create a sub dictionary of actions/Q-values
00143         for (int j = 0; j < [[tempState getActions] count]; j++) 
00144         {
00145             Action action = [[[tempState getActions] objectAtIndex:j] intValue];
00146             NSNumber* qValue = [NSNumber numberWithFloat:[tempState getQValueForAction:action]];
00147             
00148             // store the pair
00149             [stateData setObject:qValue  forKey:[Utils getActionAsString:action]];
00150         }
00151         // store the state
00152         [exportData setObject:stateData forKey:stateId];
00153     }
00154     
00155     // finally write the file
00156     [exportData writeToFile:filePath atomically:YES];
00157 }   
00158 
00162 -(void)clearKnowledgeBase
00163 {
00164     [gameStates release];
00165     gameStates = [[CCArray alloc] init]; 
00166 }
00167 
00168 @end