You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ddchar.go 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "sort"
  6. "time"
  7. "util"
  8. )
  9. type Class struct {
  10. Name string
  11. HitDie int
  12. StatPriority []string
  13. }
  14. type Race struct {
  15. Name string
  16. Str int
  17. Dex int
  18. Con int
  19. Int int
  20. Wis int
  21. Cha int
  22. Features []string
  23. }
  24. type Player struct {
  25. Name string
  26. Class *Class
  27. Race *Race
  28. Stats map[string]int
  29. }
  30. func choiceClass(ary []Class) Class {
  31. r := rand.Intn(len(ary))
  32. return ary[r]
  33. }
  34. func choiceRace(ary []Race) Race {
  35. r := rand.Intn(len(ary))
  36. return ary[r]
  37. }
  38. func stats() []int {
  39. rolls := make([]int, 6)
  40. for i := 0; i < 6; i++ {
  41. thisRoll := util.Roll(4, 6)
  42. for k, v := range thisRoll {
  43. // fmt.Println(thisRoll)
  44. for v == 1 {
  45. // fmt.Println("Replacing 1")
  46. newv := util.Roll(1, 6)
  47. thisRoll[k] = newv[0]
  48. v = newv[0]
  49. }
  50. }
  51. sort.Ints(thisRoll)
  52. top3 := make([]int, 3)
  53. copy(top3, thisRoll[1:])
  54. rolls[i] = util.Sum(top3)
  55. }
  56. return rolls
  57. }
  58. func pickClass() *Class {
  59. barbarian := Class{"Barbarian", 12, []string{"Int", "Wis", "Cha", "Dex", "Con", "Str"}}
  60. bard := Class{"Bard", 8, []string{"Str", "Con", "Wis", "Int", "Dex", "Cha"}}
  61. cleric := Class{"Cleric", 8, []string{"Dex", "Int", "Cha", "Str", "Con", "Wis"}}
  62. druid := Class{"Druid", 8, []string{"Cha", "Str", "Dex", "Int", "Con", "Wis"}}
  63. fighter_arch := Class{"Fighter", 10, []string{"Int", "Cha", "Wis", "Str", "Con", "Dex"}}
  64. fighter_melee := Class{"Fighter", 10, []string{"Int", "Cha", "Wis", "Dex", "Con", "Str"}}
  65. monk := Class{"Monk", 8, []string{"Cha", "Int", "Str", "Con", "Wis", "Dex"}}
  66. paladin := Class{"Paladin", 10, []string{"Dex", "Int", "Wis", "Con", "Cha", "Str"}}
  67. ranger := Class{"Ranger", 10, []string{"Cha", "Int", "Con", "Str", "Wis", "Dex"}}
  68. rogue := Class{"Rogue", 8, []string{"Wis", "Str", "Con", "Int", "Cha", "Dex"}}
  69. sorcerer := Class{"Sorcerer", 6, []string{"Str", "Dex", "Wis", "Int", "Con", "Cha"}}
  70. warlock := Class{"Warlock", 8, []string{"Str", "Dex", "Wis", "Int", "Con", "Cha"}}
  71. wizard := Class{"Wizard", 6, []string{"Str", "Dex", "Cha", "Con", "Wis", "Int"}}
  72. classlist := []Class{barbarian, bard, cleric, druid, fighter_arch, fighter_melee, monk, paladin, ranger, rogue, sorcerer, warlock, wizard}
  73. rclass := choiceClass(classlist)
  74. return &rclass
  75. }
  76. func (hmn *Race) humanAttr() {
  77. for i := 0; i < 2; i++ {
  78. switch r := rand.Intn(6); r {
  79. case 0:
  80. hmn.Str++
  81. case 1:
  82. hmn.Dex++
  83. case 2:
  84. hmn.Con++
  85. case 3:
  86. hmn.Int++
  87. case 4:
  88. hmn.Wis++
  89. case 5:
  90. hmn.Cha++
  91. }
  92. }
  93. }
  94. func pickRace() *Race {
  95. dragonborn := Race{"Dragonborn", 2, 0, 0, 0, 0, 1, []string{"Draconic Ancestry", "Breath Weapon", "Damage Resistance"}}
  96. dwarf := Race{"Dwarf", 0, 0, 2, 0, 0, 0, []string{"Darkvision", "Dwarven Resilience", "Dwarven Combat Training", "Stonecunning"}}
  97. elf := Race{"Elf", 0, 2, 0, 0, 0, 0, []string{"Darkvision", "Keen Senses", "Fey Ancestry", "Trance"}}
  98. gnome := Race{"Gnome", 0, 0, 0, 2, 0, 0, []string{"Darkvision", "Gnome Cunning"}}
  99. halfelf := Race{"Half-Elf", 0, 0, 0, 0, 0, 2, []string{"Darkvision", "Fey Ancestry", "Skill Versatility"}}
  100. halfling := Race{"Halfling", 0, 2, 0, 0, 0, 0, []string{"Lucky", "Brave", "Halfling Nimbleness"}}
  101. halforc := Race{"Half-Orc", 2, 0, 1, 0, 0, 0, []string{"Darkvision", "Menacing", "Relentless Endurance", "Savage Attacks"}}
  102. human := Race{"Human", 1, 1, 1, 1, 1, 1, []string{"Extra Language"}}
  103. tiefling := Race{"Tiefling", 0, 0, 0, 1, 0, 2, []string{"Darkvision", "Hellish Resistance", "Infernal Legacy"}}
  104. racelist := []Race{dragonborn, dwarf, elf, gnome, halfelf, halfling, halforc, human, tiefling}
  105. rrace := choiceRace(racelist)
  106. if rrace.Name == "Half-Elf" {
  107. rrace.humanAttr()
  108. }
  109. return &rrace
  110. }
  111. func main() {
  112. rand.Seed(time.Now().UnixNano()) // Keep this the first line in main()
  113. fmt.Println("=== Generated D&D character ===")
  114. rolls := stats()
  115. fmt.Println("Rolls: ", rolls)
  116. sort.Ints(rolls)
  117. ply := Player{util.Namegen(), pickClass(), pickRace(), make(map[string]int)}
  118. for k, v := range ply.Class.StatPriority {
  119. ply.Stats[v] = rolls[k]
  120. }
  121. ply.Stats["Str"] += ply.Race.Str
  122. ply.Stats["Dex"] += ply.Race.Dex
  123. ply.Stats["Con"] += ply.Race.Con
  124. ply.Stats["Int"] += ply.Race.Int
  125. ply.Stats["Wis"] += ply.Race.Wis
  126. ply.Stats["Cha"] += ply.Race.Cha
  127. fmt.Printf("%s - %s %s\n", ply.Name, ply.Race.Name, ply.Class.Name)
  128. fmt.Printf("Str: %d\tInt: %d\nDex: %d\tWis: %d\nCon: %d\tCha: %d\n",
  129. ply.Stats["Str"],
  130. ply.Stats["Int"],
  131. ply.Stats["Dex"],
  132. ply.Stats["Wis"],
  133. ply.Stats["Con"],
  134. ply.Stats["Cha"])
  135. }