| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 | package main
import (
	"fmt"
	"math/rand"
	"sort"
	"time"
	"util"
)
type Class struct {
	Name         string
	HitDie       int
	StatPriority []string
}
type Race struct {
	Name     string
	Str      int
	Dex      int
	Con      int
	Int      int
	Wis      int
	Cha      int
	Features []string
}
type Player struct {
	Name  string
	Class *Class
	Race  *Race
	Stats map[string]int
}
func choiceClass(ary []Class) Class {
	r := rand.Intn(len(ary))
	return ary[r]
}
func choiceRace(ary []Race) Race {
	r := rand.Intn(len(ary))
	return ary[r]
}
func stats() []int {
	rolls := make([]int, 6)
	for i := 0; i < 6; i++ {
		thisRoll := util.Roll(4, 6)
		for k, v := range thisRoll {
			// fmt.Println(thisRoll)
			for v == 1 {
				// fmt.Println("Replacing 1")
				newv := util.Roll(1, 6)
				thisRoll[k] = newv[0]
				v = newv[0]
			}
		}
		sort.Ints(thisRoll)
		top3 := make([]int, 3)
		copy(top3, thisRoll[1:])
		rolls[i] = util.Sum(top3)
	}
	return rolls
}
func pickClass() *Class {
	barbarian := Class{"Barbarian", 12, []string{"Int", "Wis", "Cha", "Dex", "Con", "Str"}}
	bard := Class{"Bard", 8, []string{"Str", "Con", "Wis", "Int", "Dex", "Cha"}}
	cleric := Class{"Cleric", 8, []string{"Dex", "Int", "Cha", "Str", "Con", "Wis"}}
	druid := Class{"Druid", 8, []string{"Cha", "Str", "Dex", "Int", "Con", "Wis"}}
	fighter_arch := Class{"Fighter", 10, []string{"Int", "Cha", "Wis", "Str", "Con", "Dex"}}
	fighter_melee := Class{"Fighter", 10, []string{"Int", "Cha", "Wis", "Dex", "Con", "Str"}}
	monk := Class{"Monk", 8, []string{"Cha", "Int", "Str", "Con", "Wis", "Dex"}}
	paladin := Class{"Paladin", 10, []string{"Dex", "Int", "Wis", "Con", "Cha", "Str"}}
	ranger := Class{"Ranger", 10, []string{"Cha", "Int", "Con", "Str", "Wis", "Dex"}}
	rogue := Class{"Rogue", 8, []string{"Wis", "Str", "Con", "Int", "Cha", "Dex"}}
	sorcerer := Class{"Sorcerer", 6, []string{"Str", "Dex", "Wis", "Int", "Con", "Cha"}}
	warlock := Class{"Warlock", 8, []string{"Str", "Dex", "Wis", "Int", "Con", "Cha"}}
	wizard := Class{"Wizard", 6, []string{"Str", "Dex", "Cha", "Con", "Wis", "Int"}}
	classlist := []Class{barbarian, bard, cleric, druid, fighter_arch, fighter_melee, monk, paladin, ranger, rogue, sorcerer, warlock, wizard}
	rclass := choiceClass(classlist)
	return &rclass
}
func (hmn *Race) humanAttr() {
	for i := 0; i < 2; i++ {
		switch r := rand.Intn(6); r {
		case 0:
			hmn.Str++
		case 1:
			hmn.Dex++
		case 2:
			hmn.Con++
		case 3:
			hmn.Int++
		case 4:
			hmn.Wis++
		case 5:
			hmn.Cha++
		}
	}
}
func pickRace() *Race {
	dragonborn := Race{"Dragonborn", 2, 0, 0, 0, 0, 1, []string{"Draconic Ancestry", "Breath Weapon", "Damage Resistance"}}
	dwarf := Race{"Dwarf", 0, 0, 2, 0, 0, 0, []string{"Darkvision", "Dwarven Resilience", "Dwarven Combat Training", "Stonecunning"}}
	elf := Race{"Elf", 0, 2, 0, 0, 0, 0, []string{"Darkvision", "Keen Senses", "Fey Ancestry", "Trance"}}
	gnome := Race{"Gnome", 0, 0, 0, 2, 0, 0, []string{"Darkvision", "Gnome Cunning"}}
	halfelf := Race{"Half-Elf", 0, 0, 0, 0, 0, 2, []string{"Darkvision", "Fey Ancestry", "Skill Versatility"}}
	halfling := Race{"Halfling", 0, 2, 0, 0, 0, 0, []string{"Lucky", "Brave", "Halfling Nimbleness"}}
	halforc := Race{"Half-Orc", 2, 0, 1, 0, 0, 0, []string{"Darkvision", "Menacing", "Relentless Endurance", "Savage Attacks"}}
	human := Race{"Human", 1, 1, 1, 1, 1, 1, []string{"Extra Language"}}
	tiefling := Race{"Tiefling", 0, 0, 0, 1, 0, 2, []string{"Darkvision", "Hellish Resistance", "Infernal Legacy"}}
	racelist := []Race{dragonborn, dwarf, elf, gnome, halfelf, halfling, halforc, human, tiefling}
	rrace := choiceRace(racelist)
	if rrace.Name == "Half-Elf" {
		rrace.humanAttr()
	}
	return &rrace
}
func main() {
	rand.Seed(time.Now().UnixNano()) // Keep this the first line in main()
	fmt.Println("=== Generated D&D character ===")
	rolls := stats()
	fmt.Println("Rolls: ", rolls)
	sort.Ints(rolls)
	ply := Player{util.Namegen(), pickClass(), pickRace(), make(map[string]int)}
	for k, v := range ply.Class.StatPriority {
		ply.Stats[v] = rolls[k]
	}
	ply.Stats["Str"] += ply.Race.Str
	ply.Stats["Dex"] += ply.Race.Dex
	ply.Stats["Con"] += ply.Race.Con
	ply.Stats["Int"] += ply.Race.Int
	ply.Stats["Wis"] += ply.Race.Wis
	ply.Stats["Cha"] += ply.Race.Cha
	fmt.Printf("%s - %s %s\n", ply.Name, ply.Race.Name, ply.Class.Name)
	fmt.Printf("Str: %d\tInt: %d\nDex: %d\tWis: %d\nCon: %d\tCha: %d\n",
		ply.Stats["Str"],
		ply.Stats["Int"],
		ply.Stats["Dex"],
		ply.Stats["Wis"],
		ply.Stats["Con"],
		ply.Stats["Cha"])
}
 |