I read with interest this post to StackOverflow: How to Make a Basic Finite State Machine in Objective-C
I used this as a basis to build my state-machine for a simple football game. I have states Defend, Attack, Stoppage, Neutral. I have created the state Machine and it will print out with NSLog "Now Entering State Defend" etc.
Now I would like to pass in a reference to my Football Team to the state Machine, such that I can make my team do something based on the state. Ie if its Defend, I can send my players to stand next to an opponent.
Ive tried many different ways but all end in syntax errors. Id appreciate a push in the right direction
TeamState.h Note the Errors Im getting in the comments
@class TeamState;
#import <Foundation/Foundation.h>
#import "FootballTeam.h"
@protocol TeamStateProt
-(void) enterTeamState:(TeamState*)team;
-(void) executeTeamState:(TeamState*)team;
-(void) exitTeamState:(TeamState*)team;
@end
@interface TeamState : NSObject{
id<TeamStateProt> currentTeamState;
id<TeamStateProt> Stoppage;
id<TeamStateProt> Neutral;
id<TeamStateProt> Defend;
id<TeamStateProt> Attack;
FootballTeam *footballTeam; //ERROR Unknown Type name FootballTeam
}
@property (nonatomic, retain) id<TeamStateProt> currentTeamState;
@property (nonatomic, retain) id<TeamStateProt> Stoppage;
@property (nonatomic, retain) id<TeamStateProt> Neutral;
@property (nonatomic, retain) id<TeamStateProt> Defend;
@property (nonatomic, retain) id<TeamStateProt> Attack;
- (id)initWithFootBallTeam:(FootballTeam*) team; //Error Expected a Type
-(void)update;
-(void)changeState:(id<TeamStateProt>) newState;
-(void)executeState:(id<TeamStateProt>) State;
@end
TeamState.m
#import "TeamState.h"
#import "FootballTeam.h"
#import "Stoppage_TS.h"
#import "Neutral_TS.h"
#import "Defend_TS.h"
#import "Attack_TS.h"
@implementation TeamState
@synthesize currentTeamState;
@synthesize Stoppage, Neutral, Defend, Attack;
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
id<TeamStateProt> s = [[Stoppage_TS alloc] init];
self.Stoppage = s;
id<TeamStateProt> n = [[Neutral_TS alloc] init];
self.Neutral = n;
id<TeamStateProt> d = [[Defend_TS alloc] init];
self.Defend = d;
id<TeamStateProt> a = [[Attack_TS alloc] init];
self.Attack = a;
self.currentTeamState = n;
[self.currentTeamState enterTeamState:self];
[self executeState:self.currentTeamState];
}
return self;
}
- (id)initWithFootBallTeam:(FootballTeam*) team
{
self = [super init];
if (self) {
// Initialization code here.
id<TeamStateProt> s = [[Stoppage_TS alloc] init];
self.Stoppage = s;
id<TeamStateProt> n = [[Neutral_TS alloc] init];
self.Neutral = n;
id<TeamStateProt> d = [[Defend_TS alloc] init];
self.Defend = d;
id<TeamStateProt> a = [[Attack_TS alloc] init];
self.Attack = a;
self.currentTeamState = n;
[self.currentTeamState enterTeamState:self];
[self executeState:self.currentTeamState];
footballTeam = team;
}
return self;
}
-(void)changeState:(id<TeamStateProt>) newState{
NSLog(@"Changing State");
if (newState != nil) {
NSLog(@"Changing a state which isn't nil");
[self.currentTeamState exitTeamState:self];
self.currentTeamState = newState;
[self.currentTeamState enterTeamState:self];
[self executeState:self.currentTeamState];
}
}
-(void)executeState:(id<TeamStateProt>) State{
[self.currentTeamState executeTeamState:self];
}
// Each update, execute the execute state on the current team state
-(void)update{
[self executeState:self.currentTeamState];
}
@end
FootballTeam.h
#import <Foundation/Foundation.h>
#import "Player.h"
#import "TeamState.h"
#import "Football.h"
typedef enum {
Home,
Away
} TeamType;
@interface FootballTeam : NSObject{
Player *ReceivingPlayer; //Player to receive the ball
Player *ClosestToBall; //Player closest to the ball
Player *ControllingPlayer; //Player who has the ball can be NULL
Player *SupportingPlayer; //Player in a position to receive the ball
NSMutableArray *players; //Array of all the Players on this team
TeamState *state; //Current state of the teams state machine
TeamType type; //Defines if Home team or Away team
}
@property (nonatomic) TeamType type;
@property(nonatomic, retain) TeamState *state;
-(void) sendPlayersToHome;
-(Player*) playerClosestToBall:(Football*) ball;
-(BOOL) areAllPlayersAtHome;
@end