Objective-C 状态机传入参数

发布于 2024-12-11 16:02:33 字数 4642 浏览 4 评论 0原文

我饶有兴趣地阅读了 StackOverflow 上的这篇文章: 如何在 Objective 中制作基本的有限状态机-C

我以此为基础来构建简单足球游戏的状态机。我有状态防御、攻击、停止、中立。我已经创建了状态机,它将打印出 NSLog“现在进入状态防守”等。

现在我想将对我的足球队的引用传递给状态机,这样我就可以让我的球队根据国家。也就是说,如果是防守,我可以派我的球员站在对手旁边。

我尝试了很多不同的方法,但都以语法错误告终。我很感激朝着正确的方向推动

TeamState.h 请注意我在评论中遇到的错误

@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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

擦肩而过的背影 2024-12-18 16:02:34

你有循环引用。您将在 FootballTeam.h 中导入 TeamState.h,反之亦然。

为了避免这种情况,请仅在 .m 文件中导入 .h 文件,并在 .h 文件中添加前向声明。

因此,在 TeamState.h 中:

@class FootballTeam;

并将导入移至 TeamState.m

在 FootballTeam 中相同。

You've got circular references. You're importing TeamState.h in FootballTeam.h and vice versa.

To avoid this, import the .h files in the .m files only, and add forward declarations in the .h files.

So, in TeamState.h:

@class FootballTeam;

And move the import to TeamState.m

The same in FootballTeam.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文