keep a low profile

One other question arises from the function is.scatter.hit is: what is the probability profile of catching a model with blast damage when the shot is short? I made a tweak to is.scatter.hit so that it would work on a vector of distance values. This means that I can reuse the code from my last post to calculate the probability of hitting at each position over the weapon’s range.

> source("WMTools/R/isscatterhit.R")
> is.scatter.hit
function(weapon, short = 0, base = 30, max = 6, dice = sample(1:6, size = 2, replace = TRUE)) {
 
    rad <- 0.5 * weapon$stats["AOE"]
   
    if (is.null(base) || is.na(base) || length(base) != 1) { stop("base should be length 1") }
   
    radBase <- 0.5 * base / 25.4
   
    isHit <- FALSE
   
    if (!is.na(rad)) {
       
        if (length(dice) < 2) { stop("insufficient dice provided, but two required") }
        if (!all(dice[1:2] %in% 1:6)) { stop("expecting D6 result, but instead: ", paste(dice, collapse = ", ")) }
       
        moves <- dice[1]
       
        if (moves > max) { moves <- max }
       
        x <- cos(pi/6)
        y <- sin(pi/6)
       
        # system is symmetrical, so only solve for one half of x
       
        dir <- switch(dice[2],
                c(0, 1),  # straight forward
                c(x, y),  # forward
                c(x, -y), # backward
                c(0, -1), # straight backward
                c(x, -y), # backward
                c(x, y))  # forward
       
        sep <- rep(0, times = length(short))
       
        sep[short != 0] <- short[short != 0] + radBase
       
        dmove <- sqrt((sep - moves * dir[2])^2 + (moves * dir[1])^2)
       
        isHit <- unname(abs(dmove) < radBase + rad)
    }
    return(isHit)
}
> # rerun the unit tests to make sure 
> # that the changes have not broken anything! > source("WMTools/test/test.isscatterhit.R") isscatterhit is okay

It is now just a small change to collect the extra dimension of calculations.

> # values to test
> diams <- c(30, 40, 50, 120)
> aoes <- c(3, 4, 5)
> shorts <- seq(from = 0.01, to = 10, by = 0.01)
>
> # objects to collect combinations
> probs <- array(NA,
+     dim = c(length(diams), length(aoes), length(shorts)),
+     dimnames = list(diams, aoes, shorts))
> # direction is important this time
> combs <- expand.grid(dist = 1:6, dir = 1:6)
> out <- matrix(NA, nrow = nrow(combs), ncol = length(shorts))
>
> # as before, except we create two dimensional summaries
> for (k in seq_along(aoes)) {
+     for (j in seq_along(diams)) {
+         for (i in seq_len(nrow(out))) {
+             out[i, ] <- is.scatter.hit(list(stats = c(AOE = aoes[k])),
+                 short = shorts, base = diams[j], 
+ dice = unlist(combs[i, ])) } + +         probs[j, k, ] <- colSums(out) / nrow(out) + }}

We can plot these probabilities by base size to make them easier to compare.

> for (d in seq_along(diams)) {
+     plot(range(shorts), range(probs), type = "n",
+         xlab = rep(c("", "Short (inches)"), each = 2)[d],
+         ylab = rep(c("Probability", ""), times = 2)[d])
+     # add lines, extracting for each base diameter
+     matlines(shorts,
+         t(apply(probs, 3, function(x) { x[d, , drop = TRUE] })),
+         lty = 1, col = c("#EC7720CC", "#2A63E2CC", "#22EE22CC"))
+     legend("topright", paste(diams[d], "mm"), bty = "n")
+ }

Image

These plots show the probability of a hit for 3 inch (orange), 4 inch (blue) and 5 inch (green) area of effects. The calculations were made every 0.01 inches, so these flat sections actually represent sections where small differences in the distance from the target hit on the same rolls.

There are some interesting quirks of these profiles. Most notably, a 5 inch template is more likely to scatter when between 0.65 and 1.03 inches short of its target than when closer.

The wiggly tail represents where the template is far enough from the target that only a one on the direction die causes a hit, with a high enough distance die. These plots are similar since the distance measurement is made to the edge of the target model’s base, rather than the centre of the model.

These profiles are exact analytical results. However, I will use is.scatter.hit for simulating the effectiveness of warjacks and warbeasts ranged attacks at different ranges, since the number of combinations of strategies and dice outcomes is very large.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s