## Thursday, 30 July 2015

### 253: Mathhammer with GNU Octave

Many folk understand how to do basic mathhammer. For example 10 marines shooting bolters at marines (outside 12").

10×(2/3)×(1/2)×(1/3)=1.1

It gets more complicated with things like rending. Still quite possible, but a bit more headscratching is required. Even trickier is shooting at vehicles. To do it properly you need to account for things like multiple immobilised results removing extra hull points.

There is a general method. You get a computer to roll the dice for you, lots of times and keep notes as it goes. This kind of thing is called a Monte Carlo Simulation. An early use was designing nuclear weapons in the second world war.

GNU Octave is a free (open source) maths scripting language. It's quite good for this sort of thing.
To get octave to roll 10 dice, you can do this.

> rolls=ceil(rand(1,10)*6)
rolls =

2   6   2   4   2   2   3   3   5   4

rand gives a matrix of 1×10 numbers. They are between 0 and 1, so you have to multiply by 6. We only want whole numbers, and dice don't give zeros, so we round up. This is what ceil (ceiling) does. Next, how many hit?

> passed=sum(rolls>=3)
passed =  6

rolls>=3 returns a matrix of 0s and 1s. As we need 3+ to hit, it gives 1s to represent the hits. sum adds up the hits. Roll some more dice to wound.

> rollstowound=ceil(rand(1,passed)*6)
rollstowound =

1   2   4   3   4   2

Find out how many wounded

> wounds=sum(rollstowound>=4)
wounds =  2

Time for amour saves

> savingrolls=ceil(rand(1,wounds)*6)
savingrolls =

4   1

How many die?

> deathtoll=sum(savingrolls<3)
deathtoll =  1

You can combine this lot into a script file ("example.m") that repeats 100 times.

n=100;
for i=1:n
rolls=ceil(rand(1,10)*6);
passed=sum(rolls>=3);
rollstowound=ceil(rand(1,passed)*6);
wounds=sum(rollstowound>=4);
savingrolls=ceil(rand(1,wounds)*6);
deathtoll=sum(savingrolls<3)
end