Commit 8af08ad0 authored by Vivien Kraus's avatar Vivien Kraus
Browse files

Check the handfuls, discard and call if we do not know the cards

There is not much that we can check: we can only check that the taker
or the player showing a handful can have these cards (i.e. we don't
have them).
parent f6e9bec2
......@@ -122,7 +122,7 @@ game_generalize (TarotGame * game, TarotGameHandle * handle)
}
}
static inline int game_step_advance (TarotGameHandle * game);
static inline int game_step_advance (TarotGame * game);
static inline void
game_set_dealt (TarotGameHandle * handle, int dealt)
......@@ -408,7 +408,7 @@ game_duplicate_set_deal (TarotGame * game, size_t n_owners,
game_set_duplicate_deal (&handle, n_owners, owners);
if (step == TAROT_DEAL)
{
int err = game_step_advance (&handle);
int err = game_step_advance (game);
if (err != 0)
{
return TAROT_GAME_INVEV;
......@@ -439,7 +439,7 @@ game_duplicate_set_taker (TarotGame * game, TarotPlayer taker)
game_set_duplicate_taker (&handle, taker);
if (step == TAROT_BIDS)
{
int err = game_step_advance (&handle);
int err = game_step_advance (game);
if (err != 0)
{
return TAROT_GAME_INVEV;
......@@ -463,7 +463,7 @@ game_duplicate_set_call (TarotGame * game, TarotCard call)
game_set_duplicate_call (&handle, call);
if (step == TAROT_CALL)
{
int err = game_step_advance (&handle);
int err = game_step_advance (game);
if (err != 0)
{
return TAROT_GAME_INVEV;
......@@ -1652,7 +1652,8 @@ game_check_decl (const TarotGameHandle * game, int decl)
}
static inline int
game_check_call (const TarotGameHandle * game, TarotCard call)
game_check_call (const TarotGame * game_for_counter,
const TarotGameHandle * game, TarotCard call)
{
int ok = (game_get_step (game) == TAROT_CALL);
TarotNumber n;
......@@ -1666,6 +1667,30 @@ game_check_call (const TarotGameHandle * game, TarotCard call)
{
ok = hand_check_call (takers_hand, n);
}
else
{
TarotNumber superior;
TarotCounter validator;
counter_load_from_game (&validator, game_for_counter);
/* Check that this is a face and that the taker may own all
* superior faces */
if (n < TAROT_JACK || n > TAROT_KING || s == TAROT_TRUMPS)
{
ok = 0;
}
for (superior = n + 1; superior <= TAROT_KING; superior++)
{
TarotCard superior_card;
if (of (superior, s, &superior_card) != 0)
{
assert (0);
}
if (!counter_may_own (&validator, 1, &taker, superior_card))
{
ok = 0;
}
}
}
}
return ok;
}
......@@ -1694,7 +1719,8 @@ game_check_dog (const TarotGameHandle * game, const TarotHand * dog)
}
static inline int
game_check_discard (const TarotGameHandle * game, const TarotHand * discard)
game_check_discard (const TarotGame * game_for_counter,
const TarotGameHandle * game, const TarotHand * discard)
{
int ok = (game_get_step (game) == TAROT_DISCARD);
TarotPlayer taker = bids_taker (game->bids);
......@@ -1713,11 +1739,26 @@ game_check_discard (const TarotGameHandle * game, const TarotHand * discard)
doscard_check_partial_discard (&(game->doscard), taker, discard);
}
}
else if (ok)
{
size_t i_card;
TarotCounter validator;
counter_load_from_game (&validator, game_for_counter);
for (i_card = 0; i_card < *(discard->n); i_card++)
{
if (!counter_may_own
(&validator, 1, &taker, discard->buffer[i_card]))
{
ok = 0;
}
}
}
return ok;
}
static inline int
game_check_handful (const TarotGameHandle * game, const TarotHand * handful)
game_check_handful (const TarotGame * game_for_counter,
const TarotGameHandle * game, const TarotHand * handful)
{
size_t i_current = tricks_current (&(game->tricks));
int ok = (game_get_step (game) == TAROT_TRICKS && i_current == 0);
......@@ -1742,6 +1783,20 @@ game_check_handful (const TarotGameHandle * game, const TarotHand * handful)
ok = hand_check_handful_without_discard (next_hand, handful);
}
}
else if (ok)
{
size_t i_card;
TarotCounter validator;
counter_load_from_game (&validator, game_for_counter);
for (i_card = 0; i_card < *(handful->n); i_card++)
{
if (!counter_may_own
(&validator, 1, &next, handful->buffer[i_card]))
{
ok = 0;
}
}
}
return ok;
}
......@@ -1906,16 +1961,16 @@ game_check_event_aux (const TarotGame * game_not_generalized,
case TAROT_CALL_EVENT:
error = event_get_call (event, &card);
assert (error == 0);
return game_check_call (game, card);
return game_check_call (game_not_generalized, game, card);
case TAROT_DOG_EVENT:
copy_cards (&hand, event->n, event->data);
return game_check_dog (game, &hand);
case TAROT_DISCARD_EVENT:
copy_cards (&hand, event->n, event->data);
return game_check_discard (game, &hand);
return game_check_discard (game_not_generalized, game, &hand);
case TAROT_HANDFUL_EVENT:
copy_cards (&hand, event->n, event->data);
return game_check_handful (game, &hand);
return game_check_handful (game_not_generalized, game, &hand);
case TAROT_CARD_EVENT:
error = event_get_card (event, &card);
assert (error == TAROT_EVENT_OK);
......@@ -1953,19 +2008,25 @@ game_create_hand (size_t n_max, size_t *n, TarotCard * buffer)
return ret;
}
static inline int game_add_deal_all (TarotGameHandle * game,
static inline int game_add_deal_all (TarotGame * game_not_generalized,
TarotGameHandle * game,
const TarotPlayer * owners);
static inline int game_add_bid (TarotGameHandle * game, TarotBid bid);
static inline int game_add_call (TarotGameHandle * game, TarotCard call);
static inline int game_add_bid (TarotGame * game_not_generalized,
TarotGameHandle * game, TarotBid bid);
static inline int game_add_call (TarotGame * game_not_generalized,
TarotGameHandle * game, TarotCard call);
static inline int
game_step_advance (TarotGameHandle * game)
game_step_advance (TarotGame * game_not_generalized)
{
TarotGameHandle game_handle;
TarotGameHandle *game = &game_handle;
game_generalize (game_not_generalized, game);
switch (game_get_step (game))
{
case TAROT_SETUP:
game_set_step (game, TAROT_DEAL);
return game_step_advance (game);
return game_step_advance (game_not_generalized);
break;
case TAROT_DEAL:
do
......@@ -1978,7 +2039,7 @@ game_step_advance (TarotGameHandle * game)
if (owners != NULL)
{
assert (n_owners == 78);
return game_add_deal_all (game, owners);
return game_add_deal_all (game_not_generalized, game, owners);
}
for (i = 0; i < game->opt.n_players; ++i)
{
......@@ -1994,7 +2055,7 @@ game_step_advance (TarotGameHandle * game)
assert (error == 0);
(void) error;
game_set_step (game, TAROT_BIDS);
return game_step_advance (game);
return game_step_advance (game_not_generalized);
}
}
while (0);
......@@ -2007,11 +2068,13 @@ game_step_advance (TarotGameHandle * game)
{
if (*forced_taker == bids_next (game->bids))
{
return game_add_bid (game, TAROT_PUSH);
return game_add_bid (game_not_generalized, game,
TAROT_PUSH);
}
else
{
return game_add_bid (game, TAROT_PASS);
return game_add_bid (game_not_generalized, game,
TAROT_PASS);
}
}
}
......@@ -2043,7 +2106,7 @@ game_step_advance (TarotGameHandle * game)
assert (error == 0);
(void) error;
game_set_step (game, TAROT_CALL);
return game_step_advance (game);
return game_step_advance (game_not_generalized);
}
else
{
......@@ -2060,7 +2123,7 @@ game_step_advance (TarotGameHandle * game)
if (bids_discard_allowed (game->bids, game->opt.n_players))
{
game_set_step (game, TAROT_DOG);
return game_step_advance (game);
return game_step_advance (game_not_generalized);
}
else
{
......@@ -2082,7 +2145,7 @@ game_step_advance (TarotGameHandle * game)
const TarotCard *forced_call = game_get_duplicate_call (game);
if (forced_call != NULL)
{
return game_add_call (game, *forced_call);
return game_add_call (game_not_generalized, game, *forced_call);
}
}
else
......@@ -2099,7 +2162,7 @@ game_step_advance (TarotGameHandle * game)
if (bids_discard_allowed (game->bids, game->opt.n_players))
{
game_set_step (game, TAROT_DOG);
return game_step_advance (game);
return game_step_advance (game_not_generalized);
}
else
{
......@@ -2185,7 +2248,8 @@ game_step_advance (TarotGameHandle * game)
}
static inline int
game_add_deal_all (TarotGameHandle * game, const TarotPlayer * owners)
game_add_deal_all (TarotGame * game_not_generalized, TarotGameHandle * game,
const TarotPlayer * owners)
{
int error = (game_check_deal_all (game, owners) == 0);
TarotCard i;
......@@ -2194,7 +2258,7 @@ game_add_deal_all (TarotGameHandle * game, const TarotPlayer * owners)
*(game->has_duplicate_deal) = 0;
game_set_dealt (game, game->opt.n_players);
error = error || hands_set_all (&(game->hands), owners);
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
for (i = 0; i < 78; i++)
{
if (owners[i] >= game->opt.n_players)
......@@ -2209,8 +2273,8 @@ game_add_deal_all (TarotGameHandle * game, const TarotPlayer * owners)
}
static inline int
game_add_deal (TarotGameHandle * game, TarotPlayer myself,
const TarotHand * cards)
game_add_deal (TarotGame * game_not_generalized, TarotGameHandle * game,
TarotPlayer myself, const TarotHand * cards)
{
int error = (game_check_deal (game, myself, cards) == 0);
if (error == 0)
......@@ -2218,20 +2282,21 @@ game_add_deal (TarotGameHandle * game, TarotPlayer myself,
*(game->has_duplicate_deal) = 0;
game_set_dealt (game, myself);
error = error || hands_set (&(game->hands), myself, cards);
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
assert (error == 0);
}
return error;
}
static inline int
game_add_bid (TarotGameHandle * game, TarotBid next)
game_add_bid (TarotGame * game_not_generalized, TarotGameHandle * game,
TarotBid next)
{
int error = (game_check_bid (game, next) == 0);
if (error == 0)
{
error = error || bids_add (game->bids, next, game->opt.n_players);
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
assert (error == 0);
*(game->has_duplicate_taker) = 0;
}
......@@ -2239,22 +2304,24 @@ game_add_bid (TarotGameHandle * game, TarotBid next)
}
static inline int
game_add_decl (TarotGameHandle * game, int next)
game_add_decl (TarotGame * game_not_generalized, TarotGameHandle * game,
int next)
{
int error = (game_check_decl (game, next) == 0);
if (error == 0)
{
error = error || decls_add (game->decls, next, game->opt.n_players);
assert (error == 0);
error = game_step_advance (game);
error = game_step_advance (game_not_generalized);
}
return error;
}
static inline int
game_add_call (TarotGameHandle * game, TarotCard call)
game_add_call (TarotGame * game_not_generalized, TarotGameHandle * game,
TarotCard call)
{
int error = (game_check_call (game, call) == 0);
int error = (game_check_call (game_not_generalized, game, call) == 0);
if (error == 0)
{
TarotPlayer i;
......@@ -2274,14 +2341,15 @@ game_add_call (TarotGameHandle * game, TarotCard call)
}
}
}
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
assert (error == 0);
}
return error;
}
static inline int
game_add_dog (TarotGameHandle * game, const TarotHand * dog)
game_add_dog (TarotGame * game_not_generalized, TarotGameHandle * game,
const TarotHand * dog)
{
int error = (game_check_dog (game, dog) == 0);
if (error == 0)
......@@ -2296,7 +2364,7 @@ game_add_dog (TarotGameHandle * game, const TarotHand * dog)
error = error || call_doscard_card (game->call, c);
}
}
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
assert (error == 0);
}
return error;
......@@ -2341,12 +2409,13 @@ game_can_autoreveal (const TarotGame * game, size_t *n_dog, size_t start,
}
static inline int
game_add_discard (TarotGameHandle * game, const TarotHand * discard)
game_add_discard (TarotGame * game_not_generalized, TarotGameHandle * game,
const TarotHand * discard)
{
TarotPlayer taker;
TarotHand *takers_hand;
TarotHand *dog;
int error = (game_check_discard (game, discard) == 0);
int error = (game_check_discard (game_not_generalized, game, discard) == 0);
if (error == 0)
{
TarotPlayer i;
......@@ -2378,21 +2447,22 @@ game_add_discard (TarotGameHandle * game, const TarotHand * discard)
}
}
}
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
assert (error == 0);
}
return error;
}
static inline int
game_add_handful (TarotGameHandle * game, const TarotHand * handful)
game_add_handful (TarotGame * game_not_generalized, TarotGameHandle * game,
const TarotHand * handful)
{
int error = (game_check_handful (game, handful) == 0);
int error = (game_check_handful (game_not_generalized, game, handful) == 0);
if (error == 0)
{
error = error
|| handfuls_add (game->handfuls, handful, game->opt.n_players);
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
}
return error;
}
......@@ -2433,7 +2503,7 @@ game_add_card_aux (TarotGame * game_not_generalized, TarotGameHandle * game,
error = error || call_trick_card (game->call, next, card);
assert (error == 0);
}
error = error || game_step_advance (game);
error = error || game_step_advance (game_not_generalized);
assert (error == 0);
error = error || handfuls_card (game->handfuls, game->opt.n_players);
assert (error == 0);
......@@ -2505,36 +2575,36 @@ game_add_event_aux (TarotGame * game, const TarotGameEvent * event)
game_generalize (game, &h);
}
while (0);
return game_step_advance (&h);
return game_step_advance (game);
case TAROT_DEAL_EVENT:
copy_cards (&hand, event->n, event->data);
myself = event->u.deal;
return game_add_deal (&h, myself, &hand);
return game_add_deal (game, &h, myself, &hand);
case TAROT_DEAL_ALL_EVENT:
n_players = event->n;
owners = event->data;
return (n_players == 78 && game_add_deal_all (&h, owners));
return (n_players == 78 && game_add_deal_all (game, &h, owners));
case TAROT_BID_EVENT:
error = event_get_bid (event, &bid);
assert (error == 0);
return game_add_bid (&h, bid);
return game_add_bid (game, &h, bid);
case TAROT_DECL_EVENT:
error = event_get_decl (event, &decl);
assert (error == 0);
return game_add_decl (&h, decl);
return game_add_decl (game, &h, decl);
case TAROT_CALL_EVENT:
error = event_get_call (event, &card);
assert (error == 0);
return game_add_call (&h, card);
return game_add_call (game, &h, card);
case TAROT_DOG_EVENT:
copy_cards (&hand, event->n, event->data);
return game_add_dog (&h, &hand);
return game_add_dog (game, &h, &hand);
case TAROT_DISCARD_EVENT:
copy_cards (&hand, event->n, event->data);
return game_add_discard (&h, &hand);
return game_add_discard (game, &h, &hand);
case TAROT_HANDFUL_EVENT:
copy_cards (&hand, event->n, event->data);
return game_add_handful (&h, &hand);
return game_add_handful (game, &h, &hand);
case TAROT_CARD_EVENT:
error = event_get_card (event, &card);
assert (error == 0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment