### Source Code

- package main
- import (
- "fmt"
- "math/rand"
- )
- func dice_roll() int {
- return rand.Intn(6)+1
- }
- func blunderbuss(tohit int, short int, mh int, bf int) int {
- r := dice_roll()
- if (r == 6) {
- return 1+mh+bf
- }
- if (r >= tohit) {
- return 1+mh
- }
- if (short > 0 && r == 1) {
- r := dice_roll()
- if (r == 6) {
- return 1+mh+bf
- }
- if (r >= tohit) {
- return 1+mh
- }
- }
- return 0
- }
- func bombardier(tohit int, bf int) int {
- num := dice_roll()
- hits := 0
- for i := 0; i < num; i++ {
- r := dice_roll()
- if (r == 6) {
- hits += 1+bf
- } else if (r >= tohit) {
- hits++
- }
- }
- return hits
- }
- func blunderbuss_unit(num int, tohit int, short int, mh int, bf int) int {
- hits := 0
- for i := 0; i < num; i++ {
- hits += blunderbuss(tohit,short,mh,bf)
- }
- return hits
- }
- func bombardier_unit(num int, tohit int, bf int) int {
- hits := 0
- for i := 0; i < num; i++ {
- hits += bombardier(tohit,bf)
- }
- return hits
- }
- func main() {
- var r = make(map[int]int)
- count := 0
- sum := 0
- for i := 0; i < 1000000000; i++ {
- t := blunderbuss_unit(20,4,1,1,1)
- r[t]++
- count++
- sum += t
- }
- fmt.Printf("# Number of samples: %e\n", float64(count))
- fmt.Printf("# Average value: %f\n", float64(sum)/float64(count))
- for key, value := range r {
- fmt.Printf("%e %d\n", float64(value)/float64(count), key)
- }
- }

This is golang program that outputs CSV with 2 columns: probability and number of hits. You should need max 2hours to learn how to run it and use it

ps. 1B of iteration is way too much to start with, 1M is more then enough to have some insights.