From: Carl Worth Date: Fri, 18 Jan 2008 08:19:40 +0000 (-0800) Subject: Add support for claiming a set. X-Git-Url: https://git.cworth.org/git?p=loudgame;a=commitdiff_plain;h=fb2a60fc08919fabf78b9558b9aafef3246d33fa Add support for claiming a set. And tons of input validation. --- diff --git a/lg-set.c b/lg-set.c index af51bd8..c5ebbfb 100644 --- a/lg-set.c +++ b/lg-set.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -75,7 +76,6 @@ typedef struct slot { typedef struct board { int num_slots; slot_t slots[BOARD_MAX_SLOTS]; - int needs_deal; int sets_possible; } board_t; @@ -91,6 +91,9 @@ board_count_sets_possible (board_t *board); static int set_game_shuffle (set_game_t *game); +static void +set_game_new_game (set_game_t *game); + static int attribute_all_same (card_t *cards, int num_cards, int attr) { @@ -142,34 +145,6 @@ is_set (card_t *cards, int num_cards) return 1; } -static int -check_selected_for_set (board_t *board) -{ - int i, num_selected; - card_t cards[3]; - - num_selected = 0; - for (i=0; i < board->num_slots; i++) { - if (board->slots[i].selected) { - if (num_selected >= 3) - return 0; - cards[num_selected++] = board->slots[i].card; - } - } - - if (num_selected !=3) - return 0; - - if (! is_set (cards, num_selected)) - return 0; - - board_count_sets_possible (board); - - board->needs_deal = 1; - - return 1; -} - static void deck_shuffle (deck_t *deck) { @@ -250,7 +225,6 @@ board_init (board_t *board) board->slots[i].has_card = 0; board->slots[i].selected = 0; } - board->needs_deal = 0; board_count_sets_possible (board); } @@ -269,8 +243,6 @@ deal (deck_t *deck, board_t *board) } board_count_sets_possible (board); - - board->needs_deal = 0; } static void @@ -313,7 +285,90 @@ set_game_handle_shuffle (set_game_t *game, return; } - set_game_shuffle (game); + if (game->deck.num_cards == 0) { + loudgame_sendf (&game->lg, peer, + "Deck exhausted, starting a new game."); + set_game_new_game (game); + } else { + set_game_shuffle (game); + } +} + +static void +set_game_handle_set (set_game_t *game, + const char *peer, + const char *message) +{ + const char *s; + char *end = NULL; + int i; + int slots[3]; + card_t cards[3]; + + s = message; + i = 0; + while (*s && i < 3) { + slots[i++] = strtoul (s, &end, 10); + if (end == s) { + loudgame_sendf (&game->lg, peer, + "Error: Not an integer: %s", s); + return; + } + s = end; + } + + while (end && *end && isspace (*end)) + end++; + + if (i != 3 || *end != '\0') { + loudgame_sendf (&game->lg, peer, + "Error: The 'set' command requires exactly 3 integers"); + return; + } + + for (i = 0; i < 3; i++) { + if (slots[i] < 0 || slots[i] > BOARD_MAX_SLOTS) { + loudgame_sendf (&game->lg, peer, + "Error: Value %d is out of range (0-%d)", + slots[i], BOARD_MAX_SLOTS); + return; + } + } + + if (slots[0] == slots[1] || + slots[0] == slots[2] || + slots[1] == slots[2]) + { + loudgame_sendf (&game->lg, peer, + "Error: All 3 values must be unique"); + return; + } + + for (i=0; i < 3; i++) { + if (game->board.slots[slots[i]].has_card) { + cards[i] = game->board.slots[slots[i]].card; + } else { + loudgame_sendf (&game->lg, peer, + "Error: There's no card at position %d", i); + return; + } + } + + if (! is_set (cards, 3)) { + loudgame_sendf (&game->lg, peer, + "Sorry, that's not a set"); + return; + } + + loudgame_sendf (&game->lg, peer, + "Yes, that's a set!"); + + for (i = 0; i < 3; i++) + game->board.slots[slots[i]].has_card = 0; + + board_count_sets_possible (&game->board); + + deal (&game->deck, &game->board); } static void @@ -329,11 +384,21 @@ set_game_handle_message (loudgame_t *lg, set_game_handle_hint (game, peer); else if (strcmp (message, "shuffle") == 0) set_game_handle_shuffle (game, peer); + else if (strncmp (message, "set", 3) == 0) + set_game_handle_set (game, peer, message + 3); else loudgame_sendf (lg, peer, "Unknown command: '%s'", message); } /* Begin a new game */ +static void +set_game_new_game (set_game_t *game) +{ + deck_init (&game->deck); + board_init (&game->board); + deal (&game->deck, &game->board); +} + static int set_game_init (set_game_t *game, int argc, char *argv[]) { @@ -343,9 +408,7 @@ set_game_init (set_game_t *game, int argc, char *argv[]) if (err) return err; - deck_init (&game->deck); - board_init (&game->board); - deal (&game->deck, &game->board); + set_game_new_game (game); return 0; }