You need only read this if you plan to do hacking on TVP -- it is not meant to be read by the general user. You will use the library to manage instances of the cardgame President. It is designed to contain all of its internal state within a single game_s structure. You should never need to access this (or any other) such structures directly; rather, you should use the provided functions to access the gamestate. You will maintain a single game_t variable which you should pass to the ass_*() functions. Before you are able to use the library, you will have to call ass_init() to initialize a game_t. After this you will most likely call ass_deal() followed by calls to ass_turn() until all turns have been taken. You can use any of numerous functions to return game state (such as whose turn it is, who has what cards, etc.) at any time after the original call to ass_init(). Follows an example of how to use the library, as well as loose documentation for every function and type. For detailed documentation, you should examine the source for comments preceding each function. Variable Types Used ------------------- game_t You will use this type to keep track of the game. You can have multiple games running, concurrently; just pass different game_t's to each. It is a pointer to a struct. game_t g; sizeof (*g); The above sizeof() is guaranteed to return the number of bytes necessary to save an instance of a game. To save the game to a file, for example, just copy sizeof(*g) bytes from the the address pointed to by g and save them. The resulting saved-game, of course, cannot be expected to be loadable by understood by versions of libass on different operating- systems or architectures, but can be used to temporarily save a game when you will be reading it again later. player_t This type refers to an individual player. You can use the same sizeof() trick with player_t as with game_t. If you wish to change the players in a game, simply copy sizeof(*player_t) bytes from the saved player_t. But, be careful!! There must ALWAYS be at least one player who is ASS. to the one returned by ass_GamePlayer(). But, be careful!! There must hand_t This type stores a player's hand, up to 54 cards. card_t This is an enum type, which contains the following possible cards: NAC -- Not a Card THREE ... TWO JOKER They are guaranteed to be in ascending order, starting from 0. set_t This stores one set of cards that can be laid down. Ie. A type of card, and a number of cards. A set of NAC cards can be laid on anything. You will usually need to initialize at least one set_t for your own purposes to pass to ass_move(). This is, of course, done with myset_t = malloc (sizeof (*myset_t)). position_t This is an enum type which stores the following possible positions: ASS VICEASS VICE PREZ Once again, they are guaranteed to be in ascending order, starting from 0. FUNCTIONS --------- void ass_init (game_t); Call this before you do anything else. The game_t must point to previously allocated memory, eg. game_t g = malloc (sizeof (*g)); void ass_deal (game_t); This will deal out the cards. If you call it with a game-in-progress, it will deal, anyways. hand_t ass_switch (game_t); This will take the President's two lowest cards and the Ass's two highest cards, as well as the Vice-Ass's highest card and the Vice-President's lowest card, and switch them. The hand_t it returns is statically allocated and can be used to see exacly which cards were traded. The first two cards in the hand_t are from the Ass, the third and fourth are from the President, the fifth is from the Vice-Ass, and the sixth is from the Vice-President. Don't call this anytime except immediately after ass_deal(), please. int ass_move (game_t, set_t) You must call this function for every player in the current round. You should use ass_turn() to determine who you are currently calling ass_move() for. You will have to allocate your set_t (eg. set_t myset = malloc (sizeof (*myset));) to pass to ass_move(). This function returns true if it was unable to lay the set you tried to lay. int ass_set (hand_t, set_t) This will return true if set_t exists within hand_t. It's not a bad idea to validate your sets before passing them to ass_move() with the function. int ass_setlt (set_t, set_t) This will return true iff the first set is lower than the second set. The set you are laying on top of should always be lower than the set you are laying on top of it. You can use this function to check for sets that don't follow this rule. int ass_all (game_t) This function will return true if all players have had their turn for this round (recall that a round refers only to a single process of laying down one set and then giving everyone one single chance to lay on top of it). It will return false if you just dealt, and you are not allowed to call it before dealing. void ass_sort (hand_t) This will sort the hand_t. Low cards are placed at the beginning, NAC's at the end, and high cards just before the NAC's. It is called automatically by ass_deal() and ass_shuffle(). int ass_a_clear (game_t) This function is called automatically by ass_move(), but sometimes you will want to call it before ass_move() does. It will clear the currently-laid set (thus starting a new round) iff everyone has had their turn in the present round. If you are using the AI library, it is important to call this before telling ai_move() what set it is trying to lay ontop of! void ass_a_shuffle (game_t) This will switch player's seats (or positions) based on how well they have done. You may call it just before every call to ass_deal(). If you do not, ass_deal() will call ass_a_shuffle() itself.