Logo
View unanswered posts | View active topics It is currently Mon Sep 28, 2020 1:19 pm



Reply to topic  [ 4 posts ] 
Probably the ultimate theorycraft challenge for WFB/9th Age 
Author Message
Malekith's Best Friend
User avatar

Joined: Fri Oct 03, 2003 7:36 pm
Posts: 3861
Location: Belgium, Brussels
Greetings,

I've been brooding on this one theory challenge for WFB and now for 9th Age. It's been on my mind for over a year now, though with the occasional break ;)
I thought I'd post my thoughts on it because... why not?

What I'm trying to theorycraft is the chance to break a unit in combat, in the first turn and the second turn of combat. Especially that second turn of combat seems interesting.

If you think about it, it's one of the most powerful moves in the game: if you charge, you do want to beat up your opponent's unit but it would be extremely powerful if you could time it to break him in his own turn. That way, your unit can get a pursuit or reform move before your own turn, ready to charge again.
Considering how incredibly valuable this move can be, I find it shocking that so little work on optimizing that strategy has been published. At least, to my knowledge.

My guess is that it's difficult to compute. I'm inclined to agree with that, but perhaps for different reasons. It's an easy to state problem. The challenge is how to compute it, technically. My ealiest attempts to build a calculator for this crashed.
I believed it was a lack of optimization and bad problem statement. Over the past months, I've slowly reached the conclusion that it wasn't just my program at fault.

Take, for example, a unit of 12 Cold One Knights and 30 Executioners. Not exactly the best match-up but it serves as an example.
we have to take into account the exact damage done by each unit for combat resolution purposes AND to give an accurate depiction of return damage (if the COK's rolled well, the Executioners will score worse).
Here is my problem. For sake of ease, I assume all models can fight.
- The Cold One Knights get to attack first, delivering 13 attacks.
- For each of these 14 possible outcomes (0 to 13 kills) we have to calculate the possible return damage.
- The attacks of the executioners can range from 18 to 31 attacks, with an average of around 24.5. In theory we have 343 possible situations.
- Then we have the return damage from the cold ones, which can be done by 0-12 models with 0-24 attacks with an average of 12 for 13 possible states, or 156 possible attack patterns.
For the first round of combat we have 53508 possible outcomes. Before optimization. This is where my program faltered.

We can optimize this, if we take into account some game mechanics. IE: the Executioners can never score more than 12 kills. Only the front 6 COKs will attack.
- Now the COKs can do 0 to 13 kills
- For each kill of the COKs, the Executioners can do 0-12 kills.
- Then the Cold ones fight back, doing 0 to 12 kills.
This gives us:
13 * 12 * 12 = 1872 possible outcomes. Notably less. Perhaps even a little less if we keep optimizing it.

But then we still see an explosion of numbers in the second round of combat:
- The COKs have any of 0-12 models and Executioners 5-30, good for 312 possible states to start from.
- With 0-12 models, we have 0-13 kills but on average this is limited to 7. So around 2184 possible states.
- The EXEs fight back, 0-30 models now, but are still limited to 10 kills. It's hard to pick an average on this now, but 21840 states is a slight over estimate.
- The Cold Ones have 0 to 6 models in the front left. 0-12 possible kills, with an average of 6
-> 131040 possible states although we could assume this is over estimated the possible outcomes a little.

But this includes a series of optimizations. What's more is that any additional units tends to explode that number of outcomes by so many states that I fear it can not be computed lightly.

My guess is that this is one of the reasons there has been little work on it. It's technically exhaustive and requires a complex system designed to handle that many states. It would need a lot of optimizations. A few simplifications in the code that penalize the calculations could quickly multiply the number of states that are computed. IE: I originally implemented my champion as a separate attack pattern, which permitted elegant coding for handling champions, but it doubled the number of computations in the best of cases.


SO... That's where I'm currently stuck with my theory. Does anyone have a magic trick to simplify this? :P

_________________
I love me a bowl of numbers to crunch for breakfast. If you need anything theoryhammered, I gladly take requests.

Furnace of Arcana, a warhammer blog with delusional grandeur.

"I move unseen. I hide in light and shadow. I move faster than a bird. No plate of armour ever stopped me. I strike recruits and veterans with equal ease. And all shiver at my coldest of whispers."
- The stiff breeze


Tue Dec 01, 2015 11:08 am
Profile WWW
Malekith's Best Friend
User avatar

Joined: Fri Oct 03, 2003 7:36 pm
Posts: 3861
Location: Belgium, Brussels
With a lunch break to think about it, I set out on a different path. How could we optimize the computation?

Well... For one we could cache the potential damage output of a unit for all situations. As I've shown in earlier theorycrafts, we can write down all possible damage outcomes of a unit as a polynomial.
For example, in WFB 8th a COK has a ~73% to score a kill vs an Executioner:
1 Attack = (27% + 73% Wound).
11 Attacks = (27% + 73% Wound)^11
Although we can have a variable number of attacks, as the unit starts taking casualties, we can pre-cache these polynomials from 0 Attacks to 11 Attacks. We can do the same for Executioners for 0 to 31 Attacks and the cold ones for 0 to 12 attacks (provided the unit is 6 wide).

I built an optimization in my combat calculator that computes 11 attacks more efficiently than calculating it one at a time. As a result, I know the extra cost of calculating all of these possible attack patterns: roughly twice as much as calculating the highest amount of attacks. That's not so bad, considering how much data is generated.

Now, to calculate a single round of combat, we have to start by making a wound matrix or list of combinations for every possible amount of remaining wounds on the units in the combat. IE: if you have 10 COKs these are 11 states (0 to 10). But we can optimize this by removing states that have no chance of occurring. So a first round of combat probably starts with 100% 10 COKs.

When we have all combination of states, we start the combat game. We need to know the initiative or order of attacks and the target. Then we apply the attack patterns in sequence to each state. We can optimize this along the way by limiting the damage output to the number of enemy models.

When all attack patterns are resolved, we can compute the combat resolution for each outcome and work out the chance to break the enemy.

Sounds simple enough, but I can't help but feel the program needs to understand a hell of a lot of game mechanics:
- Ranks
- Champions
- Banners
- Musicians
- Supporting attacks
- Split attack profiles
- Initiative, ASF,
etc...

The amount of input required for such a computation would be quite tedious to the point it would be a lot of work... And that kind of defeats the purpose of having these computations automated.
This would be the easiest to solve with a unit database, and a games engine that computes all the stats.

_________________
I love me a bowl of numbers to crunch for breakfast. If you need anything theoryhammered, I gladly take requests.

Furnace of Arcana, a warhammer blog with delusional grandeur.

"I move unseen. I hide in light and shadow. I move faster than a bird. No plate of armour ever stopped me. I strike recruits and veterans with equal ease. And all shiver at my coldest of whispers."
- The stiff breeze


Tue Dec 01, 2015 1:03 pm
Profile WWW
Corsair
Corsair
User avatar

Joined: Fri Mar 14, 2008 10:00 pm
Posts: 8740
Location: Hag Graef
Your efforts to compute the exact probability of achieving the result are impressive.
May I suggest you
- to scale it up to x models,
- to separate small scale and large scale,
- to break your computation into two steps,
- and to accept approximations?

1. To scale up:
What is true for 12 Cold One Knights vs. 30 Executioners is probably quite close to 24 Cold One Knights vs. 60 Executioners.
You might consider a unit of "x" COK vs. 2.5 "x" Execs and have similar results, as long as "x" is large enough.
Just keep the fractions of the models fighting and the result should be good enough for a decision.

2. Large scale # small scale.
What I mentioned above will provide good results for very large units, due to large numbers stats.
Small units are much more random. Fortunately, small units are easier to compute.
You may compute systematically as you planned the exact probabilities, but only for small units.
What is small? Well, that is what you can reasonably compute.
If it is up to 30 models friend & foe combined, great (counting a model with two profiles as 2). If less, it may be good enough.

3. One step at a time.
What you wish to do is to break the unit during the second turn.
The start of the second turn is therefore what matters.
Once you've established the ideal size for second turn, average +/- sigma, which would result in "sufficient" probability to achieve the desired result without overkill,
then you can trace back the ideal size for the frst turn which would likely (+/- sigma again) yield these ideal sizes.

4. Approximate.
Intermediate results which happen once a thousand battles can be discarded, even if an extraordinary turn of tide could bring them back into average.

_________________
Winds never stop blowing, Oceans are borderless. Get a ship and a crew, so the World will be ours! Today the World, tomorrow Nagg! {--|oBrotherhood of the Coast!o|--}


Tue Dec 01, 2015 3:39 pm
Profile
Malekith's Best Friend
User avatar

Joined: Fri Oct 03, 2003 7:36 pm
Posts: 3861
Location: Belgium, Brussels
I read your reply yesterday but I needed some time to think on it. It's a very interesting suggestion. We could break up the calculation in two parts, where one part handles the progressive killing of a very large unit where the loss of numbers along the way isn't so likely to influence the result. This should behave a lot like a linear function, perhaps closely tied to the average score of the unit.
The other part handles the behaviour of the unit when it's been reduced to a small size and more refined computations are desirable.
This could lead to conclusions such as "you need 1 COK for every 2 EXEs, + 5" where the +5 is calculated by the small unit function.

Hm! This is interesting ... and it might be a good calculation to have. After giving it more thought I concluded I'm close to doing such a thing already, except I didn't split in two parts.
I reused my algebra and polynomial theory.

We can express the wounds a unit has like a polynomial as well.
Wounds_EXE = 100% Wound^30.
Then it takes a single attack that has 70% chance to succeed or:
ATTACK_ON_EXE = (30% + 70% Wound)
If we "subtract" this from the wounds, then we get:
Wounds_EXE = 70% Wound^29 + 30% Wound^30
Or in case we get 12 such attacks on us:
Remaining_wounds = 100% Wound^30 - (30% + 70% Wound)^12

The polynomial "remaining wounds" can be used to determine the attack profile, taking into account any possible amount of wounds taken. Taking back the example of a single attack for sake of ease:
Wounds_EXE = 70% Wound^29 + 30% Wound^30
->
Attacks_EXE = 70% Attack^29 + 30% Attack^30
Now substitute Attack by the polynomial describing the attack of a single executioner, which is roughly 36% to kill or (64% + 36% Wound)
And we get:
Attacks_EXE = 70% (64% + 36% Wound)^29 + 30% (64% + 36% Wound)^30

While this may seem like a complex calculation, it's quite managable. It uses the same technique I use for random attacks, except the number of attacks is determined by the remaining wounds of the unit, which is variable.
As a result, I already have everything I need to achieve this.
This is also a significantly simpler calculation and it models quite perfectly the evolution of two units in combat. It could be used to determine who will grind out the other one.

But it fails to model combat resolution accurately. To compute the return damage of the executioners, it merges the odds of returning 5 kills after any number of wounds have been inflicted on the executioners. This may not matter when computing damage patterns, but there is a whole world of difference for combat resolution between suffering 0 wounds and returning 5, or suffering 6 wounds and returning 5. So combat resolution tends to reinforce extremes, and increase the variance on the outcome instead of moderating it. This effect becomes even bigger when taking into account banners and flanks, where losing a flank and disruption could make a big difference in the outcome.
While I don't have the numbers on this... Well duh :) ... I think it will look something like this (perhaps exaggerated):

Image

Average values give us an estimated outcome of a single combat res, based on average damage output (possibly taking into account return damage etc). The weighted damage profiles as I explained above will fog up a lot of situations, by merging more extreme outcomes for one unit with more regular outcomes for the other unit. I'm expecting that to give a nice hill of probable outcomes centred around the average.
But I expect the real probabilities to be more diverse and spread out. Perhaps even the average outcome might prove less likely.

Actually, this is exactly the behaviour I was hoping to model. It's an old wound from 6th ed I guess :D I used to charge a unit of Dwarven Warriors with my spears in the front and riders in the flank, expecting 2 kills more than my opponent (slightly optimistic, I admit), and 5 additional points from static combat resolution. Who could resists a -7 break test?
I often ended up doing fewer wounds than my opponent, losing my DR's unit strength in the flank and ending up on the losing side as a result. A swing from 7 point win in combat resolution to a -2 loss.
The weighted damage profiles I described above wouldn't model this accurately, though they might give hint that it's unlikely I'll do 2 more damage than my opponent.

_________________
I love me a bowl of numbers to crunch for breakfast. If you need anything theoryhammered, I gladly take requests.

Furnace of Arcana, a warhammer blog with delusional grandeur.

"I move unseen. I hide in light and shadow. I move faster than a bird. No plate of armour ever stopped me. I strike recruits and veterans with equal ease. And all shiver at my coldest of whispers."
- The stiff breeze


Wed Dec 02, 2015 10:16 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 4 posts ] 

Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software