Add "broadcast" command
This will send a readable ascii triplet to all rovers in range
This commit is contained in:
parent
30ca488890
commit
d4d82c38e0
4 changed files with 120 additions and 2 deletions
|
@ -12,6 +12,9 @@ const (
|
|||
|
||||
// CommandRecharge Will use one tick to charge the rover
|
||||
CommandRecharge = "recharge"
|
||||
|
||||
// CommandBroadcast will broadcast a message to nearby rovers within range
|
||||
CommandBroadcast = "broadcast"
|
||||
)
|
||||
|
||||
// Command represends a single command to execute
|
||||
|
@ -20,6 +23,9 @@ type Command struct {
|
|||
|
||||
// Used in the move command
|
||||
Bearing string `json:"bearing,omitempty"`
|
||||
|
||||
// Used in the broadcast command
|
||||
Message []byte `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// CommandStream is a list of commands to execute in order
|
||||
|
|
|
@ -168,6 +168,40 @@ func (w *World) RoverRecharge(rover string) (int, error) {
|
|||
return i.Charge, nil
|
||||
}
|
||||
|
||||
// RoverBroadcast broadcasts a message to nearby rovers
|
||||
func (w *World) RoverBroadcast(rover string, message []byte) (err error) {
|
||||
w.worldMutex.Lock()
|
||||
defer w.worldMutex.Unlock()
|
||||
|
||||
i, ok := w.Rovers[rover]
|
||||
if !ok {
|
||||
return fmt.Errorf("Failed to find rover with name: %s", rover)
|
||||
}
|
||||
|
||||
// Use up a charge as needed, if available
|
||||
if i.Charge == 0 {
|
||||
return
|
||||
}
|
||||
i.Charge--
|
||||
|
||||
// Check all rovers
|
||||
for r, rover := range w.Rovers {
|
||||
if rover.Name == i.Name {
|
||||
continue
|
||||
}
|
||||
|
||||
// Check if this rover is within range
|
||||
if i.Pos.Distance(rover.Pos) < float64(i.Range) {
|
||||
rover.AddLogEntryf("recieved %s from %s", string(message), i.Name)
|
||||
w.Rovers[r] = rover
|
||||
}
|
||||
}
|
||||
|
||||
i.AddLogEntryf("broadcasted %s", string(message))
|
||||
w.Rovers[rover] = i
|
||||
return
|
||||
}
|
||||
|
||||
// DestroyRover Removes an rover from the game
|
||||
func (w *World) DestroyRover(rover string) error {
|
||||
w.worldMutex.Lock()
|
||||
|
@ -399,6 +433,15 @@ func (w *World) Enqueue(rover string, commands ...Command) error {
|
|||
if _, err := bearing.FromString(c.Bearing); err != nil {
|
||||
return fmt.Errorf("unknown bearing: %s", c.Bearing)
|
||||
}
|
||||
case CommandBroadcast:
|
||||
if len(c.Message) > 3 {
|
||||
return fmt.Errorf("too many characters in message (limit 3): %d", len(c.Message))
|
||||
}
|
||||
for _, b := range c.Message {
|
||||
if b < 37 || b > 126 {
|
||||
return fmt.Errorf("invalid message character: %c", b)
|
||||
}
|
||||
}
|
||||
case CommandStash:
|
||||
case CommandRepair:
|
||||
case CommandRecharge:
|
||||
|
@ -494,6 +537,10 @@ func (w *World) ExecuteCommand(c *Command, rover string) (err error) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case CommandBroadcast:
|
||||
if err := w.RoverBroadcast(rover, c.Message); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown command: %s", c.Command)
|
||||
}
|
||||
|
|
|
@ -365,3 +365,63 @@ func TestWorld_Daytime(t *testing.T) {
|
|||
world.ExecuteCommandQueues()
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorld_Broadcast(t *testing.T) {
|
||||
world := NewWorld(8)
|
||||
|
||||
a, err := world.SpawnRover()
|
||||
assert.NoError(t, err)
|
||||
|
||||
b, err := world.SpawnRover()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Warp rovers near to eachother
|
||||
assert.NoError(t, world.WarpRover(a, vector.Vector{X: 0, Y: 0}))
|
||||
assert.NoError(t, world.WarpRover(b, vector.Vector{X: 1, Y: 0}))
|
||||
|
||||
// Broadcast from a
|
||||
assert.NoError(t, world.RoverBroadcast(a, []byte{'A', 'B', 'C'}))
|
||||
|
||||
// Check if b heard it
|
||||
ra, err := world.GetRover(a)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, ra.MaximumCharge-1, ra.Charge, "A should have used a charge to broadcast")
|
||||
assert.Contains(t, ra.Logs[len(ra.Logs)-1].Text, "ABC", "Rover B should have heard the broadcast")
|
||||
|
||||
// Check if a logged it
|
||||
rb, err := world.GetRover(b)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rb.Logs[len(rb.Logs)-1].Text, "ABC", "Rover A should have logged it's broadcast")
|
||||
|
||||
// Warp B outside of the range of A
|
||||
assert.NoError(t, world.WarpRover(b, vector.Vector{X: ra.Range, Y: 0}))
|
||||
|
||||
// Broadcast from a again
|
||||
assert.NoError(t, world.RoverBroadcast(a, []byte{'X', 'Y', 'Z'}))
|
||||
|
||||
// Check if b heard it
|
||||
ra, err = world.GetRover(b)
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, ra.Logs[len(ra.Logs)-1].Text, "XYZ", "Rover B should not have heard the broadcast")
|
||||
|
||||
// Check if a logged it
|
||||
rb, err = world.GetRover(a)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rb.Logs[len(rb.Logs)-1].Text, "XYZ", "Rover A should have logged it's broadcast")
|
||||
|
||||
// Warp B outside of the range of A
|
||||
assert.NoError(t, world.WarpRover(b, vector.Vector{X: ra.Range + 1, Y: 0}))
|
||||
|
||||
// Broadcast from a again
|
||||
assert.NoError(t, world.RoverBroadcast(a, []byte{'H', 'J', 'K'}))
|
||||
|
||||
// Check if b heard it
|
||||
ra, err = world.GetRover(b)
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, ra.Logs[len(ra.Logs)-1].Text, "HJK", "Rover B should have heard the broadcast")
|
||||
|
||||
// Check if a logged it
|
||||
rb, err = world.GetRover(a)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, rb.Logs[len(rb.Logs)-1].Text, "HJK", "Rover A should have logged it's broadcast")
|
||||
}
|
||||
|
|
|
@ -66,10 +66,15 @@ message Command {
|
|||
// "stash" - Stashes item at current location in rover inventory
|
||||
// "repair" - Repairs the rover using an inventory object
|
||||
// "recharge" - Waits a tick to add more charge to the rover
|
||||
// "broadcast" - Broadcasts a message to nearby rovers
|
||||
string command = 1;
|
||||
|
||||
// The bearing, example: NE
|
||||
// A bearing, example: NE
|
||||
string bearing = 2;
|
||||
|
||||
// A simple message, must be composed of printable ASCII glyphs (32-126)
|
||||
// maximum of three characters
|
||||
bytes message = 3;
|
||||
}
|
||||
|
||||
message CommandRequest {
|
||||
|
@ -135,7 +140,7 @@ message StatusResponse {
|
|||
// Position of the rover in world coordinates
|
||||
Vector position = 2;
|
||||
|
||||
// The range of this rover's radar
|
||||
// The range of this rover's radar and broadcasting
|
||||
int32 range = 3;
|
||||
|
||||
// The items in the rover inventory
|
||||
|
|
Loading…
Add table
Reference in a new issue