2010-04-14 17 views
28

Sto implementando un gioco di carte in C. Ci sono molti tipi di carte e ognuna ha un mucchio di informazioni, incluse alcune azioni che dovranno essere associate a script individuali.Inizializza matrice statica di strutture in C

dato una struct come questo (e io non sono certo ho il diritto sintassi per il puntatore a funzione)

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); 
}; 

vorrei inizializzare un array statico di questi, uno per ogni carta. Sto indovinando questo sarebbe simile a questa

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} 
}; 
  1. Sarà

    questo lavoro, e sto andare su questo nel modo giusto a tutti? Sto cercando di evitare un numero enorme di istruzioni switch.

  2. Devo definire le funzioni 'do_cardN' prima del tempo, o c'è un modo per definirle in linea nell'inizializzazione della struct (qualcosa come una funzione lambda in python)?

  3. Avrò bisogno di accesso in sola lettura a cardDefinitions da un file diverso - è "extern static" corretto per quello?

So che si tratta di un sacco di domande, ma sono davvero un po 'vago su come procedere.

Grazie.

Edit:

Per essere chiari, il mio obiettivo è quello di essere in grado di fare qualcosa di simile

int cost = cardDefinitions[cardNumber].cost; 

o

int result = cardDefinitions[cardNumber].do_action(state, choice1, choice2); 

Invece di utilizzare enormi istruzioni switch in tutto il luogo.

risposta

33

Il tuo approccio è giusto.

  1. Questo funzionerà, ed è un buon modo per evitare enormi dichiarazioni switch.
  2. Non è possibile definire funzioni in linea in C, ciascuna di esse deve avere un nome univoco.
  3. extern è ciò che si desidera, non static. Cambiare il vostro corpo ad essere questo:

    struct CARD cardDefinitions[] = { 
        {0, 1, do_card0}, 
        {1, 3, do_card1} 
    }; 
    

    poi in un apposito file di intestazione:

    extern struct CARD cardDefinitions[]; 
    
+3

Si può effettivamente avere funzioni "inline" in C. La parola che stai cercando è "funzioni anonime". Inoltre, aggiungerei {0, 0, NULL} come ultimo elemento dell'array, quindi non è necessario memorizzarne le dimensioni separatamente. – Philip

+0

@ Philip Bene, quelle "inline" sono del tutto estranee a ciò di cui sta parlando, ma sì, hai ragione. E io preferisco il "sizeof (cardDefinitions)/sizeof (cardDefinitions [0])" trucco per casi come questo –

+0

@ Michael: Questo trucco non funziona se si dichiara "Esterno cardDefinitions struct Scheda [];". – Philip

1
  1. Che dovrebbe funzionare bene. Sembra che tu abbia molte funzioni se ne stai facendo una per scheda, ma forse questo particolare gioco richiede quel livello di controllo

  2. Non puoi definirle in linea, ma puoi semplicemente fare un avanzamento dichiarazione.Hai bisogno di fare &func_name nell'inizializzazione struct se

  3. No; extern significa che una variabile è dichiarata in un altro file, quindi non ha senso avere una variabile esterna che stai dichiarando in quella posizione. Inoltre, static significa che la variabile è accessibile solo dal file corrente, che è l'opposto di quello che vuoi. Il che rende di sola lettura richiederebbe una funzione getter, ma se si desidera solo per renderlo accessibile da un altro file dichiararla normalmente qui (struct cardDefinitions[] = {...}) e l'altro file utilizzare un extern (extern struct cardDefinitions[];)

+3

Non è necessario eseguire '& func_name'. O 'func_name' o' & func_name' va bene (un nome di funzione nuda viene convertito in un puntatore alla funzione, analogo al modo in cui un nome di array nudo viene convertito in un puntatore al primo elemento dell'array). – caf

+2

1. Sì, il gioco ("Dominion") è abbastanza ridicolo come quello 2. Grazie per chiarire il bit extern, che rende molto più senso. Il mio approccio è stato buttare parole chiave fino a quando non ha funzionato ... –

+0

Oh wow, in realtà ho iniziato un'implementazione di quel gioco qualche tempo fa, ma ho deciso che probabilmente non sarebbe stato così divertente come IRL. Probabilmente non hai bisogno di funzioni separate per ogni carta, puoi semplicemente definire le proprietà per quanti soldi una carta ti dà, quante carte ti fanno pescare, quanti acquisti e azioni ottieni e quanti VP vale, e che coprirà la maggior parte dei casi –

2

Il tuo approccio è giusto e funzionerà. La sintassi puntatore a funzione è giusto, solo che non si utilizzano i nomi di parametro - solo tipo:

int (*do_actions)(struct GAME_STATE *, int, int); 
Problemi correlati