Move the Atlas code into it's own package

This commit is contained in:
Marc Di Luzio 2020-06-11 20:42:59 +01:00
parent 8cd7b06c0c
commit faaa556ad0
8 changed files with 44 additions and 35 deletions

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"gopls": {
"buildFlags": ["-tags=integration"]
},
}

View file

@ -13,6 +13,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/mdiluz/rove/pkg/accounts" "github.com/mdiluz/rove/pkg/accounts"
"github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/game" "github.com/mdiluz/rove/pkg/game"
"github.com/mdiluz/rove/pkg/rove" "github.com/mdiluz/rove/pkg/rove"
"github.com/mdiluz/rove/pkg/vector" "github.com/mdiluz/rove/pkg/vector"
@ -144,10 +145,10 @@ func TestHandleRadar(t *testing.T) {
wallPos2 := vector.Vector{X: 1, Y: 1} wallPos2 := vector.Vector{X: 1, Y: 1}
rockPos := vector.Vector{X: 1, Y: 3} rockPos := vector.Vector{X: 1, Y: 3}
emptyPos := vector.Vector{X: -2, Y: -3} emptyPos := vector.Vector{X: -2, Y: -3}
assert.NoError(t, s.world.Atlas.SetTile(wallPos1, game.TileWall)) assert.NoError(t, s.world.Atlas.SetTile(wallPos1, atlas.TileWall))
assert.NoError(t, s.world.Atlas.SetTile(wallPos2, game.TileWall)) assert.NoError(t, s.world.Atlas.SetTile(wallPos2, atlas.TileWall))
assert.NoError(t, s.world.Atlas.SetTile(rockPos, game.TileRock)) assert.NoError(t, s.world.Atlas.SetTile(rockPos, atlas.TileRock))
assert.NoError(t, s.world.Atlas.SetTile(emptyPos, game.TileEmpty)) assert.NoError(t, s.world.Atlas.SetTile(emptyPos, atlas.TileEmpty))
request, _ := http.NewRequest(http.MethodGet, path.Join("/", name, "/radar"), nil) request, _ := http.NewRequest(http.MethodGet, path.Join("/", name, "/radar"), nil)
response := httptest.NewRecorder() response := httptest.NewRecorder()
@ -166,17 +167,17 @@ func TestHandleRadar(t *testing.T) {
radarOrigin := vector.Vector{X: -attrib.Range, Y: -attrib.Range} radarOrigin := vector.Vector{X: -attrib.Range, Y: -attrib.Range}
// Make sure the rover tile is correct // Make sure the rover tile is correct
assert.Equal(t, game.TileRover, status.Tiles[len(status.Tiles)/2]) assert.Equal(t, atlas.TileRover, status.Tiles[len(status.Tiles)/2])
// Check our other tiles // Check our other tiles
wallPos1.Add(radarOrigin.Negated()) wallPos1.Add(radarOrigin.Negated())
wallPos2.Add(radarOrigin.Negated()) wallPos2.Add(radarOrigin.Negated())
rockPos.Add(radarOrigin.Negated()) rockPos.Add(radarOrigin.Negated())
emptyPos.Add(radarOrigin.Negated()) emptyPos.Add(radarOrigin.Negated())
assert.Equal(t, game.TileWall, status.Tiles[wallPos1.X+wallPos1.Y*scope]) assert.Equal(t, atlas.TileWall, status.Tiles[wallPos1.X+wallPos1.Y*scope])
assert.Equal(t, game.TileWall, status.Tiles[wallPos2.X+wallPos2.Y*scope]) assert.Equal(t, atlas.TileWall, status.Tiles[wallPos2.X+wallPos2.Y*scope])
assert.Equal(t, game.TileRock, status.Tiles[rockPos.X+rockPos.Y*scope]) assert.Equal(t, atlas.TileRock, status.Tiles[rockPos.X+rockPos.Y*scope])
assert.Equal(t, game.TileEmpty, status.Tiles[emptyPos.X+emptyPos.Y*scope]) assert.Equal(t, atlas.TileEmpty, status.Tiles[emptyPos.X+emptyPos.Y*scope])
} }

View file

