-
Notifications
You must be signed in to change notification settings - Fork 0
/
world.go
129 lines (109 loc) · 1.76 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
package cible
import (
"fmt"
"strings"
)
func Earth() World {
return World{
Areas: Areas{Spaceport()},
}
}
type World struct {
Areas
}
type Areas []*Area
func (me Areas) Area(id Ident) (*Area, error) {
for _, a := range me {
if a.Ident == id {
return a, nil
}
}
return nil, fmt.Errorf("area %q not found", id)
}
type Area struct {
Ident
Title
Tiles
}
func (a *Area) Tile(id Ident) (*Tile, error) {
for _, t := range a.Tiles {
if t.Ident == id {
return t, nil
}
}
return nil, fmt.Errorf("tile %q not found", id)
}
func (a *Area) AddTile(tiles ...*Tile) {
for _, t := range tiles {
a.Tiles = append(a.Tiles, t)
t.Ident.SetIdent(fmt.Sprintf("t%d", len(a.Tiles)))
}
}
type Tiles []*Tile
type Tile struct {
Ident
Short
Long
Nav
}
func (t *Tile) String() string {
return fmt.Sprintf("%s %s", t.Ident, t.Short)
}
func (me *Tile) Link(to ...interface{}) {
for i := 0; i < len(to); i += 2 {
t := to[i].(*Tile)
d := to[i+1].(Direction)
if me.Nav[d] != "" {
if me.Nav[d] == t.Ident {
continue // already linked
}
panic(
fmt.Sprintf(
"cannot link %s, %s already linked to %v",
me.String(), d.String(), me.Nav[d],
),
)
}
// link in both directions
me.Nav[d] = t.Ident
t.Nav[opposite[d]] = me.Ident
}
}
type Nav [8]Ident
func (n Nav) String() string {
var res []string
for d, id := range n {
if id != "" {
res = append(res, Direction(d).String()+":"+string(id))
}
}
return strings.Join(res, " ")
}
type Direction int
const (
N Direction = iota
NE
E
SE
S
SW
W
NW
)
var opposite = [8]Direction{
N: S,
NE: SW,
E: W,
SE: NW,
S: N,
SW: NE,
W: E,
NW: SE,
}
type Name string
func (me *Name) SetName(v string) {
*me = Name(v)
}
type Short string
type Long string
type Title string