Fix completely unrealistic "touched" calculation with almost-correct one.

Fix bug in wesnoth-attack-sim --check which caused it not to warn
about differences.
This commit is contained in:
Rusty Russell 2006-02-19 12:16:41 +00:00
parent 2588b96f51
commit 5e5b383977
2 changed files with 33 additions and 19 deletions

View file

@ -589,8 +589,6 @@ void combatant::fight(combatant &opp)
slows_ && !opp.slowed_, opp.slows_ && !slowed_, hp_, opp.hp_,
summary, opp.summary);
untouched = 1.0;
opp.untouched = 1.0;
unsigned max_attacks = maximum(hit_chances_.size(),
opp.hit_chances_.size());
@ -604,14 +602,12 @@ void combatant::fight(combatant &opp)
m.receive_blow_b(damage_, hit_chances_[i],
slows_ && !opp.slowed_, drains_);
m.dump();
opp.untouched *= (1 - hit_chances_[i]);
}
if (i < opp.hit_chances_.size()) {
debug(("B strikes\n"));
m.receive_blow_a(opp.damage_, opp.hit_chances_[i],
opp.slows_ && !slowed_, opp.drains_);
m.dump();
untouched *= (1 - opp.hit_chances_[i]);
}
}
@ -634,6 +630,10 @@ void combatant::fight(combatant &opp)
for (i = 0; i < opp.hp_dist.size(); i++)
opp.hp_dist[i] = opp.summary[0][i] + opp.summary[1][i];
}
// FIXME: This is approximate: we could drain, then get hit.
untouched = hp_dist[hp_];
opp.untouched = opp.hp_dist[opp.hp_];
}
};
@ -706,17 +706,14 @@ static void run(unsigned specific_battle)
if (i == k || j == k)
continue;
battle++;
if (battle < specific_battle)
if (specific_battle && battle != specific_battle)
continue;
u[j]->fight(*u[i]);
untouched = u[i]->untouched;
// We need this here, because swarm means out num hits
// can change.
u[i]->set_effectiveness((i % 7) + 2, 0.3 + (i % 6)*0.1,
(i % 8) == 0);
u[k]->fight(*u[i]);
// We want cumulative untouched for defender.
u[i]->untouched *= untouched;
u[i]->print("Defender", battle);
u[j]->print("Attacker #1", battle);
u[k]->print("Attacker #2", battle);

View file

@ -124,10 +124,12 @@ static void calculate_attack(const struct unit *defender,
struct unit def = *defender;
def.slowed = false;
def.touched = false;
for (j = 0; j < num_attackers && def.hp; j++) {
struct unit att = *attackers[j];
att.slowed = false;
att.touched = false;
att.num_attacks = num_attacks(att.num_attacks,
att.max_hp, att.hp,
att.swarm);
@ -161,7 +163,15 @@ static void calculate_attack(const struct unit *defender,
/* Any battle we weren't in, we're unscathed. */
attacker_res[i][attackers[i]->hp]
+= (1.0*num_sims-battles)/num_sims;
attacker_touched[i] /= battles;
/* If this attacker wasn't in more than 1% of battles, don't
* pretend to know this probability. */
if (battles <= num_sims / 100)
attacker_touched[i] = -1.0;
else
/* FIXME: attack_prediction doesn't take into account
* that opponent might already be dead. */
attacker_touched[i] /= num_sims;
}
}
@ -242,14 +252,18 @@ static void draw_results(const double res[], const struct unit *u,
if (u->firststrike)
printf("firststrike,");
printf("maxhp=%u ", u->max_hp);
printf("touched:%.2f%% ", touched*100);
if (touched == -1)
printf("touched:unknown ");
else
printf("touched:%.2f%% ", touched*100);
for (i = 0; i < u->max_hp+1; i++)
printf(" %.2f", res[i]*100);
printf("\n");
}
static void compare_results(const double res[], const struct unit *u,
const char label[], unsigned battle, double def_untouched, FILE *f)
const char label[], unsigned battle,
double touched, FILE *f)
{
unsigned int i;
char line[128], cmp[128];
@ -277,12 +291,15 @@ static void compare_results(const double res[], const struct unit *u,
battle, strlen(cmp), line, cmp);
if (fscanf(f, " %lf", &val) != 1)
barf("Malformed touched: %s hp %u battle %u",
label, i, battle);
barf("Malformed untouched: %s battle %u",
label, battle);
if (abs(val - def_untouched)*100 > 1.0)
barf("Expected %f touched, got %f battle %u",
def_untouched, val, battle);
/* We *must* have result for defender and attacker 1. */
if (touched == -1)
assert(strcmp(label, "Attacker #2") == 0);
else if (abs((val - (1.0 - touched))*100) > 1.0)
printf("Warning: expected %f untouched, got %f battle %u %s\n",
1.0 - touched, val, battle, label);
for (i = 0; i < u->max_hp+1; i++) {
if (fscanf(f, " %lf", &val) != 1)
@ -373,11 +390,11 @@ static void check(const char *filename)
check_sum(j_result, u[j].max_hp);
check_sum(k_result, u[k].max_hp);
compare_results(i_result, &u[i], "Defender",
battle, 1 - i_touched, f);
battle, i_touched, f);
compare_results(j_result, &u[j], "Attacker #1",
battle, 1 - touched[0], f);
battle, touched[0], f);
compare_results(k_result, &u[k], "Attacker #2",
battle, 1 - touched[1], f);
battle, touched[1], f);
if ((battle % percent) == 0) {
printf(".");
fflush(stdout);