-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcity.go
111 lines (88 loc) · 2.54 KB
/
city.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
package main
import (
"errors"
"fmt"
"strings"
)
// An City represents set of attributes that belongs to a city
type City struct {
name string
neighbours map[Direction]*City
residents map[string]*Alien
destroyed bool
}
// NewCity returns object of city
func NewCity(name string) *City {
return &City{
name: name,
neighbours: make(map[Direction]*City),
residents: make(map[string]*Alien),
}
}
// SetNeighbour function sets neighbour of current city to provided city
func (c *City) SetNeighbour(direction Direction, city *City) error {
if city == c {
return fmt.Errorf("City `%s` cannot be the neighbour of itself", c.name)
}
for direction, neighbour := range c.neighbours {
if city == neighbour {
if _, ok := c.neighbours[direction]; ok && c.neighbours[direction] == city {
return nil
}
return fmt.Errorf("City `%s` is already a neighbour to city `%s`", city.name, c.name)
}
}
c.neighbours[direction] = city
city.neighbours[*direction.inverse] = c
return nil
}
// GetNeighbour returns a neighbour of current city
func (c *City) GetNeighbour() (*City, error) {
// [TODO] Add random logic
for _, value := range c.neighbours {
return value, nil
}
return nil, errors.New("No neighbour found")
}
// AddResident adds a new alien as resident of current city
func (c *City) AddResident(alien *Alien) {
if _, ok := c.residents[alien.name]; ok {
return
}
c.residents[alien.name] = alien
}
// DeleteResident deletes resident (alien) from current city
func (c *City) DeleteResident(alien *Alien) {
delete(c.residents, alien.name)
}
// Destroy function completely destroy current city and removes its reference from its neighbours
func (c *City) Destroy() {
for direction, city := range c.neighbours {
delete(city.neighbours, *direction.inverse)
}
c.neighbours = make(map[Direction]*City)
c.destroyed = true
names := []string{}
for name := range c.residents {
c.residents[name].Destroy()
names = append(names, name)
}
fmt.Printf("\n%s has been destroyed by %s\n", c.name, strings.Join(names[:], ", "))
}
func (c *City) String() string {
if c.destroyed {
return fmt.Sprintf("City %s is destroyed!", c.name)
}
return fmt.Sprintf("City %s %s", c.name, c.neighbourString())
}
func (c *City) neighbourString() string {
var neighbours []string
for direction := range c.neighbours {
name := "None"
if _, ok := c.neighbours[direction]; ok {
name = c.neighbours[direction].name
}
neighbours = append(neighbours, fmt.Sprintf("%v=%v", direction.name, name))
}
return strings.Join(neighbours, " ")
}