Fix #3650: rare crash in attack prediction

The calculation for the probability to be slowed was incorrect if both
units had slow and neither of them was slowed. Calculating the sum of all
probabilities in the "not hit" row/column is a valid approach: however,
if the unit itself can slow and the other unit isn't already slowed, then
some of the "not hit" cases end up into a different plane.

Probabilities from that plane are now counted as well.
This commit is contained in:
Jyrki Vesterinen 2018-10-24 21:58:38 +03:00
parent fa12518f86
commit 1315ebf2a2

View file

@ -945,6 +945,10 @@ double prob_matrix::prob_of_zero(bool check_a, bool check_b) const
*/
double prob_matrix::row_sum(unsigned plane, unsigned row) const
{
if(!plane_used(plane)) {
return 0.0;
}
double sum = 0.0;
for(unsigned col : used_cols_[plane]) {
sum += val(plane, row, col);
@ -957,6 +961,10 @@ double prob_matrix::row_sum(unsigned plane, unsigned row) const
*/
double prob_matrix::col_sum(unsigned plane, unsigned column) const
{
if(!plane_used(plane)) {
return 0.0;
}
double sum = 0.0;
for(unsigned row : used_rows_[plane]) {
sum += val(plane, row, column);
@ -2148,10 +2156,14 @@ void complex_fight(attack_prediction_mode mode,
* with simple addition.
* Instead, just fetch the probability from the combat matrix.
*/
opp_not_hit = original_opp_not_hit * pm->col_sum(plane_index(stats, opp_stats), opp_stats.hp);
unsigned int plane = plane_index(stats, opp_stats);
double not_hit = pm->col_sum(plane, opp_stats.hp) + ((plane & 1) ? 0.0 : pm->col_sum(plane | 1, opp_stats.hp));
opp_not_hit = original_opp_not_hit * not_hit;
}
if(opp_stats.slows) {
self_not_hit = original_self_not_hit * pm->row_sum(plane_index(stats, opp_stats), stats.hp);
unsigned int plane = plane_index(stats, opp_stats);
double not_hit = pm->row_sum(plane, stats.hp) + ((plane & 2) ? 0.0 : pm->row_sum(plane | 2, stats.hp));
self_not_hit = original_self_not_hit * not_hit;
}
} else {
debug(("Using Monte Carlo simulation.\n"));