-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworld.go
147 lines (127 loc) · 3.6 KB
/
world.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
package main
import "math/rand"
// World represents our world as a 2-dimensional grid
// and a user-controlled player
type World struct {
Grid [][]Entity
Enemies []*Enemy
Player Player
}
// PlaceEntity places an entity on the world grid at
// the entity's current position as long as there isn't
// an existing entity occupying the grid position
func (w *World) PlaceEntity(e Entity) bool {
x, y := e.GetPosition()
if w.Grid[y][x] == nil {
w.Grid[y][x] = e
return true
}
return false
}
// ClearCellAt removes any entity from the cell position (x, y)
func (w *World) ClearCellAt(x, y int) {
w.Grid[y][x] = nil
}
// GetCellAt returns the entity at the cell position (x, y)
func (w *World) GetCellAt(x, y int) *Entity {
return &w.Grid[y][x]
}
// MovePlayer will attempt to update the position of a player
// based on the incoming direction. Passes the contents of the cell
// in the would-be new position as the player's awareness
func (w *World) MovePlayer(d int) bool {
var vx, vy int
switch d {
case UP:
vx = 0
vy = -1
case RIGHT:
vx = 1
vy = 0
case DOWN:
vx = 0
vy = 1
case LEFT:
vx = -1
vy = 0
}
x, y := w.Player.GetPosition()
cell := *w.GetCellAt(x+vx, y+vy)
return w.Player.UpdatePosition(d, cell)
}
// NewWorld initializes and returns a World. Responsible for
// drawing the world border and placing the player in their
// starting position
func NewWorld(width, height int, p Player, o *GameOptions) *World {
grid := make([][]Entity, height)
for i := range grid {
grid[i] = make([]Entity, width)
}
w := &World{
Grid: grid,
Player: p,
Enemies: make([]*Enemy, o.Enemies),
}
w.PlaceEntity(p)
placeBorders(w)
placeMountainRanges(width, height, o.Mountains, w)
placeEnemies(width, height, o.Enemies, w)
return w
}
/*****************************************************************************
* Helper Functions for Borders *
*****************************************************************************/
func placeBorders(w *World) {
for i := range w.Grid {
if i == 0 || i == len(w.Grid)-1 {
for k := range w.Grid[i] {
border := NewStaticBorder(k, i)
w.PlaceEntity(border)
}
} else {
leftBorder := NewStaticBorder(0, i)
rightBorder := NewStaticBorder(len(w.Grid[i])-1, i)
w.PlaceEntity(leftBorder)
w.PlaceEntity(rightBorder)
}
}
}
/*****************************************************************************
* Helper Functions for Enemies *
*****************************************************************************/
func placeEnemies(width, height, enemies int, w *World) {
i := 0
for i < enemies {
x := rand.Intn(width)
y := rand.Intn(height)
if *w.GetCellAt(x, y) == nil {
w.Enemies[i] = NewEnemy(x, y)
w.PlaceEntity(w.Enemies[i])
i++
}
}
}
/*****************************************************************************
* Helper Functions for Mountain Ranges *
*****************************************************************************/
func placeMountainRanges(width, height, ranges int, w *World) {
mtnRangeWidth := 5
mtnRangeHeight := 5
for i := 0; i < ranges; i++ {
x := rand.Intn(width-mtnRangeWidth-1) + 1
y := rand.Intn(height-mtnRangeHeight-1) + 1
placeMountain(x, y, mtnRangeWidth, mtnRangeHeight, w)
}
}
func placeMountain(x, y, width, height int, w *World) {
grid := make([][]int, width)
for i := range grid {
grid[i] = make([]int, height)
for j := range grid[i] {
if rand.Intn(6) < 3 {
mountain := NewStaticMountain(x+i, y+j)
w.PlaceEntity(mountain)
}
}
}
}