<< Back to Warzone Classic Forum   Search

Posts 31 - 50 of 52   <<Prev   1  2  3  Next >>   
What are your most improbable failed attacks?: 3/14/2012 18:13:36


Moros 
Level 50
Report


Well, I have nothing to say in this tread since I don't understand programming, but all I know is that you can tell enough from the current analyse screen to have a rough estimation and that will help me enough.

What are your most improbable failed attacks?: 3/15/2012 11:39:49

Candy flipping blazed chink
Level 9
Report

Lol last time i have 12 army attack 2 i have 11 left and became 1

What are your most improbable failed attacks?: 3/15/2012 19:15:54

RvW 
Level 54
Report

Good point, back on topic, we can now exactly calculate which failed attack is actually the most improbable. :p
I'm getting a 0,9999966445568 chance of success for 12 vs 2 (assuming 60%/70%/75%), or 1 in about 300.000. Ouch...!
Do you still have the link for that game?

@Moros:
If you're still reading this: just because you're not a programmer doesn't mean you can't give input. You can still make suggestions for improvements. If you have an idea how to make it easier to understand for people who never had a statistics class that would be very helpful!

What are your most improbable failed attacks?: 3/18/2012 19:21:39

RvW 
Level 54
Report

How well does your code work with doubles?

Fizzer,

Actually, it's not that bad. Here's a comparison:

                                        Double      Extended
    Max input size:                     1029        16378
    Worst rel. error [  990- 1000]      -15         -19
    Worst rel. error [ 1020- 1029]      -15         -18
    Worst rel. error [16370-16378]      N/A         -18

These are the results of running through the nCr calculation (essentially enumerating one row of Pascal's Triangle) and looking at the final result (which should of course be exactly 1, but in practice it's 1 +/- a small error). This is shown in the second through fourth line, where for instance "-15" means the relative error is "x * 10^-15" for some 0 < x < 1. Because the size of the error fluctuates a little between adjacent values I've shown the worst over a small interval.

Sure, the errors are a thousand times bigger, but they're still small enough. Even after summing 10.000 values with a 10^-15 error, you're still only up to a 10^-11 error (worst case, 10^-13 average case if I apply the sqrt(n) law correctly). Chopping things off at full percent points (like the built-in analyser does) or even at one-hundredth of a percent (like my demo program) is only sensitive to 10^-3 or 10^-5 errors, respectively, so there's plenty margin of error left I think.

Would you be okay with an analyser which only works up to 1029 attacking armies...? Remember, beyond that, it doesn't get inaccurate or anything, it completely refuses to work. On the plus side, this limitation is perfectly static and predictable; for 1029 it will always work and for 1030 it will always fail. In other words, this is not prone to unpredictable crashes; adding an if Attackers &gt; 1029 then ShowMessage ( &#39;unsupported&#39; ); reliably "solves" the problem.


The alternative would require porting that statistics library (or finding another one). Problem is, it uses some numerical approximations and I am not exactly qualified to properly test whether my modifications work; sure, I can throw a bunch of numbers at it (and compare them against results obtained with the original version), but I have no idea where the corner cases are.


Anyway, no hurry, if you want to carefully think about this it's perfectly okay, not like I don't have other projects which need working on. ;)

What are your most improbable failed attacks?: 3/19/2012 02:01:56

(Lost)SGV_STH
Level 23
Report

RvW, I know that it is not really too helpful and is somewhat pointless, but I was wondering something as I do not understand the programming language that you are using. Why is it that anything above 1,029 would fail to work? I would understand it if it was 1,023 to 1,025 due to binary. However, it seems to me that 1,030 would be alright. I will say that the deepest that I have gone into programming is learning about PHP, but it is a bit basic at times.

What are your most improbable failed attacks?: 3/19/2012 06:53:43

RvW 
Level 54
Report

The programming language I'm using is a dialect of Pascal (Delphi Object Pascal to be precise), but actually, that has absolutely nothing to do with it. :p



I think there are two things you're possibly misunderstanding.


First, it's not the number of armies itself that is a problem; if that were the case you'd have a very good point. The problem is a calculation I'm doing with the number of attackers; halfway through that calculation, the numbers get big (and when I say big I mean absolutely, positively huge).
Are you familiar with basic statistics? Simulating an attack in WL is very much like repeatedly flipping a (weighted) coin, once for every attacker. When it comes up heads, a defending army is killed. Now, calculating the chance of all attackers killing a defender is easy: 0,60^n (where n is the number of attackers, and of course the 0,60 is assuming the default offence kill rate of 60%). Calculating the chance of not a single attacker killing a defender is also easy: 0,40^n. It gets a little more complicated when part of the attackers kill a defender and another part doesn't; the chance that happens is not simply 0,60^x * 0,40^y, you have to multiply with something usually called cNr ("n-choose-r"). Essentially I need the n'th row of Pascal's Triangle [1] to do the calculation for n attacking armies.
In theory it's a simple enough calculation, but the result get incredibly big very, very quickly. For instance, 4 nCr 2 = 6, 8 nCr 4 = 70, 16 nCr 8 = 12870, 30 nCr 15 ~= 1,551 * 10^8, 50 nCr 25 ~= 1,264 * 10^14, ... and the "easy" way to calculate them uses intermediate values which are much, much larger still. (Luckily, I can use an alternative way to calculate them without slowing the computation down. However, there's no easy way around storing the result itself, so when that gets to big, I'm in trouble.)
So when I say it works for 1029 armies, that's just the practical consequence; internally, I'm saying 1,4 * 10^308 is okay, but 2,8orso * 10^308 (which happens in the calculation for 1030 armies) is not.

[1] Note, both Pascal's Triangle and the programming language Pascal are named after the same mathematician Blaise Pascal, but there's no real relation between the two of them.


Secondly, while the numbers in Pascal's Triangle are integers, I am not storing them as integers, I'm using floating point numbers (that's were the whole "Extended" vs. "Double" question comes in; those are two "flavours" of floating point numbers). If you're not familiar with that word, it's very similar to scientific notation (such as "1,23 * 10^4", except that (this being computers ;) ) the exponent is in powers of 2 instead of 10).
Usually floats are used when you want to store non-integral numbers, but they have another purpose as well (which is my reason for using them): storing ridiculously big numbers. And I don't think "ridiculously" is exaggerated: double precision already goes up a little past 10^300, extended precision comes very close to 10^5000. To put that into perspective, the size of the observable universe is somewhere between 10^40 and 10^45 times the radius of an atom...!
To put it in another perspective, computers can usually work with numbers up to 4,3 * 10^9 (32 bit integer) or 1,8 * 10^19 (64 bit). On a 64 bit machine it is reasonably practical to work with 128 bit integers for a maximum of 3,4 * 10^38. Of course it's possible to go beyond that (and there are some programs which do), but around this time you should start wondering whether you really want to (and, in some cases, the answer can be "yes, there's no other way"!). In this case it turns out using floating point numbers is "good enough". But, that does mean it's very unlikely the maximum allowable numbers (even if you had thought about me doing a calculation with them) will sound unfamiliar to you. Just for fun, I looked them up in the docs: MaxDouble = 1.7e+308 and MaxExtended = 1.1e+4932.


Does this clear things up? If you have any more questions, just ask!



What are your most improbable failed attacks?: 5/24/2012 16:25:41

Killer23{Warlighters}
Level 8
Report

RVW: hwo to command promt

CMD.EXE

What are your most improbable failed attacks?: 5/24/2012 19:37:54

RvW 
Level 54
Report

@Killer23:
Yeah I know (you really think I'm writing command line utilities if I don't know how to open a command prompt? :p ).

The point is, just firing up CMD isn't going to do you much good. You still need to get to the correct directory.
(Unfortunately, that's not trivial if you've never done it before, especially because MS's implementation of long filenames (read: spaces in filenames) is horribly broken, some directories show up in the graphical shell with a different name than they actually have ("RvW's Documents" versus "My Documents", aaaaragghghgh!!) and some other, smaller, issues.)
Also, completely at odds with the graphical environment, there are only very few instances where the command line asks you to confirm potentially disastrous commands. The fact that it defaults to setting the initial directory to be the system directory does not help either.

I didn't leave out the explanation because it's impossible to explain, I left it out because of the potential for causing unintended damage and because it was relatively easy to convert (almost) everything to a GUI program anyway.


ps. I didn't forget about this project, I'm just kinda low on time and I want to make absolutely sure I don't mess up.

What are your most improbable failed attacks?: 4/11/2013 06:55:41

Reith 
Level 2
Report
I googled and found this thread after I had an improbable failure: 5v2 and 6v2 in turn 3, costing me a reinforcement card. This is a 1/1209 chance, which beats the original poster (1/567) but loses to the 10v2 loss (1/19,073).

Huge props to RvW for giving the formulas and posting the code.

With apologies I converted RvW's Pascal code to Perl; any mistakes in the conversion are obviously my own.

#!/usr/bin/perl
#
# Usage:
# $ wlcalc attackers defenders [offense defense luck]
#
# Default values for offense, defense, and luck:
# - offense = 0.6
# - defense = 0.7
# - luck = 0.75
#
# Algorithms taken from RvW's code:  http://warlight.net/Forum/Thread?ThreadID=3153&Offset=0
# and converted from Pascal to Perl.
#
###########################################################################

use strict;

my ($attackers, $defenders, $offense, $defense, $luck) = @ARGV;

$offense = 0.60 unless defined $offense;
$defense = 0.70 unless defined $defense;
$luck    = 0.75 unless defined $luck;


print "Attackers         = $attackers\n";
print "Defenders         = $defenders\n";
print "Offense           = ", &get_prob($offense), "\n";
print "Defense           = ", &get_prob($defense), "\n";
print "Luck              = ", &get_prob($luck),    "\n";

print "\n";

my ($attack_success) = &attack_success_chance($attackers, $defenders, $offense, $defense, $luck);

print "Chance of success = ", &get_prob($attack_success), "\n";
print "Chance of failure = ", &get_prob(1 - $attack_success), "\n";
print "Chance of failure = 1 in ", (1 / (1 - $attack_success)), "\n";

exit;


###########################################################################
# sub get_prob($prob)
#
sub get_prob {
  my ($prob) = @_;

  return ($prob * 100) . '%';
}	# sub get_prob()


###########################################################################
# sub attack_success_chance($attackers, $defenders, $offense, $defense, $luck)
#
sub attack_success_chance {
  my ($attackers, $defenders, $offense, $defense, $luck) = @_;

  if ($attackers == $defenders) {
    return &kill_all_chance($attackers, $defenders, $offense, $defense, $luck) *
      (1 - &kill_all_chance($defenders, $attackers, $defense, $offense, $luck));
  } else {
    return &kill_all_chance($attackers, $defenders, $offense, $defense, $luck);
  }
}	# sub attack_success_chance()


###########################################################################
# sub kill_all_chance($attackers, $defenders, $offense, $defense, $luck)
#
sub kill_all_chance {
  my ($attackers, $defenders, $offense, $defense, $luck) = @_;

  my ($ncr) = 1;
  my ($sum_chance) = 0;

  my ($expected_kills) = $attackers * $offense;

  foreach my $i (0 .. $attackers) {
    $ncr = ($ncr * ($attackers + 1 - $i)) / $i if ($i > 0);

    my ($sim_kills) = $i;
    my ($sim_chance) = $offense ** $i * (1 - $offense) ** ($attackers - $i) * $ncr;
    my ($total_kills) = (1 - $luck) * $expected_kills + $luck * $sim_kills;

    my ($total_chance) = $sim_chance;
    if ($total_kills <= $defenders - 1) {
      $total_chance = 0;
    } elsif ($total_kills < $defenders) {
      $total_chance = ($total_kills - int($total_kills)) * $sim_chance;
    }

    $sum_chance += $total_chance;
  }

  return $sum_chance;
}	# sub kill_all_chance()
What are your most improbable failed attacks?: 4/13/2013 15:46:29


[WG] Warlightvet 
Level 17
Report
i want to see a 100% luck 1% offensive kill rate 1000 VS 1000 succeed.
0.01^1000 success chance
What are your most improbable failed attacks?: 6/24/2013 14:53:09


Krzysztof 
Level 67
Report
Sorry for resurrection dead thread, but anyway (maybe it will help anyone :P)

Within the calculation I depend on the nCr function, which simply grows very rapidly (exponentially in fact); with 16379 or more attackers to simulate it overflows even the Extended floating point type. I'd have to look into a reasonable approximation for bigger numbers; the current "Sorry, that's not supported" is not acceptable


Well, the fact is nCr value is not needed here. The whole formula for chance is:
nCr * probability^r * (1 - probability)^(n-r)
and it sure the result is between 0 and 1. So all we have to do is to change operations order to keep numbers low. It should looks like this:
double Chance(int n, int r, double probability)
{
	double result = 1;
	int power1counter = 0;
	int power2counter = 0;
	for (var i = 0; i <= r; i++)
	{
		if (i > 0) 
			result = result * (n + 1 - i) / i;
		
		while (result > 1 && power1counter < r) //reducing if needed
		{
			result = result * probability;
			power1counter++;
		}
		while (result > 1 && power2counter < n-r) //reducing if needed 
		{
			result = result * (1 - probability); 
			power2counter++;
		}
	}
	
	while (power1counter < r)
	{
		result = result * probability;
		power1counter++;
	}
	while (power2counter < n - r)
	{
		result = result * (1 - probability);
		power2counter++;
	}
	return result;
}


Ofc. it will be slower, but it allow calculations for any number without using special types for big numbers.
What are your most improbable failed attacks?: 7/17/2013 18:40:38

RvW 
Level 54
Report
(Sorry for the late reply, I wasn't actively checking up on this thread any more.)

This does not readily extends to doing a lot of nCr calculations... In practice that'd turn a linear running time into a quadratic running time. Pity, but I think acceptable. When I find time to work on this again I'll consider your approach (and test how fast / slow it really is (and carefully test it is indeed correct; it looks good, but you never know where corner cases might lurk!)).

Also, one minor change I'd suggest:
You only need that "if ( i > 0 )" once, to "hide" the division by i on the very first iteration (when i is zero). But... the value of "result" is one at that moment, which means the two while loops won't be executed either; you don't need that iteration at all. If you change the for loop to count from one to r, you can ditch the "if ( i > 0 )".



One thing about your proposal I find funny is how it is elegant and ugly at the same time. :p Doing the exponents one-by-one whenever result gets bigger than an (actually rather arbitrary) value is ugly, but keeping the (intermediate) result in a "nice" range for as long as possible is actually a rather elegant way to prevent an overflow. :)
What are your most improbable failed attacks?: 7/17/2013 22:21:39


Krzysztof 
Level 67
Report
Well, those calculation above is generally correct, but don't do what they where created for, because division by i in line:
result = result * (n + 1 - i) / i;


should also be used to keep intermediate results in acceptable range.



This does not readily extends to doing a lot of nCr calculations... In practice that'd turn a linear running time into a quadratic running time


yup, i've noticed that when i used this code in practice, but few mathematical transformation can do the trick and solve this problem.
I was implementing 'reversed analyzer' (inspired by Widzisz's idea described here: http://warlight.uservoice.com/forums/77051-warlight-features/suggestions/3732209-reversed-analyze-graph) but gave up cause all those graphic stuff and UI is not what i like and can :P
Still, calucaltion itself are pretty fast and looks good (weighted-random only) You can check it at http://plemiona.hostingasp.pl/warlight and i can send you code if you are planning to do anything with it
What are your most improbable failed attacks?: 7/17/2013 23:50:56


Min34 
Level 63
Report
You guys remember the good times when this thread was still about your most improbable failed attacks.
What are your most improbable failed attacks?: 7/18/2013 00:31:45

RvW 
Level 54
Report
> Well, those calculation above is generally correct, but don't do what
> they where created for, because division by i in line:
>
> result = result * (n + 1 - i) / i;
>
> should also be used to keep intermediate results in acceptable range.

I'm sorry, but I do not understand what you mean... Are you saying your code is not correct!?
What are your most improbable failed attacks?: 7/18/2013 08:10:34


Krzysztof 
Level 67
Report
@RvW - Yes and no

The goal was to write a code which can caluclate formula:

nCr * probability^r * (1 - probability)^(n-r)

and avoid overflow for bigger numbers - this isn't achieved (it needs modification described earlier) so in this terms it's incorrent

But if we stay away from bigger numbers and avoid overflows results will be fine.
What are your most improbable failed attacks?: 7/18/2013 13:00:41


{rp} Julius Caesar 
Level 46
Report
Those numbers are so… mind blowing i have no clue what they mean i just know to simply attack with double whats defending and i usually win
What are your most improbable failed attacks?: 7/18/2013 13:08:03


told you i could change your name
Level 28
Report
^+1 :P
What are your most improbable failed attacks?: 7/18/2013 14:06:22


Min34 
Level 63
Report
I use the analyse-option :D So I don't have to do all this work :p
What are your most improbable failed attacks?: 7/18/2013 18:56:33

RvW 
Level 54
Report
Min,
The built-in analyser works by performing the attack a hundred (thousand?) times and seeing how often it succeeds; it is not a mathematical analysis, it is a simulator. It is possible for the analyser to say "this attack has approximately 100% chance of succeeding", but when you actually perform the attack it still fails. The "approximately" is not in there because of rounding, it is there because the method used is simply not exact.
For comparison, the analyser I wrote makes a distinction between "100.00%" (that's a rounded result; you should read it as "99.995% or more") and "guaranteed" (it will always work).

The point of this exercise is to build a better analyser: one which performs the calculation, instead of the simulation. So, if me and kszyhoo succeed in working it out, you will benefit as well. :)
Posts 31 - 50 of 52   <<Prev   1  2  3  Next >>