Commit dd23c85a authored by Vivien Kraus's avatar Vivien Kraus
Browse files

Fix the initialization of game events

parent 3e5c1f2d
......@@ -1390,22 +1390,8 @@ Return the data associated to the current position of /iterator/, and
advance /iterator/ to the next position.
#+end_deftypefun
#+attr_texinfo: :options {size_t} tarot_game_construct (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment})
#+begin_deftypefun
#+texinfo: @deftypefunx {size_t} tarot_game_iterator_construct (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, const TarotGame *@var{game})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_setup (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, size_t @var{n_players}, int @var{with_call})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_deal (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, TarotPlayer @var{myself}, size_t @var{n_cards}, const TarotCard *@var{cards})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_deal_all (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, size_t @var{n_owners}, const TarotPlayer *@var{owners})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_deal_all_random (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, size_t @var{n_players}, size_t @var{seed_size}, const void *@var{seed})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_bid (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, TarotBid @var{bid})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_decl (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, int @var{slam})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_call (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, TarotCard @var{call})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_dog (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, size_t @var{n_cards}, const TarotCard *@var{cards})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_discard (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, size_t @var{n_cards}, const TarotCard *@var{cards})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_handful (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, size_t @var{n_cards}, const TarotCard *@var{cards})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_card (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, TarotCard @var{card})
#+texinfo: @deftypefunx {size_t} tarot_game_event_construct_copy (size_t @var{maxmem}, char *@var{mem}, size_t *@var{alignment}, const TarotGameEvent *@var{event})
#+texinfo: @deftypefunx {size_t} tarot_counter_construct (size_t @var{maxmem}, char *@var{memout}, size_t *@var{alignment})
#+attr_texinfo: :options {size_t} tarot_counter_construct (size_t @var{maxmem}, char *@var{memout}, size_t *@var{alignment})
#+begin_deftypefun
If you want to control how memory is allocated, because you have a
very good specific memory allocator you want to use, then you will not
be satisfied by the =tarot_*_alloc= / =tarot_*_dup= family of
......
......@@ -482,6 +482,14 @@ ai_strongest_player (TarotAi * ai, size_t n_players, int with_call,
return taker;
}
static inline void
ai_save_event (TarotAi * ai, const TarotGameEvent * event)
{
event_init_copy (&(ai->best_event), event,
sizeof (ai->event_data) / sizeof (ai->event_data[0]),
ai->event_data);
}
static inline void
ai_best_consider_bids (TarotAi * ai, const TarotGame * state,
TarotBid minimum)
......@@ -500,8 +508,7 @@ ai_best_consider_bids (TarotAi * ai, const TarotGame * state,
}
for (i = 0; i < n; i++)
{
events[i].n = 0;
event_set_bid (&(events[i]), candidates[i]);
event_init_bid (&(events[i]), candidates[i]);
pointers[i] = &(events[i]);
}
ai_eval (ai, state, n, pointers, 0, 5, scores);
......@@ -509,7 +516,7 @@ ai_best_consider_bids (TarotAi * ai, const TarotGame * state,
{
if (ai->best_score == -DBL_MAX || scores[i] > ai->best_score)
{
event_copy (&(ai->best_event), &(events[i]));
ai_save_event (ai, &(events[i]));
ai->best_score = scores[i];
}
}
......@@ -531,8 +538,7 @@ ai_best_consider_decls (TarotAi * ai, const TarotGame * state, int allowed)
}
for (i = 0; i < n; i++)
{
events[i].n = 0;
event_set_decl (&(events[i]), candidates[i]);
event_init_decl (&(events[i]), candidates[i]);
pointers[i] = &(events[i]);
}
ai_eval (ai, state, n, pointers, 0, 2, scores);
......@@ -540,7 +546,7 @@ ai_best_consider_decls (TarotAi * ai, const TarotGame * state, int allowed)
{
if (ai->best_score == -DBL_MAX || scores[i] > ai->best_score)
{
event_copy (&(ai->best_event), &(events[i]));
ai_save_event (ai, &(events[i]));
ai->best_score = scores[i];
}
}
......@@ -573,8 +579,7 @@ ai_best_consider_calls (TarotAi * ai, const TarotGame * state,
}
for (i = 0; i < n; i++)
{
events[i].n = 0;
event_set_call (&(events[i]), candidates[i]);
event_init_call (&(events[i]), candidates[i]);
pointers[i] = &(events[i]);
}
ai_eval (ai, state, n, pointers, 0, 16, scores);
......@@ -582,7 +587,7 @@ ai_best_consider_calls (TarotAi * ai, const TarotGame * state,
{
if (ai->best_score == -DBL_MAX || scores[i] > ai->best_score)
{
event_copy (&(ai->best_event), &(events[i]));
ai_save_event (ai, &(events[i]));
ai->best_score = scores[i];
}
}
......@@ -593,7 +598,8 @@ ai_best_consider_discards_draw (struct yarrow256_ctx *prng, size_t n_total,
size_t n_prio, const TarotCard * prio,
size_t n_additional,
const TarotCard * additional,
TarotGameEvent * e)
TarotGameEvent * e,
size_t n_data, unsigned int *data)
{
TarotCard selected[6];
size_t n_selected = 0;
......@@ -622,7 +628,7 @@ ai_best_consider_discards_draw (struct yarrow256_ctx *prng, size_t n_total,
set[position] = set[--n_set];
selected[n_selected] = c;
}
event_set_discard (e, n_selected, selected);
event_init_discard (e, n_selected, selected, n_data, data);
}
static inline void
......@@ -630,7 +636,8 @@ ai_best_consider_discards_draw_many (size_t n_total, size_t n_prio,
const TarotCard * prio,
size_t n_additional,
const TarotCard * additional,
size_t n_draws, TarotGameEvent ** draws)
size_t n_draws, TarotGameEvent ** draws,
size_t *n_data, unsigned int **data)
{
unsigned char seed[78] = { 0 };
size_t i;
......@@ -648,7 +655,8 @@ ai_best_consider_discards_draw_many (size_t n_total, size_t n_prio,
for (i = 0; i < n_draws; i++)
{
ai_best_consider_discards_draw (&generator, n_total, n_prio, prio,
n_additional, additional, draws[i]);
n_additional, additional, draws[i],
n_data[i], data[i]);
}
}
......@@ -660,23 +668,26 @@ ai_best_consider_discards (TarotAi * ai, const TarotGame * state,
{
TarotGameEvent events[20];
TarotGameEvent *pointers[20];
unsigned int event_data[20][6];
size_t n_data[20];
unsigned int event_data[20 * 6];
double scores[20];
size_t i;
unsigned int *event_data_pp[20];
for (i = 0; i < 20; i++)
{
events[i].n = 6;
events[i].data = event_data[i];
n_data[i] = 6;
event_data_pp[i] = &(event_data[i * 6]);
pointers[i] = &(events[i]);
}
ai_best_consider_discards_draw_many (n_total, n_prio, prio, n_additional,
additional, 20, pointers);
additional, 20, pointers, n_data,
event_data_pp);
ai_eval (ai, state, 20, pointers, 0, 20, scores);
for (i = 0; i < 20; i++)
{
if (ai->best_score == -DBL_MAX || scores[i] > ai->best_score)
{
event_copy (&(ai->best_event), &(events[i]));
ai_save_event (ai, &(events[i]));
ai->best_score = scores[i];
}
}
......@@ -695,7 +706,7 @@ ai_best_consider_cards (TarotAi * ai, const TarotGame * state, size_t n_cards,
for (i = 0; i < n_cards; i++)
{
candidates[i] = playable[i];
event_set_card (&(events[i]), candidates[i]);
event_init_card (&(events[i]), candidates[i]);
pointers[i] = &(events[i]);
}
ai_eval (ai, state, n_cards, pointers, 0, 78, scores);
......@@ -703,7 +714,7 @@ ai_best_consider_cards (TarotAi * ai, const TarotGame * state, size_t n_cards,
{
if (ai->best_score == -DBL_MAX || scores[i] > ai->best_score)
{
event_copy (&(ai->best_event), &(events[i]));
ai_save_event (ai, &(events[i]));
ai->best_score = scores[i];
}
}
......
/* tarot implements the rules of the tarot game
* Copyright (C) 2017, 2018, 2019 Vivien Kraus
* Copyright (C) 2017, 2018, 2019, 2020 Vivien Kraus
*
* 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
......@@ -32,323 +32,127 @@ tarot_game_event_type (const TarotGameEvent * event)
return event_type (event);
}
size_t
tarot_game_event_construct_setup (size_t max_mem, char *mem,
size_t *alignment, size_t n_players,
int with_call)
{
return event_construct_setup (max_mem, mem, alignment, n_players,
with_call);
}
TarotGameEvent *
tarot_game_event_alloc_setup (size_t n_players, int with_call)
{
size_t alignment;
size_t required = event_construct_setup (0, NULL, &alignment, n_players,
with_call);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused =
event_construct_setup (required, mem, &alignment, n_players, with_call);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_deal (size_t max_mem, char *mem, size_t *alignment,
TarotPlayer myself, size_t n_cards,
const TarotCard * cards)
{
return event_construct_deal (max_mem, mem, alignment, myself, n_cards,
cards);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
event_init_setup (ret, n_players, with_call);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_deal (TarotPlayer myself, size_t n_cards,
const TarotCard * cards)
{
size_t alignment;
size_t required =
event_construct_deal (0, NULL, &alignment, myself, n_cards,
cards);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused =
event_construct_deal (required, mem, &alignment, myself, n_cards, cards);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_deal_all (size_t max_mem, char *mem,
size_t *alignment, size_t n_owners,
const TarotPlayer * owners)
{
return event_construct_deal_all (max_mem, mem, alignment, n_owners, owners);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
unsigned int *data = xmalloc (n_cards * sizeof (unsigned int));
event_init_deal (ret, myself, n_cards, cards, n_cards, data);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_deal_all (size_t n_owners, const TarotPlayer * owners)
{
size_t alignment;
size_t required = event_construct_deal_all (0, NULL, &alignment, n_owners,
owners);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused =
event_construct_deal_all (required, mem, &alignment, n_owners, owners);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_deal_all_random (size_t max_mem, char *mem,
size_t *alignment,
size_t n_players,
size_t seed_size,
const void *seed)
{
return event_construct_deal_all_random (max_mem, mem, alignment, n_players,
seed_size, seed);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
unsigned int *data = xmalloc (n_owners * sizeof (unsigned int));
event_init_deal_all (ret, n_owners, owners, n_owners, data);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_deal_all_random (size_t n_players, size_t seed_size,
const void *seed)
{
size_t alignment;
size_t required = event_construct_deal_all_random (0, NULL, &alignment,
n_players, seed_size,
seed);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused =
event_construct_deal_all_random (required, mem, &alignment,
n_players, seed_size, seed);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_bid (size_t max_mem, char *mem, size_t *alignment,
TarotBid bid)
{
return event_construct_bid (max_mem, mem, alignment, bid);
const char *seed)
{
uint8_t *seed_u8 = xmalloc (seed_size * sizeof (uint8_t));
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
unsigned int *data = xmalloc (78 * sizeof (unsigned int));
memcpy (seed_u8, seed, seed_size);
event_init_deal_all_random (ret, n_players, seed_size, seed_u8, 78, data);
free (seed_u8);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_bid (TarotBid bid)
{
size_t alignment;
size_t required = event_construct_bid (0, NULL, &alignment, bid);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused = event_construct_bid (required, mem, &alignment, bid);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_decl (size_t max_mem, char *mem, size_t *alignment,
int decl)
{
return event_construct_decl (max_mem, mem, alignment, decl);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
event_init_bid (ret, bid);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_decl (int decl)
{
size_t alignment;
size_t required = event_construct_decl (0, NULL, &alignment, decl);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused = event_construct_decl (required, mem, &alignment, decl);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_call (size_t max_mem, char *mem, size_t *alignment,
TarotCard call)
{
return event_construct_call (max_mem, mem, alignment, call);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
event_init_decl (ret, decl);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_call (TarotCard call)
{
size_t alignment;
size_t required = event_construct_call (0, NULL, &alignment, call);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused = event_construct_call (required, mem, &alignment, call);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_dog (size_t max_mem, char *mem, size_t *alignment,
size_t n_cards, const TarotCard * cards)
{
return event_construct_dog (max_mem, mem, alignment, n_cards, cards);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
event_init_call (ret, call);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_dog (size_t n_cards, const TarotCard * cards)
{
size_t alignment;
size_t required = event_construct_dog (0, NULL, &alignment, n_cards, cards);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused = event_construct_dog (required, mem, &alignment, n_cards, cards);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_discard (size_t max_mem, char *mem,
size_t *alignment, size_t n_cards,
const TarotCard * cards)
{
return event_construct_discard (max_mem, mem, alignment, n_cards, cards);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
unsigned int *data = xmalloc (n_cards * sizeof (unsigned int));
event_init_dog (ret, n_cards, cards, n_cards, data);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_discard (size_t n_cards, const TarotCard * cards)
{
size_t alignment;
size_t required =
event_construct_discard (0, NULL, &alignment, n_cards, cards);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused =
event_construct_discard (required, mem, &alignment, n_cards, cards);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_handful (size_t max_mem, char *mem,
size_t *alignment, size_t n_cards,
const TarotCard * cards)
{
return event_construct_handful (max_mem, mem, alignment, n_cards, cards);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
unsigned int *data = xmalloc (n_cards * sizeof (unsigned int));
event_init_discard (ret, n_cards, cards, n_cards, data);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_handful (size_t n_cards, const TarotCard * cards)
{
size_t alignment;
size_t required =
event_construct_handful (0, NULL, &alignment, n_cards, cards);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused =
event_construct_handful (required, mem, &alignment, n_cards, cards);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_card (size_t max_mem, char *mem, size_t *alignment,
TarotCard card)
{
return event_construct_card (max_mem, mem, alignment, card);
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
unsigned int *data = xmalloc (n_cards * sizeof (unsigned int));
event_init_handful (ret, n_cards, cards, n_cards, data);
return ret;
}
TarotGameEvent *
tarot_game_event_alloc_card (TarotCard card)
tarot_game_event_alloc_card (TarotCard call)
{
size_t alignment;
size_t required = event_construct_card (0, NULL, &alignment, card);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused = event_construct_card (required, mem, &alignment, card);
assert (unused == required);
(void) unused;
return mem;
}
size_t
tarot_game_event_construct_copy (size_t max_mem, char *mem, size_t *alignment,
const TarotGameEvent * event)
{
switch (event_type (event))
{
case TAROT_SETUP_EVENT:
return event_construct_setup (max_mem, mem, alignment,
event->u.setup.n_players,
event->u.setup.with_call);
case TAROT_DEAL_EVENT:
return event_construct_deal (max_mem, mem, alignment, event->u.deal,
event->n, event->data);
case TAROT_DEAL_ALL_EVENT:
return event_construct_deal_all (max_mem, mem, alignment, event->n,
event->data);
case TAROT_BID_EVENT:
return event_construct_bid (max_mem, mem, alignment, event->u.bid);
case TAROT_DECL_EVENT:
return event_construct_decl (max_mem, mem, alignment, event->u.decl);
case TAROT_CALL_EVENT:
return event_construct_call (max_mem, mem, alignment, event->u.call);
case TAROT_DOG_EVENT:
return event_construct_dog (max_mem, mem, alignment, event->n,
event->data);
case TAROT_DISCARD_EVENT:
return event_construct_discard (max_mem, mem, alignment, event->n,
event->data);
case TAROT_HANDFUL_EVENT:
return event_construct_handful (max_mem, mem, alignment, event->n,
event->data);
case TAROT_CARD_EVENT:
return event_construct_card (max_mem, mem, alignment, event->u.card);
default:
break;
}
return 0;
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
event_init_card (ret, call);
return ret;
}
TarotGameEvent *
tarot_game_event_dup (const TarotGameEvent * source)
{
size_t alignment;
size_t required =
tarot_game_event_construct_copy (0, NULL, &alignment, source);
size_t unused;
void *mem = xmalloc (required);
assert (alignment >= 1 && alignment <= alignof (max_align_t));
unused =
tarot_game_event_construct_copy (required, mem, &alignment, source);
assert (unused == required);
(void) unused;
return mem;
TarotGameEvent *ret = xmalloc (sizeof (TarotGameEvent));
size_t n_data;
unsigned int *data = NULL;
event_get_data (source, &n_data);
if (n_data != 0)
{
data = xmalloc (n_data * sizeof (unsigned int));
}
event_init_copy (ret, source, n_data, data);
return ret;
}
void
tarot_game_event_free (TarotGameEvent * game_event)
{
if (game_event != NULL)
{
free (game_event->data);
}
free (game_event);
}
......
/* tarot implements the rules of the tarot game
* Copyright (C) 2018, 2019 Vivien Kraus
* Copyright (C) 2018, 2019, 2020 Vivien Kraus
*
* 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
......@@ -62,22 +62,6 @@ extern "C"
*/
TarotGameEventT tarot_game_event_type (const TarotGameEvent * event);
/**
* tarot_game_event_construct_setup:
* @max_mem: the number of bytes available. Pass 0 to query the
* necessary size and alignment.
* @mem_out: (array length=max_mem): the memory location. Either
* @max_mem is larger to the required size, or mem is properly
* aligned.
* @alignment: (out): the required alignemnt for an event.
* @with_call: (type boolean):
* Returns: the required number of bytes in @mem.
*/
size_t tarot_game_event_construct_setup (size_t max_mem,
char *mem_out,
size_t *alignment,
size_t n_players, int with_call);
/**
* tarot_game_event_alloc_setup: (constructor)
* @with_call: (type boolean):
......@@ -85,19 +69,6 @@ extern "C"
TarotGameEvent *tarot_game_event_alloc_setup (size_t n_players,