/* MaitreTarot. * (C) 2002 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 "cardgame_server.h" #include "game.h" GQuark mt_rule_error_quark (void) { static GQuark q = 0; if (q == 0) q = g_quark_from_static_string ("mt-rule-error-quark"); return q; } gboolean rule_check (void *game, int prev_winner, int c, int p, GError ** error) { game_t *g = game; gint card; gint color, pcolor; printf ("prev_winner=%d card=%2d player=%d t0=%d t1=%d t2=%d t3=%d t4=%d\n", prev_winner, c, p, RULES(g->rules)->board[0], RULES(g->rules)->board[1], RULES(g->rules)->board[2], RULES(g->rules)->board[3], RULES(g->rules)->board[4]); /* Test if the played card is in the player's hand */ if (RULES(g->rules)->card_status[c] != p) { printf ("c=%2d game->card_status[c]=%2d p=%d\n", c, RULES(g->rules)->card_status[c], p); g_set_error (error, MT_RULE_ERROR, MT_RULE_ERROR_CARD_IS_NOT_IN_PLAYERS_GAME, "The card is not in the current player's game"); return (FALSE); } /* always OK if the player played FOOL */ if (c == FOOL) return (TRUE); /* The first player can always play what he wants */ if (p == prev_winner) return (TRUE); card = RULES(g->rules)->board[prev_winner]; if (card == FOOL) { gint i = (prev_winner + 1) % g->nb_players_max; /* test if the 1st player played FOOL: * if yes, and if p is the 2nd player, * he can play anything */ if (p == i) return (TRUE); card = RULES(g->rules)->board[i]; } g_assert (card != -1); color = card / 14; pcolor = c / 14; if ((color == pcolor) && (color < 4)) { /* Test if the player played a card in the right color */ return (TRUE); } else if (pcolor >= 4) { int max; int i; if (color < 4) { /* Test if the player could play in the color or not */ for (i = color * 14; i < (color * 14 + 13); i++) { if (RULES(g->rules)->card_status[i] == p) { g_set_error (error, MT_RULE_ERROR, MT_RULE_ERROR_PLAYER_CAN_PLAY_COLOR, "Player has to play the right color"); return (FALSE); } } } /* test if the player played a high enough trump */ max = c; for (i = 0; i < g->nb_players_max; i++) { if (RULES(g->rules)->board[i] != -1) { if ((RULES(g->rules)->board[i] > max) && (RULES(g->rules)->board[i] != FOOL)) max = RULES(g->rules)->board[i]; } } if (max == c) return (TRUE); /* test if the player has a bigger trump card */ for (i = max; i < FOOL; i++) { if (RULES(g->rules)->card_status[i] == p) { g_set_error (error, MT_RULE_ERROR, MT_RULE_ERROR_PLAYER_CAN_PLAY_COLOR, "Player can player a bigger trump card"); return (FALSE); } } return (TRUE); } else if (color != pcolor) { int i; if (color < 4) { /* Test if the player could play in the color or not */ for (i = color * 14; i < (color * 14 + 13); i++) { if (RULES(g->rules)->card_status[i] == p) { g_set_error (error, MT_RULE_ERROR, MT_RULE_ERROR_PLAYER_CAN_PLAY_COLOR, "Player has to play the right color"); return (FALSE); } } } /* Test if the player could play trump or not */ for (i = TRUMP; i < FOOL; i++) { if (RULES(g->rules)->card_status[i] == p) { g_set_error (error, MT_RULE_ERROR, MT_RULE_ERROR_PLAYER_CAN_PLAY_TRUMP, "Player can play trump"); return (FALSE); } } return (TRUE); } else { g_set_error (error, MT_RULE_ERROR, MT_RULE_ERROR_UNKNOWN_CASE, "Unknown case"); return (FALSE); } g_set_error (error, MT_RULE_ERROR, MT_RULE_ERROR_UNKNOWN_CASE, "Unknown case"); return (FALSE); } gint rule_compute_winner (void *game, gint prev_winner) { game_t *g = game; gint winner = prev_winner; gint max; gint i; gint color; if (RULES (g->rules)->card_value[RULES (g->rules)->board[prev_winner]] == FOOL) winner = (winner + 1) % g->nb_players_max; max = RULES (g->rules)->card_value[RULES (g->rules)->board[winner]]; color = max / 14; if (color > 4) color = 4; for (i = 0; i < g->nb_players_max; i++) { int card = RULES (g->rules)->card_value[RULES (g->rules)->board[i]]; /* The following looks a little strange * because we test if (card > max) at the * end. This works because trumps are after * colors, which makes trumps always * stronger than colors. This is a coding * fact, not a Tarot rule :) * YM * */ if ((((card / 14) == color) || (((card / 14) >= 4) && (card != FOOL))) && (card > max)) { winner = i; max = card; } } return (winner); }