User talk:Zerghalo2
So, talk page. Yeah...
Kill Team Factions[edit]
You have simulation :)
The actual simulation code[edit]
So I wrote the simulation in the R language. The actual code is the following:
totwounds <- function(ws, s, t, ap, sth, isv, nattack, dmg, reroll1s=0, reroll1sw=0, dttfe=0, rerollw=0, hasdouble=0, hasplus1=0, attackmod=0, woundmod=0, flail=0, aura=0, plasma=0, mortalsw=0, fnp=0, reroll1sfnp=0, melta=0, nunit=1, debug=0) {
## so this is interesting, there is a different between per unit and number of attacks. In the case of possessed we do nattacks before
if(nattack == 'd3') {
nattack <- sum(sample(d3, nunit, replace = TRUE))
} else if (nattack == 'd6') {
nattack <- sum(sample(d6, nunit, replace = TRUE))
} else if(flail) {
nattack <- sum(sample(d3, nattack*nunit, replace = TRUE))
} else {
nattack <- nattack*nunit
}
if(debug) {
#cat("nattack", nattack, "\n")
}
attacks <- sort(sample(d6, nattack, replace = TRUE))
if (reroll1s) {
toreroll <- lapply(attacks, function (x) {x==1})
rix <- which(toreroll == TRUE)
attacks[rix] <- sample(d6, length(rix), replace = TRUE)
}
xtra <- 0
## there are multiple ways of doing xtra attacks.
if (dttfe) {
nxtra <- length(which(lapply(attacks, function(x) { x+attackmod >= 6}) == TRUE))
xtra <- sort(sample(d6, nxtra, replace = TRUE))
}
if(plasma) {
## want to trim attacks after one
}
tot <- length(which(lapply(append(attacks, xtra), function(x) { x+attackmod >= ws}) == TRUE))
mortals <- 0
wounds <- sample(d6, tot, replace = TRUE)
if (reroll1sw) {
toreroll1sw <- lapply(wounds, function (x) {x==1})
rwix <- which(toreroll1sw == TRUE)
wounds[rwix] <- sample(d6, length(rwix), replace = TRUE)
} else if (rerollw) {
torerollw <- lapply(wounds, function (x) {x < towound(s,t)})
rwix <- which(torerollw == TRUE)
wounds[rwix] <- sample(d6, length(rwix), replace = TRUE)
}
## the issue here is that we can stack these.
if(mortalsw) {
mortals <- length(which(lapply(wounds, function(x) { x+woundmod >= mortalsw}) == TRUE))
}
ndouble <- 0
if (hasdouble) {
ndouble <- length(which(lapply(wounds, function(x) { x+woundmod >= 7}) == TRUE))
}
nplus1only <- 0
if (hasplus1) {
nplus1only <- length(which(lapply(wounds, function(x) { x+woundmod >= 6 }) == TRUE)) - ndouble
}
## need to be able to handle invulnerable saves.
## also need to be able to think of the most wounds per point.
nrust <- 0
if(aura) {
nrust <- length(which(lapply(wounds, function(x) { x >= 6 }) == TRUE))
}
nregw <- length(which(lapply(wounds, function(x) { x+woundmod >= towound(s,t)}) == TRUE)) - ndouble - nplus1only - nrust
doublesaves <- sample(d6, ndouble, replace = TRUE)
ndoublesv <- length(which(lapply(doublesaves, function(x) { x < sth+ap }) == TRUE))
plus1saves <- sample(d6, nplus1only, replace = TRUE)
nplus1sv <- length(which(lapply(doublesaves, function(x) { x < sth+ap }) == TRUE))
rustsaves <- sample(d6, nrust, replace = TRUE)
nrustsv <- length(which(lapply(rustsaves, function(x) { x < sth+ap+1 }) == TRUE))
regwounds <- sample(d6, nregw, replace = TRUE)
nregsv <- length(which(lapply(regwounds, function(x) { x < sth+ap }) == TRUE))
## so I need to sample all the damages I need
## I also need to see if the damage is against big strong things.
## or against troops, so you are really applying it to units piecewise.
totwounds <- ((ndoublesv*3)+(nplus1sv*2)+nregsv+nrustsv)
## need to be able to handle switching between dead units and spread wounds
if(totwounds == 0)
return(0)
totwounds <- if(dmg == 'd3') {
sum(sample(d3,totwounds, replace = TRUE))
} else if (dmg == 'd6'){
## need to do melta here
## how do I do 2d6 dropping 1?
if(melta == 1) {
replicate(totwounds, max(sample(d6, 2, replace=TRUE)))
} else {
sample(d6,totwounds, replace=TRUE)
}
} else {
totwounds*dmg+mortals
}
## fnp is basically a way of shaving off wounds.
if(fnp) {
## so I need to reroll DR too.
## we need to apply this to every set of wounds.
#cat("totwounds", totwounds, "\n")
totwounds <- sapply(totwounds, function (wounds) {
fnps <- sort(sample(d6, wounds, replace = TRUE))
if (reroll1sfnp) {
toreroll <- lapply(fnps, function (x) {x==1})
rix <- which(toreroll == TRUE)
fnps[rix] <- sample(d6, length(rix), replace = TRUE)
}
length(which(lapply(fnps, function (x) {x < fnp}) == TRUE))
})
#cat("totwounds", totwounds, "\n")
}
totwounds
}
kttotwounds <- function(ws, s, t, ap, sth, isv, nattack, dmg, reroll1s=0, reroll1sw=0, dttfe=0, rerollw=0, hasdouble=0, hasplus1=0, attackmod=0, woundmod=0, flail=0, aura=0, plasma=0, mortalsw=0, fnp=0, reroll1sfnp=0, melta=0, nunit=1, debug=0, obscured=FALSE, totwounds=1, fleshwounds=0, wounds=1) {
didwounds <- totwounds(ws, s, t, ap, sth, isv, nattack, dmg, reroll1s, reroll1sw, dttfe, rerollw, hasdouble, hasplus1, attackmod, woundmod, flail, aura, plasma, mortalsw, fnp, reroll1sfnp, melta, nunit, debug)
result <- 0
for (w in didwounds) {
if (wounds - w <= 0) {
result <- max(sample(d6, didwounds, replace=TRUE))
wounds <- wounds - w
break
} else {
wounds <- wounds - w
}
}
injmod <- 0
if (obscured) {
injmod <- injmod-1
}
injmod <- injmod+fleshwounds
if(wounds > 0) {
factor("survived")
} else if(result >= 4+injmod) {
factor("outaction")
} else {
factor("fleshwound")
}
}
I just adapted it from some earlier 40k work I did for army list building.
Bob123 (talk) 04:31, 11 August 2018 (UTC)
How to simulate[edit]
So the trick is to learn a statistical language like R. A monte carlo simulation is actually super easy, you just write something that does one "event" from a 40k game and run it a bunch of times and see what the statistics for your result look like.