/* MaitreTarot. * (C) 2002 Guillaume Weexsteen * Modified by Yves Mettier * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include "defs.h" #include "game.h" #include "playerthread.h" #include "utils.h" #include "rules.h" #define I(i) game->players_order[i] static gchar card_str[FOOL + 1][4]; static void deck_shuffle (gint deck[78]); static game_t *sa_game; static gint sa_indent; void close_all_clients (game_t * game) { int i; for (i = 0; i < 4; i++) { close (game->players[i]->net_data->sock); } } gboolean wait_for_stable_state (game_t * game, gint player_index) { int i; while ((game->players[player_index]->ready != MT_PLAYER_READY_NO) && (game->players[player_index]->ready != MT_PLAYER_READY_CLOSED)) { my_wait (WAIT_TIME); } if (game->players[player_index]->ready == MT_PLAYER_READY_CLOSED) { close_all_clients (game); return (FALSE); } for (i = 0; i < 4; i++) { if (libmt_channels_set_channel_has_error (game->players[i]->net_data->channels_set, 0)) { close_all_clients (game); return (FALSE); } } return (TRUE); } player_t * player_new (gint place, gint sock) { libmt_net_t *net = g_malloc (sizeof (libmt_net_t)); player_t *player = g_malloc (sizeof (player_t)); player->net_data = net; player->place = place; net->sock = sock; player->score = 0; player->score_total = 0; player->ready = MT_PLAYER_READY_NO; return (player); } game_t * game_new (gint port) { #ifdef MT_DEBUG_SIGNAL_ENABLED struct sigaction sa; #endif struct sockaddr_in sockaddr; socklen_t lg; gint p = 0; gint sock; int i, j; game_t *game = g_malloc (sizeof (game_t)); game->sock = libmt_make_server (port); game->server_id[0] = 1; game->server_id[1] = 1; game->protocol_version = 1; for (i = 0; i < 78; i++) { game->card_value[i] = 1; game->nicks[i] = g_strdup_printf("Player %d",i); } for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) game->card_value[14 * i + 10 + j] += j + 1; } game->card_value[TRUMP] = 5; game->card_value[TRUMP + 20] = 5; game->card_value[FOOL] = 5; /* waiting for 4 players */ while (p < 4) { int i; lg = sizeof (struct sockaddr_in); if ((sock = accept (game->sock, (struct sockaddr *) &sockaddr, &lg)) >= 0) { game->players[p] = player_new (p, sock); game->players[p]->ready = MT_PLAYER_READY_NO; game->players[p]->net_data->channels_set = libmt_channels_set_new (sock); game->players[p]->th_id = g_thread_create (player_thread, game->players[p], FALSE, NULL); g_assert (game->players[p]->th_id); g_message ("connexion"); game->players[p]->net_data->server_id[0] = game->server_id[0]; game->players[p]->net_data->server_id[1] = game->server_id[1]; game->players[p]->net_data->protocol_version = game->protocol_version; for (i = 0; i < MAX_PLAYER; i++) game->players[p]->nicks[i] = game->nicks[i]; game->players[p]->nicks_len[i] = game->nicks_len[i]; p++; } } for (p = 0; p < 4; p++) game->players[p]->ready = MT_PLAYER_READY_GET_ID; for (p = 0; p < 4; p++) { if (!wait_for_stable_state (game, p)) g_error (_("A client disconnected")); } for (p = 0; p < 4; p++) game->players[p]->ready = MT_PLAYER_READY_SEND_ID; for (p = 0; p < 4; p++) { if (!wait_for_stable_state (game, p)) g_error (_("A client disconnected")); } for (p = 0; p < 4; p++) game->players[p]->ready = MT_PLAYER_READY_SEND_PROTOCOL; for (p = 0; p < 4; p++) { if (!wait_for_stable_state (game, p)) g_error (_("A client disconnected")); } for (p = 0; p < 4; p++) game->players[p]->ready = MT_PLAYER_READY_SEND_PLACE; for (p = 0; p < 4; p++) { if (!wait_for_stable_state (game, p)) g_error (_("A client disconnected")); } /* For nicknames */ for (p = 0; p < 4; p++) game->players[p]->ready = MT_PLAYER_READY_GET_NICK; for (p = 0; p < 4; p++) { { if (!wait_for_stable_state (game, p)) g_error (_("A client disconnected")); } game->nicks[p] = game->players[p]->nicks[p]; game->nicks_len[p] = game->players[p]->nicks_len[p]; } for (p = 0; p < 4; p++) { for (j = 0; j < 4; j++) { game->players[p]->nicks[j] = game->nicks[j]; game->players[p]->nicks_len[j] = game->nicks_len[j]; } game->players[p]->ready = MT_PLAYER_READY_SEND_NICKS; } for (p = 0; p < 4; p++) { if (!wait_for_stable_state (game, p)) g_error (_("A client disconnected")); } game->turn = -1; deck_shuffle (game->deck); #ifdef MT_DEBUG_SIGNAL_ENABLED sigaction (SIGUSR1, (struct sigaction *) 0, &sa); #ifdef SA_RESTART sa.sa_flags |= SA_RESTART; #endif #ifdef SA_INTERRUPT sa.sa_flags &= ~SA_INTERRUPT; #endif sa_game = game, sa_indent = 0; sa.sa_sigaction = &dump_game; sigaction (SIGUSR1, &sa, (struct sigaction *) 0); g_message ("For a game_t dump, execute 'kill -s SIGUSR1 %d'", getpid ()); #endif return game; } void init_hand (game_t * game) { gint i; gint trick; gint player; gboolean for_chien[24]; /* FIXME : this name is very strange :) */ gint rest_chien = 5; gint chien_i = 0; gint deck_i = 0; for (i = 0; i < 78; i++) game->card_status[i] = -1; game->turn++; if (game->turn >= 4) game->turn = 0; for (i = 0; i < 4; i++) { I (i) = i + game->turn; if (I (i) >= 4) I (i) -= 4; } for (i = 0; i < 24; i++) for_chien[i] = FALSE; while (rest_chien >= 0) { i = (gint) (23.0 * rand () / (RAND_MAX + 1.0) + 1.0); if (for_chien[i] == FALSE) { for_chien[i] = TRUE; rest_chien--; } } for (trick = 0; trick < 6; trick++) for (player = 0; player < 4; player++) { if (for_chien[player + trick * 4]) { game->chien[chien_i] = game->deck[deck_i]; game->card_status[game->deck[deck_i]] = 5; deck_i++; chien_i++; } for (i = 0; i < 3; i++) { game->players[I (player)]->card[trick * 3 + i] = game->deck[deck_i]; game->card_status[game->deck[deck_i]] = I (player); deck_i++; } } for (i = 0; i < 4; i++) { int j; for (j = 0; j < 6; j++) game->players[i]->chien[j] = game->chien[j]; } game->bid = 0; game->taker_score = 0; } gint dill_cards (game_t * game) { gint i; for (i = 0; i < 4; i++) game->players[i]->ready = MT_PLAYER_READY_DILL_CARDS; for (i = 0; i < 4; i++) { if (!wait_for_stable_state (game, i)) return (-1); } return (0); } static void deck_shuffle (gint * deck) { gint shuffle; gint card1, card2, card; gint i; srand (time (NULL)); shuffle = 10 + (gint) (100.0 * rand () / (RAND_MAX + 1.0)); for (i = 0; i < 78; i++) deck[i] = i; for (i = 0; i < shuffle; i++) { card1 = (gint) (78.0 * rand () / (RAND_MAX + 1.0)); while ((card2 = (gint) (78.0 * rand () / (RAND_MAX + 1.0))) == card1); card = deck[card1]; deck[card1] = deck[card2]; deck[card2] = card; } } gint bills (game_t * game) { gint i, j; for (i = 0; i < 4; i++) game->bids[i] = -1; for (i = 0; i < 4; i++) { game->bid = LIBMT_BID_PASSE; for (j = 0; j < 4; j++) { if ((game->bids[I (j)] != -1) && (LIBMT_BID_CMP (game->bid, game->bids[I (j)]) >= 0)) { game->bids[I (j)] = LIBMT_BID_PASSE; } else { game->bid = game->bids[I (j)]; } } for (j = 0; j < 4; j++) { int k; for (k = 0; k < 4; k++) game->players[j]->bid[k] = game->bids[k]; } /* Send everybody but one the state of the bids. */ for (j = 0; j < 4; j++) { if (j != i) { game->players[I (j)]->ready = MT_PLAYER_READY_SEND_BIDS_ONLY; } } /* Send the missing one the bids and an order to get his bid */ game->players[I (i)]->ready = MT_PLAYER_READY_SEND_BIDS_AND_ASK_FOR_BID; { if (!wait_for_stable_state (game, I (i))) return (-1); } game->players[I (i)]->ready = MT_PLAYER_READY_GET_BID; for (j = 0; j < 4; j++) { { if (!wait_for_stable_state (game, j)) return (-1); } } /* warning: is it bid[i] or bid[I(i)] ? */ game->bids[I (i)] = game->players[I (i)]->bid[I (i)]; } g_message ("Les enchères finales sont : \n"); for (i = 0; i < 4; i++) g_message ("%s : %d", game->nicks[i], game->bids[i]); game->bid = game->bids[0]; game->preneur = 0; for (i = 1; i < 4; i++) { if (LIBMT_BID_CMP (game->bid, game->bids[i]) < 0) { game->preneur = i; game->bid = game->bids[i]; } else { game->bids[i] = LIBMT_BID_PASSE; } } for (j = 0; j < 4; j++) { int k; for (k = 0; k < 4; k++) game->players[j]->bid[k] = game->bids[k]; } for (i = 0; i < 4; i++) game->players[i]->ready = MT_PLAYER_READY_SEND_FINAL_BIDS; for (i = 0; i < 4; i++) { if (!wait_for_stable_state (game, i)) return (-1); } if (LIBMT_BID_CMP (game->bid, LIBMT_BID_PASSE) <= 0) return 0; else return 1; } gint send_chien (game_t * game, gboolean after_bills) { int i; /* Send the chien */ for (i = 0; i < 4; i++) { game->players[i]->ready = after_bills ? MT_PLAYER_READY_SHOW_CHIEN : MT_PLAYER_READY_SHOW_CHIEN_AT_END; } for (i = 0; i < 4; i++) { if (!wait_for_stable_state (game, i)) return (-1); } return (0); } gint manage_chien (game_t * game) { gint i; gboolean chien_nok = TRUE; if (LIBMT_BID_CMP (game->bid, LIBMT_BID_SANS) < 0) { for (i = 0; i < 78; i++) { if (game->card_status[i] == 5) game->card_status[i] = game->preneur; } } else if (LIBMT_BID_CMP (game->bid, LIBMT_BID_SANS) == 0) { for (i = 0; i < 78; i++) { if (game->card_status[i] == 5) game->card_status[i] = 10 + game->preneur; } } else { gint p = (game->preneur + 1) % 4; for (i = 0; i < 78; i++) { if (game->card_status[i] == 5) game->card_status[i] = 10 + p; } } if (LIBMT_BID_CMP (game->bid, LIBMT_BID_GARDE) <= 0) { /* Send the chien */ send_chien (game, TRUE); /* send 1 for the one who got the chien, 0 for the others */ /* Get the new chien */ while (chien_nok) { game->players[game->preneur]->ready = MT_PLAYER_READY_GET_CHIEN; { if (!wait_for_stable_state (game, game->preneur)) return (-1); } chien_nok = FALSE; /* Update the local structure with the new chien */ for (i = 0; i < 6; i++) { printf ("i=%d card_status=%d preneur=%d chien=%d\n", i, game-> card_status[game->players[game->preneur]-> chien[i]], game->preneur, game->players[game->preneur]->chien[i]); if (game->card_status[game->players[game->preneur]->chien[i]] != game->preneur) { chien_nok = TRUE; break; } /* No Club King inside the chien */ if (game->players[game->preneur]->chien[i] == CLUB + 13) { chien_nok = TRUE; break; } /* No spade King inside the chien */ if (game->players[game->preneur]->chien[i] == SPADE + 13) { chien_nok = TRUE; break; } /* No heart King inside the chien */ if (game->players[game->preneur]->chien[i] == HEART + 13) { chien_nok = TRUE; break; } /* No diamond King inside the chien */ if (game->players[game->preneur]->chien[i] == DIAMOND + 13) { chien_nok = TRUE; break; } /* No Trump */ if ((game->players[game->preneur]->chien[i] >= TRUMP) && (game->players[game->preneur]->chien[i] <= TRUMP + 20)) { chien_nok = TRUE; break; } /* No Fool */ if (game->players[game->preneur]->chien[i] == FOOL) { chien_nok = TRUE; break; } } if (chien_nok) { g_message ("tricherie"); game->players[game->preneur]->ready = MT_PLAYER_READY_SEND_NOK_FOR_CHIEN; } else { game->players[game->preneur]->ready = MT_PLAYER_READY_SEND_OK_FOR_CHIEN; } { if (!wait_for_stable_state (game, game->preneur)) return (-1); } } for (i = 0; i < 6; i++) { game->card_status[game->players[game->preneur]->chien[i]] = 5; } } return (0); } gint play_game (game_t * game) { gint turn[8] = { -1, -1, -1, -1, -1, -1, -1, -1, }; gint i; gint turn_id; gint prev_winner = I (0); gint c; game->was_1trump_in_last_turn = FALSE; for (turn_id = 0; turn_id < 18; turn_id++) { for (i = 0; i < 4; i++) { gint j; gboolean turn_nok; /* Send everybody but one the state of the turn. */ for (j = 0; j < 4; j++) { if (j != ((i + prev_winner) % 4)) { memcpy (game->players[j]->turn, turn, 8 * sizeof (gint)); game->players[j]->ready = MT_PLAYER_READY_SEND_TURN_CARDS_ONLY; { if (!wait_for_stable_state (game, j)) return (-1); } } } /* Send the missing one the turn cards and an order to get his turn card */ memcpy (game->players[((i + prev_winner) % 4)]->turn, turn, 8 * sizeof (gint)); game->players[((i + prev_winner) % 4)]->ready = MT_PLAYER_READY_SEND_TURN_CARDS; { if (!wait_for_stable_state (game, ((i + prev_winner) % 4))) return (-1); } turn_nok = TRUE; c = -2; while (turn_nok) { GError *err = NULL; turn_nok = FALSE; game->players[((i + prev_winner) % 4)]->ready = MT_PLAYER_READY_WAIT_FOR_TURN_CARD; { if (!wait_for_stable_state (game, ((i + prev_winner) % 4))) return (-1); } c = game->players[((i + prev_winner) % 4)]->turn_card; if (!rule_check (game, prev_winner, c, ((i + prev_winner) % 4), game->players[((i + prev_winner) % 4)]->turn, &err)) { g_message (err->message); turn_nok = TRUE; game->players[((i + prev_winner) % 4)]->ready = MT_PLAYER_READY_SEND_NOK_FOR_CARD; while (game->players[((i + prev_winner) % 4)]->ready != MT_PLAYER_READY_NO) my_wait (WAIT_TIME); } } game->players[((i + prev_winner) % 4)]->ready = MT_PLAYER_READY_SEND_OK_FOR_CARD; { if (!wait_for_stable_state (game, ((i + prev_winner) % 4))) return (-1); } g_assert (c != -2); turn[((i + prev_winner) % 4)] = c; } prev_winner = rule_compute_winner (game, prev_winner, turn); for (i = 0; i < 4; i++) { if ((turn[i] == FOOL) && (turn_id < 17)) game->card_status[turn[i]] += 10; else game->card_status[turn[i]] = 10 + prev_winner; turn[i + 4] = turn[i]; turn[i] = -1; } } /* after the game */ for (i = 0; i < 4; i++) { memcpy (game->players[i]->turn, &(turn[4]), 4 * sizeof (gint)); game->players[i]->ready = MT_PLAYER_READY_SEND_LAST_TURN_CARDS; } for (i = 0; i < 4; i++) { { if (!wait_for_stable_state (game, i)) return (-1); } } for (i = 0; i < 4; i++) { if (turn[i + 4] == TRUMP) { game->was_1trump_in_last_turn = TRUE; } } return (0); } void compute_scores (game_t * game) { gint i; gint score = 0; gint n = 0; gint nb_oudlers = 0; gint score_ref = 56; gint points; for (i = 0; i < 78; i++) { if (game->card_status[i] == game->preneur + 10) { score += game->card_value[i]; n += 1; } } score -= (n + 1) / 2; if (game->card_status[TRUMP] == game->preneur + 10) nb_oudlers++; if (game->card_status[TRUMP + 20] == game->preneur + 10) nb_oudlers++; if (game->card_status[FOOL] == game->preneur + 10) nb_oudlers++; if (nb_oudlers == 0) score_ref = 56; else if (nb_oudlers == 1) score_ref = 51; else if (nb_oudlers == 2) score_ref = 41; else if (nb_oudlers == 3) score_ref = 36; points = score - score_ref; if (points >= 0) { points += 25; /* This is a bug. if (game->was_1trump_in_last_turn) points += 10; */ } else { points -= 25; /* This is a bug if (game->was_1trump_in_last_turn) points -= 10; */ } switch (game->bid) { case LIBMT_BID_PRISE: break; case LIBMT_BID_GARDE: points *= 2; break; case LIBMT_BID_SANS: points *= 4; break; case LIBMT_BID_CONTRE: points *= 6; break; default: g_message ("invalid value for game->bid"); } for (i = 0; i < 4; i++) { if (i == game->preneur) game->players[i]->score = (3 * points); else game->players[i]->score = -points; game->players[i]->score_total += game->players[i]->score; } for (i = 0; i < 4; i++) { int j; game->players[i]->all_scores[0] = game->bid; game->players[i]->all_scores[1] = points >= 0 ? 1 : 0; game->players[i]->all_scores[2] = score; game->players[i]->all_scores[3] = nb_oudlers; for (j = 0; j < 4; j++) { game->players[i]->all_scores[j + 4] = game->players[j]->score_total; } } } void compute_scores_when_no_game_was_played (game_t * game) { int i; for (i = 0; i < 4; i++) { int j; game->players[i]->all_scores[0] = LIBMT_BID_PASSE; game->players[i]->all_scores[1] = 1; game->players[i]->all_scores[2] = 0; game->players[i]->all_scores[3] = 0; for (j = 0; j < 4; j++) { game->players[i]->all_scores[j + 4] = game->players[j]->score_total; } } } int send_scores (game_t * game) { int i; for (i = 0; i < 4; i++) { game->players[i]->ready = MT_PLAYER_READY_SEND_SCORE; } for (i = 0; i < 4; i++) { { if (!wait_for_stable_state (game, i)) return (-1); } } return (0); } gint ask_players_if_the_want_to_play_again (game_t * game) { int i; gboolean ok_to_replay = TRUE; for (i = 0; i < 4; i++) { game->players[i]->ready = MT_PLAYER_READY_ACK_REPLAY; } for (i = 0; i < 4; i++) { { if (!wait_for_stable_state (game, i)) return (-1); } } for (i = 0; i < 4; i++) { if (game->players[i]->is_ok_to_play_again == 0) { ok_to_replay = FALSE; break; } } for (i = 0; i < 4; i++) { game->players[i]->is_ok_to_play_again = ok_to_replay ? 1 : 0; game->players[i]->ready = MT_PLAYER_READY_SEND_REPLAY_ANSWER; } for (i = 0; i < 4; i++) { { if (!wait_for_stable_state (game, i)) return (-1); } } return (ok_to_replay ? 1 : 0); } void init_card (void) { int i; /* init string of card */ for (i = 0; i < FOOL + 1; i++) { sprintf (card_str[i], "..?"); } for (i = 0; i < 10; i++) { sprintf (card_str[i + CLUB], "%i%s", i + 1, _("c")); sprintf (card_str[i + SPADE], "%i%s", i + 1, _("s")); sprintf (card_str[i + HEART], "%i%s", i + 1, _("h")); sprintf (card_str[i + DIAMOND], "%i%s", i + 1, _("d")); } sprintf (card_str[i + CLUB], "%s%s", _("J"), _("c")); sprintf (card_str[i + SPADE], "%s%s", _("J"), _("s")); sprintf (card_str[i + HEART], "%s%s", _("J"), _("h")); sprintf (card_str[i + DIAMOND], "%s%s", _("J"), _("d")); i++; sprintf (card_str[i + CLUB], "%s%s", _("C"), _("c")); sprintf (card_str[i + SPADE], "%s%s", _("C"), _("s")); sprintf (card_str[i + HEART], "%s%s", _("C"), _("h")); sprintf (card_str[i + DIAMOND], "%s%s", _("C"), _("d")); i++; sprintf (card_str[i + CLUB], "%s%s", _("Q"), _("c")); sprintf (card_str[i + SPADE], "%s%s", _("Q"), _("s")); sprintf (card_str[i + HEART], "%s%s", _("Q"), _("h")); sprintf (card_str[i + DIAMOND], "%s%s", _("Q"), _("d")); i++; sprintf (card_str[i + CLUB], "%s%s", _("K"), _("c")); sprintf (card_str[i + SPADE], "%s%s", _("K"), _("s")); sprintf (card_str[i + HEART], "%s%s", _("K"), _("h")); sprintf (card_str[i + DIAMOND], "%s%s", _("K"), _("d")); i++; for (i = 0; i < 21; i++) { sprintf (card_str[i + TRUMP], "%d", i + 1); } sprintf (card_str[FOOL], "%s", _("F")); } void dump_player (FILE * fd, player_t * player, gint indent) { gchar *indentation = g_strdup ("Player "); gint i; i = 0; while (i < indent) { indentation = g_strconcat (indentation, " ", NULL); i++; } if (!player) { fprintf (fd, "%s player=NULL\n", indentation); g_free (indentation); return; } fprintf (fd, "%splace=='%d'\n", indentation, player->place); for (i = 0; i < MAX_PLAYER; i++) { fprintf (fd, "\n%sPlayer #%d\n", indentation, i); fprintf (fd, "%snicks[%d]= '%s' (nicks_len[%d]='%d')\n", indentation, i, player->nicks[i] ? player->nicks[i] : "NULL", i, player->nicks_len[i]); fprintf (fd, "%sbids[%d]=", indentation, i); switch (player->bid[i]) { case LIBMT_BID_PASSE: fprintf (fd, "LIBMT_BID_PASSE\n"); break; case LIBMT_BID_PRISE: fprintf (fd, "LIBMT_BID_PRISE\n"); break; case LIBMT_BID_GARDE: fprintf (fd, "LIBMT_BID_GARDE\n"); break; case LIBMT_BID_SANS: fprintf (fd, "LIBMT_BID_SANS\n"); break; case LIBMT_BID_CONTRE: fprintf (fd, "LIBMT_BID_CONTRE\n"); break; } } fprintf (fd, "\n%sChien:\n%s", indentation, indentation); for (i = 0; i < 6; i++) { fprintf (fd, "%s (%02d) ", card_str[player->chien[i]], player->chien[i]); } fprintf (fd, "\n\n%sCards:\n%s", indentation, indentation); for (i = 0; i < MAX_HAND_CARD; i++) { fprintf (fd, "%s (%02d) ", card_str[player->card[i]], player->card[i]); } fprintf (fd, "\n\n%sTurn:\n%s", indentation, indentation); for (i = 0; i < 8; i++) { fprintf (fd, "%s (%02d) ", card_str[player->turn[i]], player->turn[i]); } fprintf (fd, "\n\n%sscore='%d'\n", indentation, player->score); fprintf (fd, "%sscore_total='%d'\n", indentation, player->score_total); fprintf (fd, "%sready=", indentation); switch (player->ready) { case MT_PLAYER_READY_NO: fprintf (fd, "MT_PLAYER_READY_NO\n"); break; case MT_PLAYER_READY_CLOSED: fprintf (fd, "MT_PLAYER_READY_CLOSED\n"); break; case MT_PLAYER_READY_GET_ID: fprintf (fd, "MT_PLAYER_READY_GET_ID\n"); break; case MT_PLAYER_READY_SEND_ID: fprintf (fd, "MT_PLAYER_READY_SEND_ID\n"); break; case MT_PLAYER_READY_SEND_PROTOCOL: fprintf (fd, "MT_PLAYER_READY_SEND_PROTOCOL\n"); break; case MT_PLAYER_READY_SEND_PLACE: fprintf (fd, "MT_PLAYER_READY_SEND_PLACE\n"); break; case MT_PLAYER_READY_GET_NICK: fprintf (fd, "MT_PLAYER_READY_GET_NICK\n"); break; case MT_PLAYER_READY_SEND_NICKS: fprintf (fd, "MT_PLAYER_READY_SEND_NICKS\n"); break; case MT_PLAYER_READY_DILL_CARDS: fprintf (fd, "MT_PLAYER_READY_DILL_CARDS\n"); break; case MT_PLAYER_READY_SEND_BIDS_ONLY: fprintf (fd, "MT_PLAYER_READY_SEND_BIDS_ONLY\n"); break; case MT_PLAYER_READY_SEND_BIDS_AND_ASK_FOR_BID: fprintf (fd, "MT_PLAYER_READY_SEND_BIDS_AND_ASK_FOR_BID\n"); break; case MT_PLAYER_READY_GET_BID: fprintf (fd, "MT_PLAYER_READY_GET_BID\n"); break; case MT_PLAYER_READY_SEND_FINAL_BIDS: fprintf (fd, "MT_PLAYER_READY_SEND_FINAL_BIDS\n"); break; case MT_PLAYER_READY_SHOW_CHIEN: fprintf (fd, "MT_PLAYER_READY_SHOW_CHIEN\n"); break; case MT_PLAYER_READY_GET_CHIEN: fprintf (fd, "MT_PLAYER_READY_GET_CHIEN\n"); break; case MT_PLAYER_READY_SEND_TURN_CARDS_ONLY: fprintf (fd, "MT_PLAYER_READY_SEND_TURN_CARDS_ONLY\n"); break; case MT_PLAYER_READY_SEND_TURN_CARDS: fprintf (fd, "MT_PLAYER_READY_SEND_TURN_CARDS\n"); break; case MT_PLAYER_READY_WAIT_FOR_TURN_CARD: fprintf (fd, "MT_PLAYER_READY_WAIT_FOR_TURN_CARD\n"); break; case MT_PLAYER_READY_SEND_LAST_TURN_CARDS: fprintf (fd, "MT_PLAYER_READY_SEND_LAST_TURN_CARDS\n"); break; case MT_PLAYER_READY_SEND_SCORE: fprintf (fd, "MT_PLAYER_READY_SEND_SCORE\n"); break; case MT_PLAYER_READY_END: fprintf (fd, "MT_PLAYER_READY_END\n"); break; default: fprintf (fd, "??? (%d)\n", player->ready); } g_free (indentation); } void dump_game (int sig, siginfo_t * siginfo, void *val) { game_t *game = sa_game; gint indent = sa_indent; time_t t = time (0); gchar *filename; FILE *fd; gchar *indentation = g_strdup (""); gint i; gchar *s; init_card (); i = 0; while (i < indent) { indentation = g_strconcat (indentation, " ", NULL); i++; } filename = g_strdup_printf ("%s/dump_maitretarot_game_t_%d", s = g_get_current_dir (), (gint) t); g_free (s); fd = fopen (filename, "w"); if (!fd) { g_message ("Could not dump the game_t structure into '%s'", filename); return; } fprintf (fd, "%sMAX_PLAYER='%d'\n", indentation, MAX_PLAYER); fprintf (fd, "%ssock='%d'\n", indentation, game->sock); fprintf (fd, "%sserver_id[0]='%d'\n", indentation, game->server_id[0]); fprintf (fd, "%sserver_id[1]='%d'\n", indentation, game->server_id[1]); fprintf (fd, "%sprotocol_version='%d'\n", indentation, game->protocol_version); for (i = 0; i < MAX_PLAYER; i++) { fprintf (fd, "\n%sPlayer #%d\n", indentation, i); dump_player (fd, game->players[i], indent + 4); fprintf (fd, "%s nicks[%d]= '%s' (nicks_len[%d]='%d')\n", indentation, i, game->nicks[i] ? game->nicks[i] : "NULL", i, game->nicks_len[i]); } fprintf (fd, "\n%s/* card_status[i]: \n" "%s * 0->4 : player id\n" "%s * 5 : chien\n" "%s * 10->14 : owner of the turn\n" "%s */\n", indentation, indentation, indentation, indentation, indentation); fprintf (fd, "\n%s i Card deck card_status card_value\n", indentation); for (i = 0; i < 78; i++) { fprintf (fd, "%s%02d %4s %4d %11d %10d\n", indentation, i, card_str[i], game->deck[i], game->card_status[i], game->card_value[i]); } fprintf (fd, "\n%sChien:\n%s", indentation, indentation); for (i = 0; i < 6; i++) { fprintf (fd, "%s (%02d) ", card_str[game->chien[i]], game->chien[i]); } fprintf (fd, "\n\n%staker_score='%d'\n", indentation, game->taker_score); fprintf (fd, "%sbid=", indentation); switch (game->bid) { case LIBMT_BID_PASSE: fprintf (fd, "LIBMT_BID_PASSE\n"); break; case LIBMT_BID_PRISE: fprintf (fd, "LIBMT_BID_PRISE\n"); break; case LIBMT_BID_GARDE: fprintf (fd, "LIBMT_BID_GARDE\n"); break; case LIBMT_BID_SANS: fprintf (fd, "LIBMT_BID_SANS\n"); break; case LIBMT_BID_CONTRE: fprintf (fd, "LIBMT_BID_CONTRE\n"); break; } for (i = 0; i < 4; i++) { fprintf (fd, "%sbids[%d]=", indentation, i); switch (game->bids[i]) { case LIBMT_BID_PASSE: fprintf (fd, "LIBMT_BID_PASSE\n"); break; case LIBMT_BID_PRISE: fprintf (fd, "LIBMT_BID_PRISE\n"); break; case LIBMT_BID_GARDE: fprintf (fd, "LIBMT_BID_GARDE\n"); break; case LIBMT_BID_SANS: fprintf (fd, "LIBMT_BID_SANS\n"); break; case LIBMT_BID_CONTRE: fprintf (fd, "LIBMT_BID_CONTRE\n"); break; } } fprintf (fd, "\n%sturn='%d'\n", indentation, game->turn); for (i = 0; i < 4; i++) { fprintf (fd, "%splayers_order[%d]='%d'\n", indentation, i, game->players_order[i]); } fprintf (fd, "%spreneur='%d'\n", indentation, game->preneur); fprintf (fd, "%swas_1trump_in_last_turn='%s'\n", indentation, (game->was_1trump_in_last_turn ? "TRUE" : "FALSE")); fclose (fd); g_free (indentation); }