/* spite.h * * Type definitions and function prototypes. * * Copyright (C) 2002 Andy Goth * Matt Harang * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef SEEN_SPITE_H #define SEEN_SPITE_H #include /* --- TYPE DEFINITIONS ----------------------------------------------------- */ /* A hint for when things are supposed to be true/false. */ typedef unsigned bool; /* Possible suits for a card. Note that these values, the first four anyway, * are used for card_t.suit. */ typedef enum suit_t { S_HEART, S_DIAMOND, S_CLUB, S_SPADE, S_JOKER, /* Jokers have no suit */ S_NO_CARD, /* No hay tarjeta */ S_UNKNOWN /* Card is hidden */ } suit_t; /* Possible values for a card. Among other things, this is used for * card_t.real_value and card_t.eff_value. */ typedef enum value_t { V_NO_CARD, /* There is no spoon, err, card */ V_ACE, V_TWO, V_THREE, V_FOUR, V_FIVE, V_SIX, V_SEVEN, V_EIGHT, V_NINE, V_TEN, V_JACK, V_QUEEN, V_KING, V_JOKER, V_UNKNOWN /* Card is hidden */ } value_t; /* Identifier for a card. Note that there are multiple copies of a particular * card in a Spite & Malice deck, so this value is nonunique. Also note that * in different contexts and at different times, the same card will have * different identifiers as it goes from being hidden to being visible, changes * piles, changes effective values, is being looked at by different * players, and so on. */ typedef struct card_t { bool exists: 1; /* True if card is present */ bool visible: 1; /* True if card can be seen in this context */ value_t real_value: 4; /* 1 - 14, 1: A, 11: J, 12: Q, 13: K, 14: Jo */ suit_t suit: 3; /* 0: Heart, 1: Diamond, 2: Club, 3: Spade */ bool in_play: 1; /* True if card is in a shared discard pile */ value_t eff_value: 4; /* 1 - 14, 1: A, 11: J, 12: Q, 13: K, 14: Jo */ } card_t; /* Unique identifier for a player. A value of 0 means no player. */ typedef int player_id_t; /* Additional state information for a player; doubles as a secret unique * identifier for passing to system functions. */ typedef void player_state_t; /* Names of the various piles in play. These values, along with a player's * unique id, can be used to obtain access to pile data. */ typedef enum pile_name_t { P_NONE, /* Not applicable */ /* Shared piles */ P_SHARED_JUNK, /* Junk pile to be shuffled into draw pile */ P_SHARED_DRAW, /* Pile all players draw from */ P_SHARED_DISCARD_1, /* First shared discard pile */ P_SHARED_DISCARD_2, /* Second shared discard pile */ P_SHARED_DISCARD_3, /* Third shared discard pile */ P_SHARED_DISCARD_4, /* Fourth shared discard pile */ /* Personal piles */ P_PLAYER_DRAW, /* Player's personal draw pile */ P_PLAYER_HAND, /* Player's hand */ P_PLAYER_DISCARD_1, /* Player's first discard pile */ P_PLAYER_DISCARD_2, /* Player's second discard pile */ P_PLAYER_DISCARD_3, /* Player's third discard pile */ P_PLAYER_DISCARD_4 /* Player's fourth discard pile */ } pile_name_t; /* A stack or a hand of cards. */ typedef struct pile_t { card_t* cards; /* Actual card data */ int capacity; /* The maximum number of cards in the pile */ player_id_t owner; /* Owner (0: shared amongst players) */ pile_name_t name; /* Name of pile */ bool is_stack; /* True if this file is a stack */ int top; /* For a stack, index of top card (-1: empty) */ } pile_t; /* Types of game events. */ typedef enum event_type_t { E_INITIALIZE, /* Initialize state structures */ E_SHUTDOWN, /* Deallocate state structures */ E_GAME_BEGIN, /* Do last-minute preparations */ E_GAME_END, /* Notification of game ending */ E_TURN_BEGIN, /* Draw, play cards, and discard */ E_TURN_END, /* Notification of turn ending */ E_DRAW_REQUEST, /* Request for game to end in a draw */ E_CARD_MOVE, /* Card movement from one pile to another */ E_DISCARD_JUNK, /* Movement of discard piles into junk pile */ E_SHUFFLE, /* Junk pile shuffling into draw pile */ E_SPLIT, /* A player lost his link */ E_JOIN, /* A player regained his link */ E_CHAT /* Someone thinks he has something to say */ } event_type_t; /* Description of a single game event. */ typedef struct event_t { event_type_t type; /* Type of event */ player_id_t player; /* Player involved (can be 0) */ card_t card_pre; /* Card value before movement */ card_t card_post; /* Card value after movement */ pile_name_t source; /* Card's source pile */ pile_name_t dest; /* Card's destination pile */ char* text; /* Text relating to the event */ void* data; /* Extra event data */ } event_t; /* An event queue. */ typedef struct event_queue_t { event_t** events; /* Actual event slots */ int num_events; /* Current number of events */ int head; /* Index of next event to insert */ int tail; /* Index of next event to remove */ int capacity; /* Current maximum number of events */ } event_queue_t; /* Generic state information for a player. */ typedef struct player_t { player_id_t id; /* Unique id */ player_state_t* state; /* personal state information */ pile_t* hand; /* Hand */ pile_t* draw; /* Draw pile */ pile_t* discard[4]; /* Discard piles */ void (*event)(player_state_t*, event_t*); } player_t; /* Player type information needed for registration and initialization. */ typedef struct player_type_t { char* name; /* Name of player type */ char* description; /* Description */ char* options; /* Information about options */ int sizeof_state; /* Size, in bytes, of player's state */ void (*event)(player_state_t*, event_t*); /* Event handler */ } player_type_t; /* Game state. */ typedef struct game_state_t { /* List of all supported player types */ player_type_t* player_types; int num_player_types; /* List of all players in the game */ player_t* players; int num_players; /* Event queue */ event_queue_t* event_queue; /* The deck */ int num_cards; /* Shared piles */ pile_t* draw; /* Pile both players draw from */ pile_t* discard[4]; /* Piles both players play to */ pile_t* junk; /* Cards from queened discard piles */ } game_state_t; /* --- FUNCTION PROTOTYPES -------------------------------------------------- */ /* main.c */ extern int main(int argc, char** argv); /* util.c */ extern void* xmalloc(size_t size); extern void* xrealloc(void* p, size_t size); /* pile.c */ extern pile_t* pile_new(int capacity, player_id_t owner, pile_name_t name, bool is_stack); extern void pile_del(pile_t* p); extern bool pile_is_stack(const pile_t* p); extern bool pile_is_empty(const pile_t* p); extern bool pile_is_full(const pile_t* p); extern int pile_num_cards(const pile_t* p); extern void pile_push(pile_t* p, card_t c); extern card_t pile_pop(pile_t* p); extern card_t pile_peek(const pile_t* p); extern card_t pile_peek_i(const pile_t* p, int i); extern void pile_move_card(pile_t* src, pile_t* dst, int i); /* card.c */ extern const card_t card_empty; extern suit_t card_suit(card_t c); extern value_t card_real_value(card_t c); extern value_t card_eff_value(card_t c); extern bool card_is_wild(card_t c); extern bool card_in_play(card_t c); extern bool card_is_playable(card_t top, card_t bottom); /* event.c */ extern event_t* event_new(event_type_t type, player_id_t player, card_t card_pre, card_t card_post, pile_name_t source, pile_name_t dest, char* text, void* data); extern void event_del(event_t* e); extern void event_queue_push(event_queue_t* q, event_t* e); extern event_t* event_queue_pop(event_queue_t* q); extern int event_queue_num_events(const event_queue_t* q); extern event_queue_t* event_queue_new(void); extern void event_queue_del(event_queue_t* q); /* player.c */ /* game.c */ #endif /* EOF */