@ -1,4 +1,4 @@
package game package atlas
import ( import (
"fmt" "fmt"

View file

@ -1,4 +1,4 @@
package game package atlas
import ( import (
"testing" "testing"

View file

@ -1,4 +1,4 @@
package game package atlas
// Tile represents the type of a tile on the map // Tile represents the type of a tile on the map
type Tile byte type Tile byte

View file

@ -9,6 +9,7 @@ import (
"sync" "sync"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/bearing"
"github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/vector" "github.com/mdiluz/rove/pkg/vector"
@ -21,7 +22,7 @@ type World struct {
Rovers map[uuid.UUID]Rover `json:"rovers"` Rovers map[uuid.UUID]Rover `json:"rovers"`
// Atlas represends the world map of chunks and tiles // Atlas represends the world map of chunks and tiles
Atlas Atlas `json:"atlas"` Atlas atlas.Atlas `json:"atlas"`
// Mutex to lock around all world operations // Mutex to lock around all world operations
worldMutex sync.RWMutex worldMutex sync.RWMutex
@ -42,7 +43,7 @@ func NewWorld(size, chunkSize int) *World {
Rovers: make(map[uuid.UUID]Rover), Rovers: make(map[uuid.UUID]Rover),
CommandQueue: make(map[uuid.UUID]CommandStream), CommandQueue: make(map[uuid.UUID]CommandStream),
Incoming: make(map[uuid.UUID]CommandStream), Incoming: make(map[uuid.UUID]CommandStream),
Atlas: NewAtlas(size, chunkSize), Atlas: atlas.NewAtlas(size, chunkSize),
} }
} }
@ -88,7 +89,7 @@ func (w *World) SpawnRover() (uuid.UUID, error) {
if tile, err := w.Atlas.GetTile(rover.Attributes.Pos); err != nil { if tile, err := w.Atlas.GetTile(rover.Attributes.Pos); err != nil {
return uuid.Nil, err return uuid.Nil, err
} else { } else {
if tile == TileEmpty { if tile == atlas.TileEmpty {
break break
} else { } else {
// Try and spawn to the east of the blockage // Try and spawn to the east of the blockage
@ -98,7 +99,7 @@ func (w *World) SpawnRover() (uuid.UUID, error) {
} }
// Set the world tile to a rover // Set the world tile to a rover
if err := w.Atlas.SetTile(rover.Attributes.Pos, TileRover); err != nil { if err := w.Atlas.SetTile(rover.Attributes.Pos, atlas.TileRover); err != nil {
return uuid.Nil, err return uuid.Nil, err
} }
@ -117,7 +118,7 @@ func (w *World) DestroyRover(id uuid.UUID) error {
if i, ok := w.Rovers[id]; ok { if i, ok := w.Rovers[id]; ok {
// Clear the tile // Clear the tile
if err := w.Atlas.SetTile(i.Attributes.Pos, TileEmpty); err != nil { if err := w.Atlas.SetTile(i.Attributes.Pos, atlas.TileEmpty); err != nil {
return fmt.Errorf("coudln't clear old rover tile: %s", err) return fmt.Errorf("coudln't clear old rover tile: %s", err)
} }
delete(w.Rovers, id) delete(w.Rovers, id)
@ -167,11 +168,11 @@ func (w *World) WarpRover(id uuid.UUID, pos vector.Vector) error {
// Update the world tile // Update the world tile
if tile, err := w.Atlas.GetTile(pos); err != nil { if tile, err := w.Atlas.GetTile(pos); err != nil {
return fmt.Errorf("coudln't get state of destination rover tile: %s", err) return fmt.Errorf("coudln't get state of destination rover tile: %s", err)
} else if tile == TileRover { } else if tile == atlas.TileRover {
return fmt.Errorf("can't warp rover to occupied tile, check before warping") return fmt.Errorf("can't warp rover to occupied tile, check before warping")
} else if err := w.Atlas.SetTile(pos, TileRover); err != nil { } else if err := w.Atlas.SetTile(pos, atlas.TileRover); err != nil {
return fmt.Errorf("coudln't set rover tile: %s", err) return fmt.Errorf("coudln't set rover tile: %s", err)
} else if err := w.Atlas.SetTile(i.Attributes.Pos, TileEmpty); err != nil { } else if err := w.Atlas.SetTile(i.Attributes.Pos, atlas.TileEmpty); err != nil {
return fmt.Errorf("coudln't clear old rover tile: %s", err) return fmt.Errorf("coudln't clear old rover tile: %s", err)
} }
@ -201,11 +202,11 @@ func (w *World) MoveRover(id uuid.UUID, b bearing.Bearing) (RoverAttributes, err
// Get the tile and verify it's empty // Get the tile and verify it's empty
if tile, err := w.Atlas.GetTile(newPos); err != nil { if tile, err := w.Atlas.GetTile(newPos); err != nil {
return i.Attributes, fmt.Errorf("couldn't get tile for new position: %s", err) return i.Attributes, fmt.Errorf("couldn't get tile for new position: %s", err)
} else if tile == TileEmpty { } else if tile == atlas.TileEmpty {
// Set the world tiles // Set the world tiles
if err := w.Atlas.SetTile(newPos, TileRover); err != nil { if err := w.Atlas.SetTile(newPos, atlas.TileRover); err != nil {
return i.Attributes, fmt.Errorf("coudln't set rover tile: %s", err) return i.Attributes, fmt.Errorf("coudln't set rover tile: %s", err)
} else if err := w.Atlas.SetTile(i.Attributes.Pos, TileEmpty); err != nil { } else if err := w.Atlas.SetTile(i.Attributes.Pos, atlas.TileEmpty); err != nil {
return i.Attributes, fmt.Errorf("coudln't clear old rover tile: %s", err) return i.Attributes, fmt.Errorf("coudln't clear old rover tile: %s", err)
} }
@ -221,7 +222,7 @@ func (w *World) MoveRover(id uuid.UUID, b bearing.Bearing) (RoverAttributes, err
} }
// RadarFromRover can be used to query what a rover can currently see // RadarFromRover can be used to query what a rover can currently see
func (w *World) RadarFromRover(id uuid.UUID) ([]Tile, error) { func (w *World) RadarFromRover(id uuid.UUID) ([]atlas.Tile, error) {
w.worldMutex.RLock() w.worldMutex.RLock()
defer w.worldMutex.RUnlock() defer w.worldMutex.RUnlock()
@ -252,7 +253,7 @@ func (w *World) RadarFromRover(id uuid.UUID) ([]Tile, error) {
} }
// Gather up all tiles within the range // Gather up all tiles within the range
var radar = make([]Tile, radarSpan*radarSpan) var radar = make([]atlas.Tile, radarSpan*radarSpan)
for j := scanMin.Y; j <= scanMax.Y; j++ { for j := scanMin.Y; j <= scanMax.Y; j++ {
for i := scanMin.X; i <= scanMax.X; i++ { for i := scanMin.X; i <= scanMax.X; i++ {
q := vector.Vector{X: i, Y: j} q := vector.Vector{X: i, Y: j}
@ -377,7 +378,7 @@ func (w *World) ExecuteCommand(c *Command, rover uuid.UUID) (finished bool, err
} }
// PrintTiles simply prints the input tiles directly for debug // PrintTiles simply prints the input tiles directly for debug
func PrintTiles(tiles []Tile) { func PrintTiles(tiles []atlas.Tile) {
num := int(math.Sqrt(float64(len(tiles)))) num := int(math.Sqrt(float64(len(tiles))))
for j := num - 1; j >= 0; j-- { for j := num - 1; j >= 0; j-- {
for i := 0; i < num; i++ { for i := 0; i < num; i++ {

View file

@ -3,6 +3,7 @@ package game
import ( import (
"testing" "testing"
"github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/bearing"
"github.com/mdiluz/rove/pkg/vector" "github.com/mdiluz/rove/pkg/vector"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -87,7 +88,7 @@ func TestWorld_GetSetMovePosition(t *testing.T) {
assert.Equal(t, pos, newAttribs.Pos, "Failed to correctly move position for rover") assert.Equal(t, pos, newAttribs.Pos, "Failed to correctly move position for rover")
// Place a tile in front of the rover // Place a tile in front of the rover
assert.NoError(t, world.Atlas.SetTile(vector.Vector{X: 0, Y: 2}, TileWall)) assert.NoError(t, world.Atlas.SetTile(vector.Vector{X: 0, Y: 2}, atlas.TileWall))
newAttribs, err = world.MoveRover(a, b) newAttribs, err = world.MoveRover(a, b)
assert.Equal(t, pos, newAttribs.Pos, "Failed to correctly not move position for rover into wall") assert.Equal(t, pos, newAttribs.Pos, "Failed to correctly not move position for rover into wall")
} }
@ -134,12 +135,12 @@ func TestWorld_RadarFromRover(t *testing.T) {
PrintTiles(radar) PrintTiles(radar)
// Test all expected values // Test all expected values
assert.Equal(t, TileRover, radar[1+fullRange]) assert.Equal(t, atlas.TileRover, radar[1+fullRange])
assert.Equal(t, TileRover, radar[4+4*fullRange]) assert.Equal(t, atlas.TileRover, radar[4+4*fullRange])
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
assert.Equal(t, TileWall, radar[i]) assert.Equal(t, atlas.TileWall, radar[i])
assert.Equal(t, TileWall, radar[i+(7*9)]) assert.Equal(t, atlas.TileWall, radar[i+(7*9)])
assert.Equal(t, TileWall, radar[i*9]) assert.Equal(t, atlas.TileWall, radar[i*9])
assert.Equal(t, TileWall, radar[(i*9)+7]) assert.Equal(t, atlas.TileWall, radar[(i*9)+7])
} }
} }

View file

@ -3,6 +3,7 @@ package rove
import ( import (
"path" "path"
"github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/game" "github.com/mdiluz/rove/pkg/game"
) )
@ -78,8 +79,8 @@ type RadarResponse struct {
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
// The set of positions for nearby non-empty tiles // The set of positions for nearby non-empty tiles
Range int `json:"range"` Range int `json:"range"`
Tiles []game.Tile `json:"tiles"` Tiles []atlas.Tile `json:"tiles"`
} }
// ================ // ================