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

Also compute the ideal call when computing the strongest player

parent cc8e45a9
Pipeline #172816 passed with stages
in 37 minutes and 38 seconds
......@@ -2605,15 +2605,19 @@ Allocate a fresh predictor that will always use the CNN.
Given the ML building blocks, we have some opportunities for a few
interesting applications.
#+attr_texinfo: :options {TarotPlayer} tarot_features_strongest_player (size_t @var{nplayers}, int @var{withcall}, size_t @var{ncards}, const TarotPlayer *@var{owners}, double *@var{confidence})
#+attr_texinfo: :options {TarotPlayer} tarot_features_strongest_player (size_t @var{nplayers}, int @var{withcall}, size_t @var{ncards}, const TarotPlayer *@var{owners}, double *@var{confidence}, TarotCard *@var{call})
#+begin_deftypefun
Given a deal for all players as the 78-player /owners/ array (of size
/ncards/), find the strongest player in the game and set /confidence/
to a real value which is positive if the AI would actually take, and
negative if no player would take.
negative if no player would take. If /withcall/ is true, then /call/
is set to the best card the AI taker would call.
If the deal has a /petit sec/, then this function will return any
player while setting /confidence/ to a low value.
This function is especially useful for determining the duplicaté
options.
#+end_deftypefun
* GNU Free Documentation License
:PROPERTIES:
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: tarot 0.4.2.83-ebdc-dirty\n"
"Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n"
"POT-Creation-Date: 2019-09-30 23:53+0200\n"
"POT-Creation-Date: 2019-10-06 12:00+0200\n"
"PO-Revision-Date: 2019-09-14 13:19+0200\n"
"Last-Translator: Vivien Kraus <vivien@planete-kraus.eu>\n"
"Language-Team: French\n"
......@@ -560,12 +560,12 @@ msgstr "Copyright © 2019 Vivien Kraus"
msgid "Error: could not log the game: %s\n"
msgstr "Erreur : impossible d'enregistrer la partie : %s\n"
#: src/tarot-app/gui/window.vala:377
#: src/tarot-app/gui/window.vala:387
#, c-format
msgid "Error: could not set up the game: %s\n"
msgstr "Erreur : impossible de mettre en place la partie : %s\n"
#: src/tarot-app/gui/window.vala:497
#: src/tarot-app/gui/window.vala:508
#, c-format
msgid "Error: could not run explorer.exe: %s\n"
msgstr "Erreur : impossible d'exécuter explorer.exe : %s\n"
......
......@@ -316,10 +316,10 @@ tarot_features_strongest_player (size_t n_players,
int with_call,
size_t n_cards,
const TarotPlayer * owners,
double *confidence)
double *confidence, TarotCard * call)
{
return features_strongest_player (n_players, with_call, n_cards, owners,
confidence);
confidence, call);
}
size_t
......
......@@ -386,12 +386,14 @@ extern "C"
* @with_call: (type boolean):
* @owners: (array length=n_cards):
* @confidence: (out):
* @call: (out):
*/
TarotPlayer tarot_features_strongest_player (size_t n_players,
int with_call,
size_t n_cards,
const TarotPlayer *owners,
double *confidence);
double *confidence,
TarotCard *call);
struct TarotPredictor;
typedef struct TarotPredictor TarotPredictor;
......
......@@ -132,7 +132,8 @@ extern "C"
int with_call,
size_t n_cards,
const TarotPlayer * owners,
double *confidence);
double *confidence,
TarotCard * call);
static size_t predictor_construct (size_t max_mem, char *mem,
size_t *alignment);
......
......@@ -2103,11 +2103,62 @@ features_strongest_player_aux (size_t n_players,
return features_strongest_player_try_bid (&predictor);
}
static int predictor_select_call (int cnn, const TarotGame * game,
TarotCard * call, double *score);
static inline TarotCard
features_strongest_call (size_t n_players, size_t n_cards,
const TarotPlayer * owners, TarotPlayer taker)
{
/* Anything may fail in this function if there is a petit sec. We
* need to fail gracefully. */
TarotGame game;
TarotCard call;
double score;
TarotGameEvent setup;
size_t i;
game_initialize (&game, n_players, 1);
setup.t = TAROT_SETUP_EVENT;
setup.u.setup.n_players = n_players;
setup.u.setup.with_call = 1;
if (game_add_event (&game, &setup) != TAROT_GAME_OK)
{
return ((TarotCard) (-1));
}
if (game_duplicate_set_deal (&game, n_cards, owners) != TAROT_GAME_OK)
{
/* Anyway, the call event will never be evaluated. */
return ((TarotCard) (-1));
}
if (game_duplicate_set_taker (&game, taker) != TAROT_GAME_OK)
{
/* Since we have dealt, we cannot fail here */
assert (0);
}
for (i = 0; i < n_players; i++)
{
TarotGameEvent decl;
decl.t = TAROT_DECL_EVENT;
decl.u.decl = 0;
/* This one cannot fail */
if (game_add_event (&game, &decl) != TAROT_GAME_OK)
{
assert (0);
}
}
if (predictor_select_call (0, &game, &call, &score) != 0)
{
assert (0);
}
return call;
}
static inline TarotPlayer
features_strongest_player (size_t n_players,
int with_call,
size_t n_cards,
const TarotPlayer * owners, double *confidence)
const TarotPlayer * owners, double *confidence,
TarotCard * call)
{
TarotPlayer candidate;
TarotPlayer best = 0;
......@@ -2126,6 +2177,10 @@ features_strongest_player (size_t n_players,
}
}
*confidence = best_score;
if (with_call)
{
*call = features_strongest_call (n_players, n_cards, owners, best);
}
return best;
}
......
......@@ -307,22 +307,26 @@ namespace Tarot {
});
}
private Tarot.Player gen_strongest_player (size_t n_players, bool with_call, Tarot.GameEvent deal_all, out double confidence) {
private Tarot.Player gen_strongest_player (size_t n_players, bool with_call, Tarot.GameEvent deal_all, out double confidence, out Tarot.Card call) {
var owners = new Tarot.Player[0];
if (deal_all.get_deal_all_alloc (out owners) != Tarot.GameEvent.OK) {
GLib.Process.abort ();
}
double my_confidence = 0;
Tarot.Player taker = Tarot.features_strongest_player (n_players, with_call, owners, out my_confidence);
Tarot.Card my_call = (Tarot.Card) (-1);
Tarot.Player taker = Tarot.features_strongest_player (n_players, with_call, owners, out my_confidence, out my_call);
confidence = my_confidence;
call = my_call;
return taker;
}
private Tarot.Player gen_strongest_player_from_seed (size_t n_players, bool with_call, char[] seed, out Tarot.GameEvent deal_all, out double confidence) {
private Tarot.Player gen_strongest_player_from_seed (size_t n_players, bool with_call, char[] seed, out Tarot.GameEvent deal_all, out double confidence, out Tarot.Card call) {
deal_all = new Tarot.GameEvent.alloc_deal_all_random (n_players, seed);
double my_confidence = 0;
Tarot.Player taker = gen_strongest_player (n_players, with_call, deal_all, out my_confidence);
Tarot.Card my_call = (Tarot.Card) (-1);
Tarot.Player taker = gen_strongest_player (n_players, with_call, deal_all, out my_confidence, out my_call);
confidence = my_confidence;
call = my_call;
return taker;
}
......@@ -339,34 +343,40 @@ namespace Tarot {
return ret;
}
private Tarot.Player gen_strongest_player_many_tries (size_t n_tries, size_t n_players, bool with_call, char[] seed, out Tarot.GameEvent deal_all, out double confidence) {
private Tarot.Player gen_strongest_player_many_tries (size_t n_tries, size_t n_players, bool with_call, char[] seed, out Tarot.GameEvent deal_all, out double confidence, out Tarot.Card call) {
Tarot.GameEvent best_deal;
double best_confidence;
Tarot.Player best_taker = gen_strongest_player_from_seed (n_players, with_call, divert_seed (seed, 0), out best_deal, out best_confidence);
Tarot.Card best_call;
Tarot.Player best_taker = gen_strongest_player_from_seed (n_players, with_call, divert_seed (seed, 0), out best_deal, out best_confidence, out best_call);
for (size_t i = 1; i < n_tries; i++) {
Tarot.GameEvent candidate_deal;
double candidate_confidence;
Tarot.Player candidate_taker = gen_strongest_player_from_seed (n_players, with_call, divert_seed (seed, i), out candidate_deal, out candidate_confidence);
Tarot.Card candidate_call;
Tarot.Player candidate_taker = gen_strongest_player_from_seed (n_players, with_call, divert_seed (seed, i), out candidate_deal, out candidate_confidence, out candidate_call);
if (candidate_confidence > best_confidence) {
best_deal = candidate_deal;
best_confidence = candidate_confidence;
best_taker = candidate_taker;
best_call = candidate_call;
}
}
deal_all = best_deal;
confidence = best_confidence;
call = best_call;
return best_taker;
}
private Tarot.GameEvent interesting_deal_all (size_t n_players, bool with_call, string seed, out Tarot.Player taker) {
private Tarot.GameEvent interesting_deal_all (size_t n_players, bool with_call, string seed, out Tarot.Player taker, out Tarot.Card call) {
Tarot.GameEvent deal_all;
double confidence;
double confidence = 0;
Tarot.Card my_call = (Tarot.Card) (-1);
long seed_length = seed.length;
var seed_bytes = new char[seed_length];
for (long i = 0; i < seed_length; i++) {
seed_bytes[i] = seed[i];
}
taker = gen_strongest_player_many_tries (20, n_players, with_call, seed_bytes, out deal_all, out confidence);
taker = gen_strongest_player_many_tries (20, n_players, with_call, seed_bytes, out deal_all, out confidence, out my_call);
call = my_call;
return deal_all;
}
......@@ -378,7 +388,8 @@ namespace Tarot {
GLib.Process.exit (1);
}
Tarot.Player taker;
Tarot.GameEvent deal = interesting_deal_all (n_players, with_call, seed, out taker);
Tarot.Card call;
Tarot.GameEvent deal = interesting_deal_all (n_players, with_call, seed, out taker, out call);
// 1/2 chance to be the taker, 1/2 to be a defendant
if (prng.boolean ()) {
myself = prng.int_range (0, (int32) 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