diff --git a/cmd/rove/main.go b/cmd/rove/main.go index c9e0691..9497573 100644 --- a/cmd/rove/main.go +++ b/cmd/rove/main.go @@ -134,7 +134,7 @@ func InnerMain(command string) error { return fmt.Errorf("Server returned failure: %s", response.Error) } else { - fmt.Printf("Spawned at position %+v\n", response.Position) + fmt.Printf("Spawned rover with attributes %+v\n", response.Attributes) } case "move": @@ -184,7 +184,7 @@ func InnerMain(command string) error { return fmt.Errorf("Server returned failure: %s", response.Error) } else { - fmt.Printf("position: %v\n", response.Position) + fmt.Printf("attributes: %v\n", response.Attributes) } default: diff --git a/go.mod b/go.mod index a70d6e1..6d4da8d 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,5 @@ require ( github.com/gorilla/mux v1.7.4 github.com/robfig/cron v1.2.0 github.com/stretchr/testify v1.6.0 + github.com/tjarratt/babble v0.0.0-20191209142150-eecdf8c2339d ) diff --git a/go.sum b/go.sum index 709e988..1ae6bb1 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfm github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tjarratt/babble v0.0.0-20191209142150-eecdf8c2339d h1:b7oHBI6TgTdCDuqTijsVldzlh+6cfQpdYLz1EKtCAoY= +github.com/tjarratt/babble v0.0.0-20191209142150-eecdf8c2339d/go.mod h1:O5hBrCGqzfb+8WyY8ico2AyQau7XQwAfEQeEQ5/5V9E= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/game/command_test.go b/pkg/game/command_test.go index 830727f..fcdb9ce 100644 --- a/pkg/game/command_test.go +++ b/pkg/game/command_test.go @@ -29,8 +29,8 @@ func TestCommand_Move(t *testing.T) { // Tick the world world.ExecuteCommandQueues() - newpos, err := world.RoverPosition(a) + newatributes, err := world.RoverAttributes(a) assert.NoError(t, err, "Failed to set position for rover") pos.Add(Vector{0.0, duration * attribs.Speed}) // We should have moved duration*speed north - assert.Equal(t, pos, newpos, "Failed to correctly set position for rover") + assert.Equal(t, pos, newatributes.Pos, "Failed to correctly set position for rover") } diff --git a/pkg/game/world.go b/pkg/game/world.go index 2f322dd..85a8bf2 100644 --- a/pkg/game/world.go +++ b/pkg/game/world.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/google/uuid" + "github.com/tjarratt/babble" ) // World describes a self contained universe and everything in it @@ -22,27 +23,6 @@ type World struct { cmdMutex sync.RWMutex } -// RoverAttributes contains attributes of a rover -type RoverAttributes struct { - // Speed represents the Speed that the rover will move per second - Speed int `json:"speed"` - - // Range represents the distance the unit's radar can see - Range int `json:"range"` -} - -// Rover describes a single rover in the world -type Rover struct { - // Id is a unique ID for this rover - Id uuid.UUID `json:"id"` - - // Pos represents where this rover is in the world - Pos Vector `json:"pos"` - - // Attributes represents the physical attributes of the rover - Attributes RoverAttributes `json:"attributes"` -} - // NewWorld creates a new world object func NewWorld() *World { return &World{ @@ -59,14 +39,14 @@ func (w *World) SpawnRover() uuid.UUID { // Initialise the rover rover := Rover{ Id: uuid.New(), - - // TODO: Set this somehow - Pos: Vector{}, - - // TODO: Stop these being random numbers Attributes: RoverAttributes{ + Speed: 1.0, Range: 20.0, + Pos: Vector{}, + + // Set the name randomly + Name: babble.NewBabbler().Babble(), }, } @@ -101,25 +81,13 @@ func (w *World) RoverAttributes(id uuid.UUID) (RoverAttributes, error) { } } -// RoverPosition returns the position of a given rover -func (w *World) RoverPosition(id uuid.UUID) (Vector, error) { - w.worldMutex.RLock() - defer w.worldMutex.RUnlock() - - if i, ok := w.Rovers[id]; ok { - return i.Pos, nil - } else { - return Vector{}, fmt.Errorf("no rover matching id") - } -} - // WarpRover sets an rovers position func (w *World) WarpRover(id uuid.UUID, pos Vector) error { w.worldMutex.Lock() defer w.worldMutex.Unlock() if i, ok := w.Rovers[id]; ok { - i.Pos = pos + i.Attributes.Pos = pos w.Rovers[id] = i return nil } else { @@ -128,7 +96,7 @@ func (w *World) WarpRover(id uuid.UUID, pos Vector) error { } // SetPosition sets an rovers position -func (w *World) MoveRover(id uuid.UUID, bearing Direction) (Vector, error) { +func (w *World) MoveRover(id uuid.UUID, bearing Direction) (RoverAttributes, error) { w.worldMutex.Lock() defer w.worldMutex.Unlock() @@ -140,13 +108,13 @@ func (w *World) MoveRover(id uuid.UUID, bearing Direction) (Vector, error) { move := bearing.Vector().Multiplied(distance) // Increment the position by the movement - i.Pos.Add(move) + i.Attributes.Pos.Add(move) // Set the rover values to the new ones w.Rovers[id] = i - return i.Pos, nil + return i.Attributes, nil } else { - return Vector{}, fmt.Errorf("no rover matching id") + return RoverAttributes{}, fmt.Errorf("no rover matching id") } } @@ -166,8 +134,8 @@ func (w *World) RadarFromRover(id uuid.UUID) (RadarDescription, error) { // Gather nearby rovers within the range for _, r2 := range w.Rovers { - if r1.Id != r2.Id && r1.Pos.Distance(r2.Pos) < float64(r1.Attributes.Range) { - desc.Rovers = append(desc.Rovers, r2.Pos) + if r1.Id != r2.Id && r1.Attributes.Pos.Distance(r2.Attributes.Pos) < float64(r1.Attributes.Range) { + desc.Rovers = append(desc.Rovers, r2.Attributes.Pos) } } diff --git a/pkg/game/world_test.go b/pkg/game/world_test.go index 3b37908..b33662d 100644 --- a/pkg/game/world_test.go +++ b/pkg/game/world_test.go @@ -67,16 +67,16 @@ func TestWorld_GetSetMovePosition(t *testing.T) { err = world.WarpRover(a, pos) assert.NoError(t, err, "Failed to set position for rover") - newpos, err := world.RoverPosition(a) + newAttribs, err := world.RoverAttributes(a) assert.NoError(t, err, "Failed to set position for rover") - assert.Equal(t, pos, newpos, "Failed to correctly set position for rover") + assert.Equal(t, pos, newAttribs.Pos, "Failed to correctly set position for rover") bearing := North duration := 1 - newpos, err = world.MoveRover(a, bearing) + newAttribs, err = world.MoveRover(a, bearing) assert.NoError(t, err, "Failed to set position for rover") pos.Add(Vector{0, attribs.Speed * duration}) // We should have move one unit of the speed north - assert.Equal(t, pos, newpos, "Failed to correctly move position for rover") + assert.Equal(t, pos, newAttribs.Pos, "Failed to correctly move position for rover") } func TestWorld_RadarFromRover(t *testing.T) { diff --git a/pkg/rove/api.go b/pkg/rove/api.go index 130e2c4..d47f1c6 100644 --- a/pkg/rove/api.go +++ b/pkg/rove/api.go @@ -66,8 +66,8 @@ type SpawnResponse struct { Success bool `json:"success"` Error string `json:"error,omitempty"` - // The location of the spawned entity - Position game.Vector `json:"position"` + // The attributes of the spawned entity + Attributes game.RoverAttributes `json:"attributes"` } // ============================== @@ -122,6 +122,6 @@ type RoverResponse struct { Success bool `json:"success"` Error string `json:"error,omitempty"` - // The set of positions for nearby rovers - Position game.Vector `json:"position"` + // The current position of this rover + Attributes game.RoverAttributes `json:"attributes"` } diff --git a/pkg/server/routes.go b/pkg/server/routes.go index f06e337..64041ef 100644 --- a/pkg/server/routes.go +++ b/pkg/server/routes.go @@ -126,14 +126,14 @@ func HandleSpawn(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer } else if id, err := uuid.Parse(id); err != nil { response.Error = "Provided account ID was invalid" - } else if pos, rover, err := s.SpawnRoverForAccount(id); err != nil { + } else if attribs, rover, err := s.SpawnRoverForAccount(id); err != nil { response.Error = err.Error() } else { - fmt.Printf("New rover spawned\taccount:%s\trover:%s\tpos:%+v\n", id, rover, pos) + fmt.Printf("New rover spawned\taccount:%s\trover:%s\attributes:%+v\n", id, rover, attribs) response.Success = true - response.Position = pos + response.Attributes = attribs } return response, nil @@ -217,12 +217,12 @@ func HandleRover(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer } else if inst, err := s.accountant.GetRover(id); err != nil { response.Error = fmt.Sprintf("Provided account has no rover: %s", err) - } else if pos, err := s.world.RoverPosition(inst); err != nil { + } else if attribs, err := s.world.RoverAttributes(inst); err != nil { response.Error = fmt.Sprintf("Error getting radar from rover: %s", err) } else { - fmt.Printf("Responded with rover\taccount:%s\trover:%+v\n", id, pos) - response.Position = pos + fmt.Printf("Responded with rover\taccount:%s\trover:%+v\n", id, attribs) + response.Attributes = attribs response.Success = true } diff --git a/pkg/server/routes_test.go b/pkg/server/routes_test.go index 6d46fa0..34929dc 100644 --- a/pkg/server/routes_test.go +++ b/pkg/server/routes_test.go @@ -92,7 +92,7 @@ func TestHandleCommand(t *testing.T) { // Spawn the rover rover for the account _, inst, err := s.SpawnRoverForAccount(a.Id) - pos, err := s.world.RoverPosition(inst) + attribs, err := s.world.RoverAttributes(inst) assert.NoError(t, err, "Couldn't get rover position") data := rove.CommandData{ @@ -127,10 +127,10 @@ func TestHandleCommand(t *testing.T) { // Tick the command queues to progress the move command s.world.ExecuteCommandQueues() - pos2, err := s.world.RoverPosition(inst) + attribs2, err := s.world.RoverAttributes(inst) assert.NoError(t, err, "Couldn't get rover position") - pos.Add(game.Vector{X: 0.0, Y: attrib.Speed * 1}) // Should have moved north by the speed and duration - assert.Equal(t, pos, pos2, "Rover should have moved by bearing") + attribs.Pos.Add(game.Vector{X: 0.0, Y: attrib.Speed * 1}) // Should have moved north by the speed and duration + assert.Equal(t, attribs.Pos, attribs2.Pos, "Rover should have moved by bearing") } func TestHandleRadar(t *testing.T) { diff --git a/pkg/server/server.go b/pkg/server/server.go index f853d67..089f9b8 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -258,10 +258,10 @@ func (s *Server) wrapHandler(method string, handler Handler) func(w http.Respons } // SpawnRoverForAccount spawns the rover rover for an account -func (s *Server) SpawnRoverForAccount(accountid uuid.UUID) (game.Vector, uuid.UUID, error) { +func (s *Server) SpawnRoverForAccount(accountid uuid.UUID) (game.RoverAttributes, uuid.UUID, error) { inst := s.world.SpawnRover() - if pos, err := s.world.RoverPosition(inst); err != nil { - return game.Vector{}, uuid.UUID{}, fmt.Errorf("No position found for created rover") + if attribs, err := s.world.RoverAttributes(inst); err != nil { + return game.RoverAttributes{}, uuid.UUID{}, fmt.Errorf("No attributes found for created rover") } else { if err := s.accountant.AssignRover(accountid, inst); err != nil { @@ -270,9 +270,9 @@ func (s *Server) SpawnRoverForAccount(accountid uuid.UUID) (game.Vector, uuid.UU fmt.Printf("Failed to destroy rover after failed rover assign: %s", err) } - return game.Vector{}, uuid.UUID{}, err + return game.RoverAttributes{}, uuid.UUID{}, err } else { - return pos, inst, nil + return attribs, inst, nil } } }