Add a "wait" command with a number

This commit is contained in:
Marc Di Luzio 2020-07-26 17:09:47 +01:00
parent cec61a9db7
commit bcf71f0bf9
4 changed files with 218 additions and 158 deletions

View file

@ -9,6 +9,15 @@ import (
"github.com/stretchr/testify/assert"
)
func TestCommand_Invalid(t *testing.T) {
w := NewWorld(8)
name, err := w.SpawnRover("")
assert.NoError(t, err)
err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_none})
assert.Error(t, err)
}
func TestCommand_Toggle(t *testing.T) {
w := NewWorld(8)
a, err := w.SpawnRover("")
@ -211,11 +220,31 @@ func TestCommand_Transfer(t *testing.T) {
}
func TestCommand_Invalid(t *testing.T) {
func TestCommand_Wait(t *testing.T) {
w := NewWorld(8)
name, err := w.SpawnRover("")
a, err := w.SpawnRover("")
assert.NoError(t, err)
err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_none})
assert.Error(t, err)
r, err := w.GetRover(a)
assert.NoError(t, err)
assert.Equal(t, roveapi.SailPosition_SolarCharging, r.SailPosition)
err = w.Enqueue(a, &roveapi.Command{Command: roveapi.CommandType_wait, Number: 5}, &roveapi.Command{Command: roveapi.CommandType_toggle})
assert.NoError(t, err)
// Tick 5 times during the wait
for i := 0; i < 5; i++ {
w.Tick()
r, err = w.GetRover(a)
assert.NoError(t, err)
assert.Equal(t, roveapi.SailPosition_SolarCharging, r.SailPosition)
}
// One last tick to do the toggle
w.Tick()
r, err = w.GetRover(a)
assert.NoError(t, err)
assert.Equal(t, roveapi.SailPosition_CatchingWind, r.SailPosition)
}

View file

@ -582,6 +582,10 @@ func (w *World) Enqueue(rover string, commands ...*roveapi.Command) error {
if c.GetBearing() == roveapi.Bearing_BearingUnknown {
return fmt.Errorf("turn command given unknown bearing")
}
case roveapi.CommandType_wait:
if c.GetNumber() <= 0 {
return fmt.Errorf("wait command must be given positie number of ticks to wait")
}
case roveapi.CommandType_toggle:
case roveapi.CommandType_stash:
case roveapi.CommandType_repair:
@ -612,15 +616,16 @@ func (w *World) Tick() {
if len(cmds) != 0 {
// Execute the command
if err := w.ExecuteCommand(cmds[0], rover); err != nil {
if done, err := w.ExecuteCommand(cmds[0], rover); err != nil {
log.Println(err)
// TODO: Report this error somehow
}
// Extract the first command in the queue
// Only if the command queue still has entries
if _, ok := w.CommandQueue[rover]; ok {
w.CommandQueue[rover] = cmds[1:]
} else if done {
// Extract the first command in the queue
// Only if the command queue still has entries (the command may have modified this queue)
if _, ok := w.CommandQueue[rover]; ok {
w.CommandQueue[rover] = cmds[1:]
}
}
} else {
@ -709,46 +714,50 @@ func (w *World) Tick() {
}
// ExecuteCommand will execute a single command
func (w *World) ExecuteCommand(c *roveapi.Command, rover string) (err error) {
func (w *World) ExecuteCommand(c *roveapi.Command, rover string) (done bool, err error) {
log.Printf("Executing command: %+v for %s\n", c.Command, rover)
switch c.Command {
case roveapi.CommandType_toggle:
if _, err := w.RoverToggle(rover); err != nil {
return err
return true, err
}
case roveapi.CommandType_stash:
if _, err := w.RoverStash(rover); err != nil {
return err
return true, err
}
case roveapi.CommandType_repair:
if _, err := w.RoverRepair(rover); err != nil {
return err
return true, err
}
case roveapi.CommandType_broadcast:
if err := w.RoverBroadcast(rover, c.GetData()); err != nil {
return err
return true, err
}
case roveapi.CommandType_turn:
if _, err := w.RoverTurn(rover, c.GetBearing()); err != nil {
return err
return true, err
}
case roveapi.CommandType_salvage:
if _, err := w.RoverSalvage(rover); err != nil {
return err
return true, err
}
case roveapi.CommandType_transfer:
if _, err := w.RoverTransfer(rover); err != nil {
return err
return true, err
}
case roveapi.CommandType_wait:
c.Number--
return c.Number == 0, nil
default:
return fmt.Errorf("unknown command: %s", c.Command)
return true, fmt.Errorf("unknown command: %s", c.Command)
}
return