-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
163 lines (138 loc) · 3.27 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package main
import (
"flag"
"fmt"
"log"
"math/rand"
"time"
)
const (
numberOfOptions = 4
symbolTree = "\u1F33"
symbolMountain = "\u26F0"
symbolWater = "\u1F30"
symbolGem = "\u1F48"
symbolSpace = " "
symbolHealthPotion = "\u2764"
symbolKey = "\u1F51"
symbolTreasureChest = "\u2423"
)
var (
mapSizeX int
mapSizeY int
seed int64
questItems = []string{
symbolKey,
symbolTreasureChest,
}
)
func main() {
flag.Parse()
//Minimum map size - currently based on quest items so the grid size needs to grow to at least incorporate these items.
if !(mapSizeX*mapSizeY >= len(questItems)) {
log.Fatalf("Map size must be greater than the specified rows/columns allow. Size of map: %d, Items needing placement: %d", mapSizeX*mapSizeY, len(questItems))
}
//Determines if a new seed needs creation or use the provided seed
var s int64
if seed == -1 {
s = int64(time.Now().Nanosecond())
defer fmt.Printf("New seed is: %d\n", s)
} else {
s = seed
defer fmt.Printf("Existing seed is: %d\n", s)
}
rand.Seed(s)
workflow(createBlankMap())
}
func workflow(a [][]string) {
placeQuestItems(a)
//Go through map location and tries to place a random item based on the rules.
for x := 0; x < mapSizeX; x++ {
for y := 0; y < mapSizeY; y++ {
if a[x][y] == "" {
a[x][y] = placeGeneralLocation(a, x, y)
}
}
}
//Print out the grid
for i := range a {
fmt.Println(a[i])
}
}
func placeQuestItems(a [][]string) {
for _, qi := range questItems {
//TODO Temporary way to ensure they're placed but should be better to ensure it's impossible to be caught in an infinite loop
var x, y int
for true {
x = rand.Int() % mapSizeX
y = rand.Int() % mapSizeY
if a[x][y] == "" {
break
}
}
a[x][y] = qi
}
}
func placeGeneralLocation(a [][]string, x int, y int) string {
ri := rand.Int() % numberOfOptions
switch ri {
case 0:
return symbolTree
case 1:
if y > 0 && a[x][y-1] == symbolTree {
return placeHelpfulItem()
}
return symbolWater
case 2:
return symbolSpace
case 3:
// A mountain can't be placed directly next to another mountain
if !checkPerimeterIsClear(a, x, y, symbolMountain) {
return symbolSpace
}
return symbolMountain
}
return "X"
}
func placeHelpfulItem() string {
switch rand.Int() % 2 {
case 0:
return symbolHealthPotion
case 1:
return symbolGem
}
return "X"
}
//checkPerimeterIsClear returns true or false on if a specific symbol is left, right, up or down of the current position provided.
func checkPerimeterIsClear(a [][]string, x int, y int, symbol string) bool {
//Check up
if y > 0 && a[x][y-1] == symbol {
return false
}
//Check down
if y < len(a[0])-1 && a[x][y+1] == symbol {
return false
}
//Check left
if x > 0 && a[x-1][y] == symbol {
return false
}
//Check right
if x < len(a)-1 && a[x+1][y] == symbol {
return false
}
return true
}
func createBlankMap() (a [][]string) {
//Sets up the map arrays
for i := 0; i < mapSizeX; i++ {
ta := make([]string, mapSizeY)
a = append(a, ta)
}
return
}
func init() {
flag.IntVar(&mapSizeX, "rows", 10, "Number of rows to be used.")
flag.IntVar(&mapSizeY, "columns", 10, "Number of columns to be used.")
flag.Int64Var(&seed, "seed", -1, "Uses an existing seed if it exits.")
}