私はCでカードゲームを実装しています。多くの種類のカードがあり、それぞれに関連する個別のスクリプトを作成する必要があるいくつかのアクションを含む多くの情報があります。
このような構造体が与えられた場合(および関数ポインターの構文が正しいかどうかはわかりません)
struct CARD {
int value;
int cost;
// This is a pointer to a function that carries out actions unique
// to this card
int (*do_actions) (struct GAME_STATE *state, int choice1, int choice2);
};
これらの静的配列を、各カードに1つずつ初期化したいと思います。これはこんな感じだと思う
int do_card0(struct GAME_STATE *state, int choice1, int choice2)
{
// Operate on state here
}
int do_card1(struct GAME_STATE *state, int choice1, int choice2)
{
// Operate on state here
}
extern static struct cardDefinitions[] = {
{0, 1, do_card0},
{1, 3, do_card1}
};
これは機能しますか、私はこれについて正しい方法で進んでいますか?膨大な数のswitchステートメントを避けようとしています。
「do_cardN」関数を事前に定義する必要がありますか、または構造体の初期化でそれらをインラインで定義する方法はありますか(Pythonのラムダ関数のようなもの)?
別のファイルからcardDefinitionsに読み取り専用でアクセスする必要があります-'extern static'は正しいですか?
これは多くの質問が1つにまとまっていることは知っていますが、これをどのように進めるかについては少しあいまいです。
ありがとう。
編集:
明確にするために、私の目標は次のようなことをできるようにすることです
int cost = cardDefinitions[cardNumber].cost;
または
int result = cardDefinitions[cardNumber].do_action(state, choice1, choice2);
あちこちで巨大なswitchステートメントを使用する代わりに。
あなたのアプローチは正確です。
switch
ステートメントを避ける良い方法です。extern
はstatic
ではなく、必要なものです。体をこれに変更します:
struct CARD cardDefinitions[] = {
{0, 1, do_card0},
{1, 3, do_card1}
};
次に、適切なヘッダーファイルで:
extern struct CARD cardDefinitions[];
あなたのアプローチは正しく、機能します。関数ポインタの構文は正しいですが、パラメータ名を使用せず、次のように入力するだけです。
int (*do_actions)(struct GAME_STATE *, int, int);
それはうまくいくはずです。あなたがカードごとに1つをやっているなら、あなたは多くの機能を持っているようですが、おそらくこの特定のゲームはそのレベルの制御を必要とします
それらをインラインで定義することはできませんが、前方宣言を行うことはできます。あなたがする必要があります&func_name
しかし、構造体の初期化
番号; extern
は、変数が別のファイルで宣言されていることを意味します。そのため、その場所で宣言している外部変数を持つことは意味がありません。また、static
は、変数が現在のファイルからのみアクセス可能であることを意味します。これは、あなたが望むものの反対です。読み取り専用にするにはゲッター関数が必要になりますが、別のファイルからアクセスできるようにするだけの場合は、ここで通常に宣言してください(struct cardDefinitions[] = {...}
)および他のファイルではextern(extern struct cardDefinitions[];
)