wesnoth-cvs-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Wesnoth-cvs-commits] wesnoth ./changelog src/actions.cpp


From: ott
Subject: [Wesnoth-cvs-commits] wesnoth ./changelog src/actions.cpp
Date: Tue, 10 May 2005 02:55:12 -0400

CVSROOT:        /cvsroot/wesnoth
Module name:    wesnoth
Branch:         
Changes by:     ott <address@hidden>    05/05/10 06:55:11

Modified files:
        .              : changelog 
        src            : actions.cpp 

Log message:
        added %-to-kill to Damage Calculations

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/changelog.diff?tr1=1.659&tr2=1.660&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/actions.cpp.diff?tr1=1.214&tr2=1.215&r1=text&r2=text

Patches:
Index: wesnoth/changelog
diff -u wesnoth/changelog:1.659 wesnoth/changelog:1.660
--- wesnoth/changelog:1.659     Mon May  9 16:11:11 2005
+++ wesnoth/changelog   Tue May 10 06:55:10 2005
@@ -1,6 +1,7 @@
 CVS HEAD:
  * balancing change: reduced cost of dwarvish fighter by 1 gold; made 
Lieutenant more powerful
  * user interface improvements:
+   * added %-to-kill to Damage Calculations
    * made it so a unit's defense in a terrain is displayed over the terrain 
when choosing to move the unit
    * added 'Advanced' preferences section with 'binary save files' and 'show 
combat' as initial options
    * fix editor file chooser when starting directory has many files (#11698)
Index: wesnoth/src/actions.cpp
diff -u wesnoth/src/actions.cpp:1.214 wesnoth/src/actions.cpp:1.215
--- wesnoth/src/actions.cpp:1.214       Mon May  2 19:42:04 2005
+++ wesnoth/src/actions.cpp     Tue May 10 06:55:11 2005
@@ -1,4 +1,4 @@
-/* $Id: actions.cpp,v 1.214 2005/05/02 19:42:04 silene Exp $ */
+/* $Id: actions.cpp,v 1.215 2005/05/10 06:55:11 ott Exp $ */
 /*
    Copyright (C) 2003 by David White <address@hidden>
    Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
@@ -234,6 +234,52 @@
        return maximum<int>(1, (base_damage * bonus + rounding) / divisor);
 }
 
+double pr_atleast(int m, double p, int n, int d)
+{
+       // calculate Pr[A does damage in [m,...)], where
+       // p probability to hit, n swings, d damage/swing
+       double P = 0;
+       for(int k = (m + d - 1)/d; k <= n; ++k) {
+               double r = 1.0;
+               const int k2 = (k > n - k) ? (n - k) : k;
+               for(int i = 0; i < k2; ++i) { r *= (n-i); r /= (k2-i); }
+               P += ((int)r) * pow(p, k) * pow(1-p, n-k);
+       }
+       return P;
+}
+
+double pr_between(int mn, int mx, double p, int n, int d)
+{
+       // calculate Pr[A does damage in [mn,mx)], where
+       // p probability to hit, n swings, d damage/swing
+       return pr_atleast(mn, p, n, d) - pr_atleast(mx, p, n, d);
+}
+
+int reduce(int i, int u, int v)
+{
+       // i-th swingpair, but reduce since u < v
+       if(i == 0)
+           return i;
+       else
+           return ((i-1) / v)*u + minimum<int>(u, ((i-1) % v) + 1);
+}
+
+double pr_kills_during(const int hpa, const int dmga, const double pa,
+       const int swa, const int hpb, const int dmgb, const double pb,
+       const int swb, const int n, const bool second)
+{
+       if ((swa < swb) and (swa < (n-1) % swb + 1)) // not our move
+               return 0.0;
+       // A kills B during swing n, and is it second?
+       // take into account where one unit doesn't get all n swings
+       const double t1 = pr_between(hpb - dmga, hpb, pa,
+               (swa<swb) ? reduce(n-1, swa, swb) : (n-1), dmga);
+       const int n2 = second ? n : (n - 1);
+       const double t2 = 1 - pr_atleast(hpa, pb,
+               (swa>swb) ? reduce(n2, swb, swa) : n2, dmgb);
+       return t1 * pa * t2;
+}
+
 battle_stats evaluate_battle_stats(const gamemap& map,
                                    const gamemap::location& attacker,
                                    const gamemap::location& defender,
@@ -569,6 +615,42 @@
        if(d->second.has_flag(slowed_string) && res.ndefends > 1)
                --res.ndefends;
 
+       // FIXME: doesn't take into account berserk+slow, drain or firststrike
+       if (strings && res.amount_attacker_drains == 0 &&
+               res.amount_defender_drains == 0 &&
+               (!res.defender_strikes_first) && !(res.to_the_death &&
+                       (res.attacker_slows || res.defender_slows)))
+       {
+               const int maxrounds = (res.to_the_death ? 30 : 1);
+               const int hpa = a->second.hitpoints();
+               const int hpb = d->second.hitpoints();
+               const int dmga = res.damage_defender_takes;
+               const int dmgb = res.damage_attacker_takes;
+               const double pa = res.chance_to_hit_defender/100.0;
+               const double pb = res.chance_to_hit_attacker/100.0;
+               const int swa = res.nattacks;
+               const int swb = res.ndefends;
+               double P1 = 0;  double P2 = 0;
+
+               for(int n = 1; n <= maxrounds*maximum<int>(swa,swb); ++n) {
+                       P1 += pr_kills_during(hpa, dmga, pa, swa,
+                               hpb, dmgb, pb, swb, n, FALSE);
+                       P2 += pr_kills_during(hpb, dmgb, pb, swb,
+                               hpa, dmga, pa, swa, n, TRUE);
+               }
+
+               std::stringstream str;
+               if (P1 < 0.005 && P2 < 0.005) {
+                       str << _("(both should survive)");
+               } else {
+                       str << _("% Pr[kills/killed by/both survive]")
+                           << EMPTY_COLUMN << (int)(P1*100+0.5)
+                           << '/' << (int)(P2*100+0.5)
+                           << '/' << (int)((1-P1-P2)*100+0.5);
+               }
+               strings->attack_calculations.push_back(str.str());
+       }
+
        return res;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]