Commit 2d9f4c50 authored by Vivien Kraus's avatar Vivien Kraus
Browse files

Use the AI in the solo games

An AI is used to play for the other players, and at the end of the
game it learns the game of the main player.
parent b201329e
......@@ -392,6 +392,7 @@ extern "C"
{
TarotGame game;
TarotPlayer myself;
TarotAi *ai;
};
struct TarotPerceptron
......
......@@ -28,9 +28,6 @@
#include <nettle/yarrow.h>
#include <float.h>
#define TAROT_SOLO_USE_PREDICTOR 0
#define TAROT_SOLO_USE_PERCEPTRON 1
static inline void solo_advance (TarotSolo * dest);
static inline size_t
......@@ -43,6 +40,7 @@ solo_construct (size_t max_mem, char *mem, size_t *alignment)
TarotSolo *solo = (TarotSolo *) mem;
game_initialize (&(solo->game), 4, 0);
solo->myself = 0;
solo->ai = tarot_ai_alloc_perceptron ();
return max_mem;
}
return required;
......@@ -51,7 +49,10 @@ solo_construct (size_t max_mem, char *mem, size_t *alignment)
static inline void
solo_destruct (TarotSolo * solo)
{
(void) solo;
if (solo != NULL)
{
tarot_ai_free (solo->ai);
}
}
static inline void
......@@ -59,6 +60,8 @@ solo_copy (TarotSolo * dest, const TarotSolo * source)
{
game_copy (&(dest->game), &(source->game));
dest->myself = source->myself;
tarot_ai_free (dest->ai);
dest->ai = tarot_ai_dup (source->ai);
}
static inline void
......@@ -70,6 +73,8 @@ solo_copy_as (TarotSolo * dest, const TarotSolo * source, TarotPlayer who)
assert (0);
}
dest->myself = who;
tarot_ai_free (dest->ai);
dest->ai = tarot_ai_dup (source->ai);
solo_advance (dest);
}
......@@ -186,8 +191,9 @@ solo_setup_random (TarotSolo * solo, size_t n_players, int with_call,
candidate_owners[j] = ev.data[j];
}
candidate_taker =
features_strongest_player (n_players, with_call, 78, candidate_owners,
&candidate_prediction, &candidate_call);
tarot_ai_strongest_player (solo->ai, n_players, with_call, 78,
candidate_owners, &candidate_prediction,
&candidate_call);
if (candidate_prediction >= best_prediction)
{
for (j = 0; j < 78; j++)
......@@ -234,44 +240,22 @@ solo_advance (TarotSolo * solo)
int has_next = (game_get_next (&(solo->game), &next) == TAROT_GAME_OK);
TarotCard dog[6];
size_t n_dog;
int my_score;
size_t n_scores;
if (has_next && next == solo->myself)
{
return;
}
else if (has_next)
{
TarotGameEvent *chosen;
double predicted_score;
if (TAROT_SOLO_USE_PREDICTOR)
{
TarotPredictor predictor;
size_t unused;
size_t sz =
predictor_construct (sizeof (predictor), (char *) &predictor,
&unused);
(void) unused;
(void) sz;
assert (sz == sizeof (predictor));
predictor_set_game (&predictor, &(solo->game));
chosen =
tarot_game_event_dup (predictor_best
(&predictor, &predicted_score));
}
else if (TAROT_SOLO_USE_PERCEPTRON)
{
TarotPerceptron *perceptron = tarot_perceptron_static_default ();
chosen =
tarot_game_event_dup (tarot_perceptron_best
(perceptron, &(solo->game),
&predicted_score));
tarot_perceptron_free (perceptron);
}
const TarotGameEvent *chosen =
tarot_ai_best (solo->ai, &(solo->game), &predicted_score);
if (game_add_event (&(solo->game), chosen) != TAROT_GAME_OK)
{
assert (0);
}
(void) predicted_score;
tarot_game_event_free (chosen);
solo_advance (solo);
}
else if (game_can_autoreveal (&(solo->game), &n_dog, 0, 6, dog))
......@@ -293,6 +277,25 @@ solo_advance (TarotSolo * solo)
}
solo_advance (solo);
}
else
if (game_get_scores (&(solo->game), &n_scores, solo->myself, 1, &my_score)
== TAROT_GAME_OK)
{
TarotGameIterator i;
TarotGame rebuilt;
const TarotGameEvent *next_event;
game_initialize (&rebuilt, 4, 0);
game_iterator_setup (&i, &(solo->game));
while ((next_event = game_iterator_next_value (&i)) != NULL)
{
const double s = my_score;
tarot_ai_learn (solo->ai, &rebuilt, next_event, s);
if (game_add_event (&rebuilt, next_event) != TAROT_GAME_OK)
{
assert (0);
}
}
}
}
#include <tarot/game_private_impl.h>
......
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