/* MaitreTarot. * (C) 2002 Philippe Brochard * * 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 /* FIXME change this by gettext functions */ #define _(a) a static libmt_client_function_t libmt_client_function[LIBMT_CLIENT_MAX_FUNCTION]; static gchar *str_err_function[LIBMT_CLIENT_MAX_FUNCTION]; gboolean libmt_client_check_version (gint major, gint minor, gint micro) { return ((LIBMT_MAJOR > major) || ((LIBMT_MAJOR == major) && (LIBMT_MINOR > minor)) || ((LIBMT_MAJOR == major) && (LIBMT_MINOR == minor) && (LIBMT_MICRO >= micro))); } static void player_callback (libmt_client_player_t * player, gint num) { if (num >= 0 && num < LIBMT_CLIENT_MAX_FUNCTION) { if (libmt_client_function[num] != NULL) { libmt_client_function[num] (player); } else { g_printerr (str_err_function[num]); exit (-1); } } else { g_printerr (_ ("libmt_client_function : try to call an undefined function\n")); exit (-1); } } gint libmt_client_init (libmt_client_player_t * player, gint nb_player, gint nb_hand_card, gint nb_chien_card) { gint i; player->nb_player = nb_player; player->nb_hand_card = nb_hand_card; player->nb_chien_card = nb_chien_card; player->client_private_data = NULL; player->replay = TRUE; player->place = -1; player->card_play = -1; player->net.sock = -1; player->channels_set = NULL; for (i = 0; i < nb_player; i++) { player->score[i] = 0; player->nick[i] = NULL; player->bid[i] = -1; player->card_turn[i] = -1; player->card_previous_turn[i] = -1; } for (i = 0; i < nb_hand_card; i++) player->card[i] = -1; for (i = 0; i < nb_chien_card; i++) player->chien[i] = -1; for (i = 0; i < LIBMT_CLIENT_MAX_FUNCTION; i++) { libmt_client_function[i] = NULL; } str_err_function[LIBMT_CLIENT_FUNCTION_INIT] = _("libmt_client_function INIT : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_GAME_INIT] = _("libmt_client_function GAME_INIT : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_MAKE_BID] = _("libmt_client_function MAKE_BID : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_MAKE_CHIEN] = _("libmt_client_function MAKE_CHIEN : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_NOT_MAKE_CHIEN] = _("libmt_client_function NOT_MAKE_CHIEN : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_CHOOSE_CARD] = _("libmt_client_function CHOOSE_CARD : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_DRAW] = _("libmt_client_function DRAW : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_REMOVE_CARD] = _("libmt_client_function REMOVE CARD : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_ACK_REPLAY] = _("libmt_client_function ACK REPLAY : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_LOST_CONNECTION] = _("libmt_client_function LOST CONNECTION : not initialised\n"); str_err_function[LIBMT_CLIENT_FUNCTION_NORMAL_CLOSE] = _("libmt_client_function NORMAL CLOSE : not initialised\n"); return (0); } gint libmt_client_init_callback (libmt_client_function_e num_funct, libmt_client_function_t function) { if (num_funct < 0 || num_funct >= LIBMT_CLIENT_MAX_FUNCTION) return (-1); libmt_client_function[num_funct] = function; return (0); } static gboolean game_loop (libmt_client_player_t * player) { gint ok; gint gi, gj; gint cpt; gint ret; gboolean replay; ok = libmt_client_get_hand_card (player); if (ok < 0) return -1; player_callback (player, LIBMT_CLIENT_FUNCTION_GAME_INIT); player->draw_state = LIBMT_CLIENT_DRAW_OTHER_BID; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); for (gi = 0; gi < player->nb_player; gi++) { ok = libmt_client_get_bid (player); if (ok < 0) return -1; /* gi can be pass to draw_function as the player who makes its bid */ player->draw_state = LIBMT_CLIENT_DRAW_GET_BID; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); ok = libmt_client_get_bid_is_valide (player); if (ok < 0) return -1; if (ok != 0 /* && libmt_client_have_to_make_bid (player) != 0 */ ) { player_callback (player, LIBMT_CLIENT_FUNCTION_MAKE_BID); ok = libmt_client_send_bid (player); if (ok < 0) return -1; } } ok = libmt_client_get_final_bid (player); if (ok < 0) return -1; player->draw_state = LIBMT_CLIENT_DRAW_MAKE_CHIEN; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); if (libmt_client_is_someone_take (player)) { if (libmt_client_have_to_get_chien (player) != 0) { ok = libmt_client_get_chien (player); if (ok < 0) return -1; if (libmt_client_is_the_taker (player) != 0) { ok = 0; while (ok == 0) { player_callback (player, LIBMT_CLIENT_FUNCTION_MAKE_CHIEN); ok = libmt_client_send_chien (player); if (ok < 0) return -1; } } else { player->draw_state = LIBMT_CLIENT_DRAW_GET_CHIEN; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); player_callback (player, LIBMT_CLIENT_FUNCTION_NOT_MAKE_CHIEN); } } else { player_callback (player, LIBMT_CLIENT_FUNCTION_NOT_MAKE_CHIEN); } /* Main loop */ player->draw_state = LIBMT_CLIENT_DRAW_START_PLAYING; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); for (gi = 0, cpt = -1; gi < player->nb_hand_card; gi++) { for (gj = 0; gj < player->nb_player; gj++) { ret = libmt_client_get_card (player); if (ret < 0) return -1; cpt += 1; if (gi > 0 && (cpt % 4) == 0) { player->draw_state = LIBMT_CLIENT_DRAW_PAUSE_END_TURN; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); } if (ret == 0) { player->draw_state = LIBMT_CLIENT_DRAW_OTHER_PLAY; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); } else { ok = 0; while (ok == 0) { player_callback (player, LIBMT_CLIENT_FUNCTION_CHOOSE_CARD); ok = libmt_client_send_card (player); if (ok < 0) return -1; } } } player_callback (player, LIBMT_CLIENT_FUNCTION_REMOVE_CARD); } ok = libmt_client_get_last_turn (player); if (ok < 0) return -1; ok = libmt_client_get_score (player); if (ok < 0) return -1; ok = libmt_client_get_chien_at_end (player); if (ok < 0) return -1; player->draw_state = LIBMT_CLIENT_DRAW_PAUSE_END_GAME; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); } else { ok = libmt_client_get_score (player); if (ok < 0) return -1; ok = libmt_client_get_chien_at_end (player); if (ok < 0) return -1; player->draw_state = LIBMT_CLIENT_DRAW_NONE_TAKE; player_callback (player, LIBMT_CLIENT_FUNCTION_DRAW); } player_callback (player, LIBMT_CLIENT_FUNCTION_ACK_REPLAY); ok = libmt_client_send_replay_answer (player); if (ok < 0) return -1; ok = libmt_client_get_replay_answer (player); if (ok < 0) { return -1; } else if (ok == 1) { replay = TRUE; } else replay = FALSE; return replay; } gint libmt_client_main_loop (libmt_client_player_t * player, GString * host_name, gint port, gint id, gint version) { gint ok = 0; player_callback (player, LIBMT_CLIENT_FUNCTION_INIT); if (libmt_client_connect_to_server (player, host_name, port, id, version) < 0) { player_callback (player, LIBMT_CLIENT_FUNCTION_LOST_CONNECTION); libmt_client_close_connexion (player); return -1; } ok = 1; while (ok) { ok = game_loop (player); if (ok < 0) { player_callback (player, LIBMT_CLIENT_FUNCTION_LOST_CONNECTION); libmt_client_close_connexion (player); return -1; } } libmt_client_close_connexion (player); player_callback (player, LIBMT_CLIENT_FUNCTION_NORMAL_CLOSE); return (0); }