1 package world
2 3 import "fmt"
4 5 const (
6 N = iota
7 E
8 W
9 S
10 kvSep = "="
11 )
12 13 // Dirs are ordered so that `^dir & 3` is the opposite direction:
14 // n=00 e=01 w=10 s=11
15 // `& 3` masks the higher bits out
16 // `^` is bitwise NOT
17 var Dirs = [4]string{"north", "east", "west", "south"}
18 19 type FromName map[string]uint32
20 type FromNumber map[uint32]string
21 22 type Lookup struct {
23 Name FromName
24 Index FromNumber
25 }
26 27 func NewLookup() *Lookup {
28 return &Lookup{
29 Name: FromName{"": 0},
30 Index: FromNumber{0: ""},
31 }
32 }
33 34 func (l *Lookup) Add(name string, index uint32) (err error) {
35 36 // Check for existing entries
37 if n, ok := l.Name[name]; ok {
38 return fmt.Errorf(
39 "name conflict: "+
40 "%s already exists with different index %d from submitted %d",
41 name, n, index,
42 )
43 }
44 // Consuming code only adds new entries as it grows the Cities slice so
45 // this error cannot occur, leaving this here for hypothetical
46 // if n, ok := l.Index[index]; ok {
47 // return fmt.Errorf(
48 // "index conflict: "+
49 // "%d already exists with different name %s from submitted %s",
50 // index, n, name,
51 // )
52 // }
53 54 l.Name[name] = index
55 l.Index[index] = name
56 return
57 }
58 59 // City name is not stored in the structure as the Index is the proper source
60 type City struct {
61 Neighbour [4]uint32
62 }
63 64 type Cities []City
65 66 func NewCities() Cities { return Cities{City{}} }
67 68 type World struct {
69 Length int
70 *Lookup
71 Cities
72 }
73 74 func New() *World {
75 return &World{
76 Length: 1, Lookup: NewLookup(), Cities: NewCities(),
77 }
78 }
79