Commit 43b05d41 authored by Vivien Kraus's avatar Vivien Kraus
Browse files

Deal for one player.

parent 826efcee
Pipeline #27373 passed with stage
in 1 minute and 3 seconds
......@@ -9,6 +9,7 @@ AC_CONFIG_MACRO_DIRS([m4])
# Checks for programs.
AC_PROG_CC
AC_PROG_CC_STDC
gl_EARLY
AM_INIT_AUTOMAKE([subdir-objects])
AM_PROG_AR
......
......@@ -49,23 +49,8 @@ is dealt the @emph{petit} without any other trumps and without the
situation is called @dfn{single petit} (or in French @dfn{petit sec}
or @dfn{petit imprenable}).
The way libtarot deals cards is called @emph{imputation}. This way,
it can be used for an AI: the AI holds a list of constraints telling
what players can have what cards (deducted from the game rules) so it
can compute a complete deal that is compatible with rules, and have an
idea who has what cards in reality. @xref{Artificial intelligence}
for a more in-depth overview of the imputation process.
For a game server, one would do the following:
@itemize
@item
build a @code{TarotGame};
@item
@emph{impute} the game (@pxref{Artificial intelligence});
@item
you can get the cards of everybody:
@deftypefun {const TarotCard *} taort_game_cards (const TarotGame *restrict @var{game}, TarotPlayer @var{player}, unsigned int *@var{n})
Return the cards of @var{player}, setting @var{n} to the number of
cards.
@deftypefun {int} tarot_game_check_deal_one (const TarotGame *@var{game}, TarotPlayer @var{player}, unsigned int @var{n}, const TarotCard *@var{cards})
Check that a regular player can be given the @var{n} cards in
@var{cards}. The computation is faster if @var{cards} are sorted
ascendently.
@end deftypefun
@end itemize
......@@ -8,11 +8,14 @@ libtarot_la_SOURCES = \
_tarot_localedir.c \
_tarot_n_cards_in_trick.c \
_tarot_n_players_between.c \
_tarot_no_doubles.c \
_tarot_no_petit_sec.c \
_tarot_strongest_trump.c \
tarot_decompose.c \
tarot_game_bids.c \
tarot_game_call.c \
tarot_game_cards.c \
tarot_game_check_deal_one.c \
tarot_game_decl.c \
tarot_game_discard.c \
tarot_game_dog.c \
......@@ -38,11 +41,13 @@ include_HEADERS = tarot.h
TESTS = \
check_composition \
check_game_init
check_game_init \
check_deal
check_PROGRAMS = \
check_composition \
check_game_init
check_game_init \
check_deal
check_composition_SOURCES = check_composition.c
check_composition_CFLAGS = $(ASAN_CFLAGS)
......@@ -54,11 +59,17 @@ check_game_init_CFLAGS = $(ASAN_CFLAGS)
check_game_init_LDADD = libtarot.la
check_game_init_LIBS = $(ASAN_LIBS)
check_deal_SOURCES = check_deal.c
check_deal_CFLAGS = $(ASAN_CFLAGS)
check_deal_LDADD = libtarot.la
check_deal_LIBS = $(ASAN_LIBS)
INDENTED_FILES = \
$(include_HEADERS) \
$(libtarot_la_SOURCES) \
$(check_composition_SOURCES) \
$(check_game_init_SOURCES)
$(check_game_init_SOURCES) \
$(check_deal_SOURCES)
../lib/libgnu.la:
(cd ../lib && $(MAKE) libgnu.la)
......
#include "tarot_private.h"
/* In case cards is not sorted, the complexity is a little higher */
static int
is_present_before (const TarotCard *cards, unsigned int i)
{
unsigned int j = 0;
for (j = 0; j < i; ++j)
{
if (cards[j] == cards[i])
return 1;
}
return 0;
}
static int
no_doubles_unsorted (const TarotCard *cards, unsigned int n)
{
unsigned int i = 1;
for (i = 1; i < n; ++i)
{
if (is_present_before (cards, i))
return 0;
}
return 1;
}
int
_tarot_no_doubles (const TarotCard *cards, unsigned int n)
{
unsigned int i = 1;
for (i = 1; i < n; ++i)
{
if (cards[i] > cards[i-1])
{
/* continue */
}
else if (cards[i] == cards[i-1])
{
return 0;
}
else
{
return no_doubles_unsorted (cards, n);
}
}
return 1;
}
#include "tarot_private.h"
static int
has_petit (const TarotCard *cards,
unsigned int n)
{
unsigned int i = 0;
for (i = 0; i < n; ++i)
{
if (cards[i] == TAROT_PETIT)
{
return 1;
}
}
return 0;
}
static int
has_another_trump_or_excuse (const TarotCard *cards,
unsigned int n)
{
unsigned int i = 0;
for (i = 0; i < n; ++i)
{
if (cards[i] > TAROT_PETIT)
{
return 1;
}
}
return 0;
}
int
_tarot_no_petit_sec (const TarotCard *cards,
unsigned int n)
{
return (!has_petit (cards, n)
|| has_another_trump_or_excuse (cards, n));
}
#include <config.h>
#include <stdlib.h>
#include <assert.h>
#include "tarot.h"
#include "gettext.h"
static void
check ()
{
TarotGame *game = NULL;
char *buffer = NULL;
size_t sz = 0;
sz = tarot_game_init (5, 1, 0, NULL);
buffer = malloc (sz);
assert (buffer);
assert (tarot_game_init (5, 1, sz, buffer) == sz);
game = (TarotGame *) buffer;
/* First check: there are not enough cards */
{
TarotCard not_enough[] =
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
assert (tarot_game_check_deal_one (game, 14, not_enough) == 0);
}
/* Second check: there are too many cards */
{
TarotCard too_many[] =
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
assert (tarot_game_check_deal_one (game, 16, too_many) == 0);
}
/* There is an obvious double */
{
TarotCard double_zero[] =
{0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
assert (tarot_game_check_deal_one (game, 15, double_zero) == 0);
}
/* There is a double but the cards are not sorted */
{
TarotCard double_zero[] =
{0, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
assert (tarot_game_check_deal_one (game, 15, double_zero) == 0);
}
/* There is a double but the cards are not sorted, other */
{
TarotCard double_zero[] =
{0, 0, 3, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
assert (tarot_game_check_deal_one (game, 15, double_zero) == 0);
}
/* There is a petit sec, with sorted cards */
{
TarotCard petit_sec[] =
{0, 1, 3, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 56};
assert (tarot_game_check_deal_one (game, 15, petit_sec) == 0);
}
/* There is a petit sec, but the cards are not sorted */
{
TarotCard petit_sec[] =
{0, 1, 3, 2, 56, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
assert (tarot_game_check_deal_one (game, 15, petit_sec) == 0);
}
/* OK (not petit sec since there is the excuse) */
{
TarotCard ok[] =
{0, 1, 3, 2, 56, 5, 6, 7, 8, 9, 77, 11, 12, 13, 14};
assert (tarot_game_check_deal_one (game, 15, ok) == 1);
}
free (buffer);
}
int
main ()
{
tarot_init ();
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
check ();
return 0;
}
......@@ -176,6 +176,8 @@ extern "C"
unsigned int i_trick, TarotPlayer p,
TarotHint * hint);
int tarot_game_check_deal_one (const TarotGame *game, unsigned int n, const TarotCard *cards);
#ifdef __cplusplus
}
#endif /* cplusplus */
......
#include "tarot_private.h"
int
tarot_game_check_deal_one (const TarotGame *game,
unsigned int n,
const TarotCard *cards)
{
unsigned int n_cards, n_dog;
_tarot_count_cards (game->n_players, &n_cards, &n_dog);
return (n_cards == n
&& _tarot_no_doubles (cards, n)
&& _tarot_no_petit_sec (cards, n));
}
......@@ -38,6 +38,10 @@ extern "C"
TarotNumber _tarot_strongest_trump (const TarotCard * cards,
unsigned int n);
int _tarot_no_doubles (const TarotCard *cards, unsigned int n);
int _tarot_no_petit_sec (const TarotCard *cards, unsigned int n);
struct TarotGame
{
unsigned int n_players;
......
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