types.go raw

   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