1

I have a struct for a tile (all properties are previously-defined enums)

typedef struct {
    ShapeType shape;
    ColorType color;
    PatternType pattern;
    IconType icon;
} TileDefinition;

And I want to create another struct that holds 16 tiles, for a "board". Something like this:

typedef struct {
    TileDefinition[16]

} BoardDefinition;

And then I want to be able to loop through that, like so:

for(int i=0;i<16;i++) {
    TileDefinition tileDef = boardDef[i];
    // Do something with tileDef
}

But obviously the setup for the BoardDefinition struct isn't working. How can I set that up? Where should I and shouldn't I use pointers?

Thanks

1
  • struct { TileDefinition[16] } looks really odd to me. What's wrong with struct { TileDefinition tiles[16]; } and then using boardDef.tiles[i]? Commented May 17, 2013 at 7:53

3 Answers 3

1

This is actually a C question.

This bit is fine:

typedef struct {
    ShapeType shape;
    ColorType color;
    PatternType pattern;
    IconType icon;
} TileDefinition;

Here, you need to declare BoardDefinition as:

enum { BoardDefinition_NTiles = 16 }; // << declare a constant for your ease of use
typedef struct {
    TileDefinition tile[BoardDefinition_NTiles];
} BoardDefinition;

Then to loop through them:

// Given:
BoardDefinition boardDef;

for (size_t i = 0; i < BoardDefinition_NTiles; i++) {
    TileDefinition* const tile = &boardDef.tile[i]; // << get a reference to a tile
    // member access of the referenced tile:
    tile->color.red = 1;
}

The version you wrote creates a copy of the tile:

for (size_t i = 0; i < BoardDefinition_NTiles; i++) {
    TileDefinition tile = boardDef.tile[i]; // << creates a copy of the tile, local to the loop body
    // member access of the copied tile:
    tile.color.red = 1;
}
Sign up to request clarification or add additional context in comments.

Comments

0

Option 1: Make BoardDefinition an Objective-C object where it can be set-up in the init method.

Option 2: Use (Objective-)C++ and provide a constructor for struct BoardDefinition.

Option 3: Keep with C and provide an initBoardDefinition(BoardDefinition *boardDef); function.

Comments

0

As trojanfoe suggest, these would be better as Objective-C objects, but if for some reason you don't wont to do that. You probable want to declare an instance variable of type BoardDefinition in some class for example

@interface MyClass : NSObject
{
    BoardDefinition    definition;
}

Also you BoardDefinition is wrong it should be something like

typedef struct {
    TileDefinition      boardDef[16];

} BoardDefinition;

Your loop would then be something like

for(int i=0;i<16;i++) {
    TileDefinition tileDef = definition.boardDef[i];
    // Do something with tileDef
}

You don't need to use pointers put you could for the TileDefinition in the parent struct something like

typedef struct {
    TileDefinition    * tileDefinition;
    NSUInteger        count;
} BoardDefinition;

This way you can have a variable number of TileDefinition. In this case you would have to malloc the tileDefinition soemthing like the following for the class init method.

- (id)init
{
    if( (self = [super init]) != nil )
    {
        definition.count = 16;
        definition.tileDefinition = malloc( definition.count * sizeof(*definition.tileDefinition);
    }
    return self;
}

3 Comments

"these would be better as Objective-C objects" -- Why?
Well, don't take that question seriously -- just my way of pointing out that there's no evident reason/benefit in converting the type to ObjC, given the information/problem in the OP.
I'm going to send these via Game Center to other players and want to keep them as lightweight as possible

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.