Dungeons & Dragons Attack hit probability success percentage In D&D players roll a 20 sided die trying to beat a set number to determine if an attack hits the target. Players often can add modifiers to this roll to help the odds in reaching this target number. If the target number (enemy armor level) is passed by the attack roll, damage is done to the target which requires a different roll depending on the power of the attack. If the armor level is matched for that attack roll, damage is calculated like normal (rolling dice, adding modifiers) and then halved, rounding down to the nearest integer.
One of my spells allows me to do three attacks at once on one creature, and on a hit deals 2 6-sided dice +2 damage.
It so happened I used this spell on my "Ally" and I'm trying to figure out what my chances of actually killing him were.
I roll a 1d20 (1 20-sided die) and add +4 to the roll and if that result is greater than or equal to 16 (my 'Allies' Armor level), I roll damage which is 2d6+2 (halfing then rounding down the damage if the attack equaled Armor level). That damage result is then subtracted from my 'Allies' starting Health which is 20.
I repeat this 2 more times, adding damage on each hit. If his health reduces to 0 then he is dead. If his health is 1 or more by the end of this attack he lives and gets to attack me.
I want to know, statistically what percentage of time will my Ally be reduced to 0 health after doing this spell?
 A: One way to get at this fairly simply is just through simulation - you won't get the exact percentage to the second decimal, but you can nail it down very closely. I've input some R code below that will simulate the rolls you're making and spit out the probability that your ally dies.
# Creating a hundred thousand sets of your three rolls to hit     
roll.1 <- sample(1:20, replace = TRUE, 100000)
roll.2 <- sample(1:20, replace = TRUE, 100000)
roll.3 <- sample(1:20, replace = TRUE, 100000)

# Creating a hundred thousand sets of three damage rolls
damage.1 <- replicate(100000, (sample(1:6, 1) + sample(1:6, 1) + 2))
damage.2 <- replicate(100000, (sample(1:6, 1) + sample(1:6, 1) + 2))
damage.3 <- replicate(100000, (sample(1:6, 1) + sample(1:6, 1) + 2))

# Here we calculate the damage of each roll. Essentially this line is saying
# "Apply the full damage if the hit roll was 13 or more (13 + 4 = 17), and 
# apply half the damage if the roll was 12." Applying zero damage when the roll
# was less than 12 is implicit here.
hurt.1 <- ((roll.1 >= 13) * damage.1 + floor((roll.1 == 12) * damage.1 * .5))
hurt.2 <- ((roll.2 >= 13) * damage.2 + floor((roll.2 == 12) * damage.2 * .5))
hurt.3 <- ((roll.3 >= 13) * damage.3 + floor((roll.3 == 12) * damage.3 * .5))

# Now we just subtract the total damage from the health
health <- 20 - (hurt.1 + hurt.2 + hurt.3)

# And this gives the percentage of the time you'd kill your ally.
sum(health <= 0)/1000000

When I run this, I consistently get between 16.8% and 17.2%. So you had about a 17% chance of killing your ally with this spell.
If you're interested, the below code also computes the exact probability using the method outlined in Micah's answer. It turns out the exact probability is 16.99735%
# Get a vector of the probability to hit 0, 1, 2, and 3 times. Since you can
# only kill him if you get 2 hits or more, we only need the latter 2 probabilities
hit.times <- (dbinom(0:3, 3, 9/20))

# We'll be making extensive use of R's `outer` function, which gives us all
# combinations of adding or multiplying various numbers - useful for dice 
# rolling
damage.prob <- table(outer(1:6, 1:6, FUN = "+") + 2)/36

damage.prob <- data.frame(damage.prob)
colnames(damage.prob) <- c("Damage", "Prob")
damage.prob$Damage <- as.numeric(as.character(damage.prob$Damage))

# Since we'll be multiplying by the probability to hit each number of times 
# later, we just use 8/9 as the probability to get full damage, and 1/9 as 
# the probability of half damage.
damage.prob.full <- data.frame("Damage" = damage.prob$Damage, "Prob" = damage.prob$Prob * 8/9)
damage.prob.half <- data.frame("Damage" = damage.prob$Damage * .5, "Prob" = damage.prob$Prob * 1/9)

# Rounding down the half damage
damage.prob.half$Damage <- floor(damage.prob.half$Damage)
damage.prob.half <- aggregate(damage.prob.half$Prob, by = list(damage.prob.half$Damage), FUN = sum)
colnames(damage.prob.half) <- c("Damage", "Prob")

damage.prob.total <- merge(damage.prob.full, damage.prob.half, by = "Damage", all.x = TRUE, all.y = TRUE)
damage.prob.total$Prob <- rowSums(cbind(damage.prob.total$Prob.x, damage.prob.total$Prob.y), na.rm=TRUE)

# Below I'm multiplying out all the damage probabilities for 2 and 3 hits, then
# summing the probabilities of getting each damage total that equals 20 or more.

damage.2 <- outer(damage.prob.total$Damage, damage.prob.total$Damage, FUN = '+')
prob.kill.2 <- sum(outer(damage.prob.total$Prob, damage.prob.total$Prob)[damage.2 >= 20])

damage.3 <- outer(outer(damage.prob.total$Damage, damage.prob.total$Damage, FUN = "+"), damage.prob.total$Damage, FUN = "+")

prob.kill.3 <- outer(outer(damage.prob.total$Prob, damage.prob.total$Prob), damage.prob.total$Prob)[damage.3 >= 20]

# Now we just multiply the probability of killing with 2 hits by the probability
# of hitting twice, and the same for 3 hits. Adding that together we get the 
# answer.

sum(prob.kill.2)*hit.times[3] + sum(prob.kill.3)*hit.times[4]

