summaryrefslogtreecommitdiff
path: root/digital/io-hub/src/guybrush/strat.c
diff options
context:
space:
mode:
Diffstat (limited to 'digital/io-hub/src/guybrush/strat.c')
-rw-r--r--digital/io-hub/src/guybrush/strat.c152
1 files changed, 138 insertions, 14 deletions
diff --git a/digital/io-hub/src/guybrush/strat.c b/digital/io-hub/src/guybrush/strat.c
index 0c7de8f6..fe029f4d 100644
--- a/digital/io-hub/src/guybrush/strat.c
+++ b/digital/io-hub/src/guybrush/strat.c
@@ -25,11 +25,13 @@
#include "common.h"
#include "strat.h"
+#include "contact.h"
#include "playground_2012.h"
#include "bot.h"
#include "path.h"
#include "asserv.h"
+#include "chrono.h"
/*
* This file implements strategic decisions.
@@ -37,6 +39,11 @@
enum
{
+ /** Unloading area. */
+ STRAT_PLACE_CAPTAIN0,
+ STRAT_PLACE_CAPTAIN1,
+ STRAT_PLACE_HOLD0,
+ STRAT_PLACE_HOLD1,
/** The four collecting places for totems. */
STRAT_PLACE_TOTEM0,
STRAT_PLACE_TOTEM1,
@@ -48,7 +55,9 @@ enum
STRAT_PLACE_BOTTLE2,
STRAT_PLACE_BOTTLE3,
/** Number of places, should be last. */
- STRAT_PLACE_NB
+ STRAT_PLACE_NB,
+ /** Number of unloading area. */
+ STRAT_PLACE_UNLOAD_NB = 4,
};
/** Place static information. */
@@ -57,23 +66,35 @@ struct strat_place_t
/** Collect position. */
vect_t pos;
/** Static score. */
- uint8_t score;
+ int16_t score;
/** Decision code. */
uint8_t decision;
};
static const struct strat_place_t strat_place[STRAT_PLACE_NB] = {
+ { { PG_CAPTAIN_ROOM_LENGTH_MM,
+ PG_LENGTH - PG_CAPTAIN_ROOM_LENGTH_MM / 2 },
+ 0, STRAT_DECISION_UNLOAD },
+ { { PG_MIRROR_X (PG_CAPTAIN_ROOM_LENGTH_MM),
+ PG_LENGTH - PG_CAPTAIN_ROOM_LENGTH_MM / 2 },
+ 0, STRAT_DECISION_UNLOAD },
+ { { (PG_CAPTAIN_ROOM_WIDTH_MM + PG_HOLD_NORTH_X) / 2,
+ (PG_LENGTH - PG_CAPTAIN_ROOM_LENGTH_MM + PG_HOLD_NORTH_Y) / 2 - 75 },
+ 1500, STRAT_DECISION_UNLOAD },
+ { { PG_MIRROR_X ((PG_CAPTAIN_ROOM_WIDTH_MM + PG_HOLD_NORTH_X) / 2),
+ (PG_LENGTH - PG_CAPTAIN_ROOM_LENGTH_MM + PG_HOLD_NORTH_Y) / 2 - 75 },
+ 1500, STRAT_DECISION_UNLOAD },
{ { PG_WIDTH / 2 - PG_TOTEM_X_OFFSET_MM,
- PG_LENGTH / 2 + PATH_PEANUT_CLEAR_MM }, 100, STRAT_DECISION_TOTEM },
+ PG_LENGTH / 2 + PATH_PEANUT_CLEAR_MM }, 1000, STRAT_DECISION_TOTEM },
{ { PG_WIDTH / 2 + PG_TOTEM_X_OFFSET_MM,
- PG_LENGTH / 2 + PATH_PEANUT_CLEAR_MM }, 100, STRAT_DECISION_TOTEM },
+ PG_LENGTH / 2 + PATH_PEANUT_CLEAR_MM }, 1000, STRAT_DECISION_TOTEM },
{ { PG_WIDTH / 2 - PG_TOTEM_X_OFFSET_MM,
PG_LENGTH / 2 - PATH_PEANUT_CLEAR_MM }, 100, STRAT_DECISION_TOTEM },
{ { PG_WIDTH / 2 + PG_TOTEM_X_OFFSET_MM,
PG_LENGTH / 2 - PATH_PEANUT_CLEAR_MM }, 100, STRAT_DECISION_TOTEM },
- { { PG_BOTTLE0_X, BOT_SIZE_RADIUS + 70 }, 100, STRAT_DECISION_BOTTLE },
- { { PG_BOTTLE1_X, BOT_SIZE_RADIUS + 70 }, 100, STRAT_DECISION_BOTTLE },
- { { PG_BOTTLE2_X, BOT_SIZE_RADIUS + 70 }, 100, STRAT_DECISION_BOTTLE },
- { { PG_BOTTLE3_X, BOT_SIZE_RADIUS + 70 }, 100, STRAT_DECISION_BOTTLE },
+ { { PG_BOTTLE0_X, BOT_SIZE_RADIUS + 70 }, 1000, STRAT_DECISION_BOTTLE },
+ { { PG_BOTTLE1_X, BOT_SIZE_RADIUS + 70 }, 1000, STRAT_DECISION_BOTTLE },
+ { { PG_BOTTLE2_X, BOT_SIZE_RADIUS + 70 }, 1000, STRAT_DECISION_BOTTLE },
+ { { PG_BOTTLE3_X, BOT_SIZE_RADIUS + 70 }, 1000, STRAT_DECISION_BOTTLE },
};
/** Place dynamic information. */
@@ -92,8 +113,16 @@ struct strat_t
uint8_t last_decision;
/** Place of last decision. */
uint8_t last_place;
+ /** Decision is prepared in advance. */
+ uint8_t prepared;
+ /** Prepared position. */
+ vect_t prepared_pos;
/** Robot content estimation. */
uint8_t load;
+ /** Number of time the robot unloaded. */
+ uint8_t unload_nb;
+ /** Upper clamp is dead. */
+ uint8_t upper_clamp_dead;
/** Places information. */
struct strat_place_dyn_t place[STRAT_PLACE_NB];
};
@@ -108,11 +137,15 @@ strat_init (void)
strat.place[i].valid = 1;
if (team_color)
{
+ strat.place[STRAT_PLACE_CAPTAIN1].valid = 0;
+ strat.place[STRAT_PLACE_HOLD1].valid = 0;
strat.place[STRAT_PLACE_BOTTLE1].valid = 0;
strat.place[STRAT_PLACE_BOTTLE3].valid = 0;
}
else
{
+ strat.place[STRAT_PLACE_CAPTAIN0].valid = 0;
+ strat.place[STRAT_PLACE_HOLD0].valid = 0;
strat.place[STRAT_PLACE_BOTTLE0].valid = 0;
strat.place[STRAT_PLACE_BOTTLE2].valid = 0;
}
@@ -152,7 +185,39 @@ strat_place_score (uint8_t i)
int32_t position_score = strat_position_score (&strat_place[i].pos);
if (position_score == -1)
return -1;
- return 10000 - position_score;
+ int32_t score = 10000ll - position_score + strat_place[i].score
+ - 100ll * strat.place[i].fail_nb;
+ if (team_color)
+ {
+ if (i == STRAT_PLACE_TOTEM1 || i == STRAT_PLACE_TOTEM3)
+ score -= 1500;
+ }
+ else
+ {
+ if (i == STRAT_PLACE_TOTEM0 || i == STRAT_PLACE_TOTEM2)
+ score -= 1500;
+ }
+ if (i < STRAT_PLACE_UNLOAD_NB)
+ {
+ if (strat.load && chrono_remaining_time () < 7000)
+ score += strat.load * 4000;
+ else if (strat.load && chrono_remaining_time () < 15000)
+ score += strat.load * 2000;
+ else if (strat.load > 3)
+ score += 7000;
+ else
+ score -= 7000;
+ }
+ if (strat_place[i].decision == STRAT_DECISION_TOTEM
+ && chrono_remaining_time () < 20000)
+ score -= 2000;
+ if (strat.upper_clamp_dead
+ && strat_place[i].decision == STRAT_DECISION_TOTEM)
+ score -= 3000;
+ if (strat.load <= 4 && strat.unload_nb != 0
+ && (i == STRAT_PLACE_CAPTAIN0 || i == STRAT_PLACE_CAPTAIN1))
+ score += 2000;
+ return score;
}
uint8_t
@@ -161,13 +226,14 @@ strat_decision (vect_t *pos)
int32_t best_score = -1;
uint8_t best_place = 0;
uint8_t i;
- if (strat.load > 1)
+ /* If decision was prepared, use it now. */
+ if (strat.prepared)
{
- strat.last_decision = STRAT_DECISION_UNLOAD;
- pos->x = PG_X (BOT_SIZE_RADIUS + 30);
- pos->y = PG_Y (PG_LENGTH / 2);
+ strat.prepared = 0;
+ *pos = strat.prepared_pos;
return strat.last_decision;
}
+ /* Else compute the best decision. */
for (i = 0; i < STRAT_PLACE_NB; i++)
{
int32_t score = strat_place_score (i);
@@ -189,18 +255,31 @@ strat_decision (vect_t *pos)
}
void
+strat_prepare (void)
+{
+ strat_decision (&strat.prepared_pos);
+ strat.prepared = 1;
+}
+
+void
strat_success (void)
{
switch (strat.last_decision)
{
case STRAT_DECISION_TOTEM:
- strat.load++;
+ strat.load += 4;
/* no break; */
case STRAT_DECISION_BOTTLE:
strat.place[strat.last_place].valid = 0;
break;
case STRAT_DECISION_UNLOAD:
strat.load = 0;
+ strat.unload_nb++;
+ if (strat.last_place == STRAT_PLACE_CAPTAIN0
+ || strat.last_place == STRAT_PLACE_CAPTAIN1)
+ {
+ strat.place[strat.last_place].valid = 0;
+ }
break;
default:
assert (0);
@@ -221,3 +300,48 @@ strat_failure (void)
}
}
+void
+strat_bad_failure (void)
+{
+ switch (strat.last_decision)
+ {
+ default:
+ if (strat.place[strat.last_place].fail_nb < 256 - 20)
+ strat.place[strat.last_place].fail_nb += 20;
+ break;
+ case STRAT_DECISION_UNLOAD:
+ break;
+ }
+}
+
+void
+strat_giveup (void)
+{
+ switch (strat.last_decision)
+ {
+ default:
+ strat.place[strat.last_place].valid = 0;
+ break;
+ case STRAT_DECISION_UNLOAD:
+ assert (0);
+ }
+}
+
+void
+strat_coin_taken (void)
+{
+ strat.load++;
+}
+
+void
+strat_clamp_dead (void)
+{
+ /* TODO */
+}
+
+void
+strat_upper_clamp_dead (void)
+{
+ strat.upper_clamp_dead = 1;
+}
+