+ 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!");
+ loudgame_broadcastf (&game->lg,
+ "%s found the set: %d %d %d. Please send a new 'show' command.",
+ peer,
+ slots[0], slots[1], slots[2]);
+
+ 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
+set_game_handle_help (set_game_t *game,
+ const char *peer)
+{
+ loudgame_sendf (&game->lg, peer,
+ "I'm a bot that allows you to play the game of SET.\n"
+ "Here are some generic commands I understand:\n"
+ LOUDGAME_HELP
+ "\n"
+ "And some game-specific commands:\n"
+ "\tshow \tShow the current cards on the board\n"
+ "\thint \tIndicate how many sets are currently possible\n"
+ "\tshuffle \tReturn the cards to the deck, shuffle and deal\n"
+ "\t \t(this is only allowed if no sets are possible)\n"
+ "\tset X Y Z\tClaim three cards as a set. The cards are numbered\n"
+ "\t \tleft-to-right, and top-to-bottom from 0 to 11.\n"
+ "\n"
+ "For more information about SET, or to purchase your own deck, visit\n"
+ "http://setgame.com . Please note that this server is unaffiliated\n"
+ "with Set Enterprises, Inc., who publish the SET card game.");