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:
parent
2588b96f51
commit
5e5b383977
2 changed files with 33 additions and 19 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue