2
\$\begingroup\$

I need a simple algorithm to calculate the outcome of two differently sized armies battling.

Each army has 1-100 troops and every troop is the same value on the battlefield. The troops do not have individual stats. The only parameter on each army is the number of troops. For example: A with 57 troops battles B with 89 troops. Who wins?

Randomness can be a factor: For example, there could be a 50% chance that team A's total is subtracted by half of team B's total. Here's what I have so far (in a variation of BASIC):

lbl 1
If A>B goto2
If A<(or equal to)B goto3
lbl 2
50% chance B-((A-B)/2)→B
50% chance A-(B/2)→A
goto4
lbl 3
50% chance A-((B-A-/2)→A
50% chance B-(A/2)→B
goto4
lbl 4
If A=0:stop
If B=0:stop
goto1

So this system repeats until one of the armies reaches 0 troops.

The problem is, the battles go too fast. The battle is done almost instantly sometimes. Is there a better algorithm?

\$\endgroup\$
6
  • \$\begingroup\$ If A>B there is a 50% chance B-((A-B)/2)→B. Then A-(B/2)→A. If B>A there is a 50% chance B-((B-A)/2)→B. Then B-(A/2)→B. \$\endgroup\$ Commented May 7, 2013 at 0:54
  • 6
    \$\begingroup\$ You should read that en.wikipedia.org/wiki/Lanchester's_laws \$\endgroup\$
    – PD81
    Commented May 7, 2013 at 1:13
  • 2
    \$\begingroup\$ and this gamedev.stackexchange.com/questions/6262/… \$\endgroup\$
    – PD81
    Commented May 7, 2013 at 1:14
  • 1
    \$\begingroup\$ Wait, your algorithm is too efficient and you want us to make it slower? I don't get it. \$\endgroup\$
    – Anko
    Commented May 8, 2013 at 11:16
  • 2
    \$\begingroup\$ @Anko maybe he wants to visualise battles in more then one step \$\endgroup\$
    – PD81
    Commented May 8, 2013 at 12:13

4 Answers 4

5
\$\begingroup\$

The simplest solution is to simply use the ratio of the two forces as the probability of success/defeat. If you want a method that does not happen instantly, simply implement this method one unit at a time, with a variable speed and output threshold.

For example, 57 vs 89 troops would mean that, for the first step, one side has a chance of 57/146 (39%) to lower the other side by 1, the other has an 89/146 (61%) chance to lower the first side by 1. Each step proceeds until one side wins.

The speed can be variable, the number of units lost per step can be variable, and it's a fairly safe way of showing a realistic simulation.

\$\endgroup\$
1
\$\begingroup\$

When you think about soldiers sitting in trenches firing at each other with a constant fire rate, you could model it by giving each soldier an x% chance to hit and eliminate one enemy soldier per shot, and repeat until one army is defeated.

double kill_chance = 0.05; // 5% chance to kill an enemy per round
int troops_A = 57; // starting strength of army A
int troops_B = 89; // starting strength of army B

// combat loop
while (troops_A > 0 && troops_B > 0) {
    int losses_A = 0;
    int losses_B = 0;
    // army A fires
    for (int i = 0; i < troops_A; i++) {
         if (random() < kill_chance) losses_B++;
    }
    // army B fires
    for (int i = 0; i < troops_B; i++) {
         if (random() < kill_chance) losses_A++;
    }
    // remove casualties
    troops_A -= losses_A;
    troops_B -= losses_B;
    // here would be a good place to report the combat progress to the player
}
// make sure no army ends up with a negative amount of soldiers
if (troops_A < 0) troops_A = 0;
if (troops_B < 0) troops_B = 0;

The function random() in this example is expected to returns pseudorandom floating-point values equally distributed between 0.0 and 1.0.

Keep in mind that this algorithm allows for the battle ending in a draw with both armies losing all their soldiers. This would be equivalent to the last two soldiers shooting each other and then bleeding to death. When you don't want this to happen, you could decrement the enemy troop count in the fire loop of each army instead of decimating them afterwards. This, however, would give an advantage to the army which fires first.

Yeah, war is hell.

\$\endgroup\$
0
\$\begingroup\$

It's very simple example and has nothing to do with my comments (example in js) You could spice it by giving random advantage to one side or another + other rules.

var red = 50;
var blue = 100;

while ( ( red != 0 ) && ( blue != 0 ) ) {    
   var result =  Math.floor((Math.random()*(red+blue))+1);
    if ( red < result   ) {
        red--;
    } else {
        blue--;
    }
   document.write('red:'+red+' '+ ' blue:'+blue+"<br />");
}
\$\endgroup\$
1
  • \$\begingroup\$ I think I posted this same answer while you were typing yours. Great minds, and all. =) \$\endgroup\$
    – Attackfarm
    Commented May 7, 2013 at 2:15
0
\$\begingroup\$

I'm going to improve on the idea of soldiers shooting each other, and then simulating the battle. The fact that you dislike the high speed of the current simulation makes me assume that having simulation (as opposed to direct computation) is part of your goal.

Method 1

The simulation is run in time steps. Each time step, each soldier has a probability of dying given by the formula 1 - (1-X)^(B/A), where X is a number between 0 and 1 (but much closer to zero), B is the number of living soldiers in the opposing army, and A is the number of living soldiers in that particular soldier's army. To be specific, X is the probability of dying when a single enemy soldier fires a single bullet towards you.

Method 2

This simulation is also run in steps. Each step, one soldier is randomly chosen to be killed. Pick a random soldier from all of the soldiers. Then, figure out which team that random soldier is on. The opposing team receives the fatality.

If we were to just kill a random soldier, then the larger army will have a higher chance of having the fatality, which is the opposite of real life. By my method, a soldier on a smaller team has a higher probability of being killed.

For example, if Army X has 57 men and Army Y has 89 men, then there is a 61% chance that Army X will have the first fatality and a 39% chance that Army Y will have the first fatality.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .