commit cb0f6111cea8c67b21e0afd48dddc8ff86e5dd3c Author: Trevor Slocum Date: Mon May 24 02:51:12 2021 -0700 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c144b7c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +vendor/ +*.sh + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..51c4dd1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Trevor Slocum + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..9e6624c --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# world +[![GoDoc](https://code.rocketnine.space/tslocum/godoc-static/raw/branch/master/badge.svg)](https://docs.rocketnine.space/code.rocketnine.space/tslocum/world) +[![Donate](https://img.shields.io/liberapay/receives/rocketnine.space.svg?logo=liberapay)](https://liberapay.com/rocketnine.space) + +Tile-based worldbuilding library + +## Install + +```go get code.rocketnine.space/tslocum/world``` + +## Documentation + +All documentation is available via [godoc](https://docs.rocketnine.space/code.rocketnine.space/tslocum/world). + +## Support + +Please share issues and suggestions [here](https://code.rocketnine.space/tslocum/world/issues). diff --git a/entity.go b/entity.go new file mode 100644 index 0000000..afa05d7 --- /dev/null +++ b/entity.go @@ -0,0 +1,32 @@ +package world + +import "sync" + +// Entity represents an entity within the world. +type Entity struct { + t int // Type + x, y, z int + + sync.RWMutex +} + +// NewEntity returns a new Entity. +func NewEntity(t int) *Entity { + return &Entity{t: t} +} + +// Is returns whether the Entity matches the specified type. +func (e *Entity) Is(t int) bool { + e.RLock() + defer e.RUnlock() + + return e.t == t +} + +// Coordinates returns the position of the entity. +func (e *Entity) Coordinates() (x, y, z int) { + e.RLock() + defer e.RUnlock() + + return e.x, e.y, e.z +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e1dd525 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module code.rocketnine.space/tslocum/world + +go 1.16 diff --git a/map.go b/map.go new file mode 100644 index 0000000..93c3173 --- /dev/null +++ b/map.go @@ -0,0 +1,48 @@ +package world + +import ( + "strconv" + "sync" +) + +// Coordinates returns the provided coordinates as a comma-delimited string. +func Coordinates(x, y, z int) string { + return strconv.Itoa(x) + "," + strconv.Itoa(y) + "," + strconv.Itoa(z) +} + +// Map represents a collection of entities in a 3D space. +type Map struct { + contents map[string]*Entity + + sync.RWMutex +} + +// NewMap returns a new Map. +func NewMap() *Map { + return &Map{} +} + +// Contents returns the entities contained in the Map. +func (m *Map) Contents() map[string]*Entity { + m.RLock() + defer m.RUnlock() + + c := make(map[string]*Entity) + for key, value := range m.contents { + c[key] = value + } + return c +} + +// Add adds an entity to the Map. +func (m *Map) Add(e *Entity, x, y, z int) { + m.Lock() + defer m.Unlock() + + if m.contents == nil { + m.contents = make(map[string]*Entity) + } + + e.x, e.y, e.z = x, y, z + m.contents[Coordinates(x, y, z)] = e +} diff --git a/map_test.go b/map_test.go new file mode 100644 index 0000000..eb06f0f --- /dev/null +++ b/map_test.go @@ -0,0 +1,32 @@ +package world + +import "testing" + +const ( + EntityNone = iota + EntityFloor + EntityWall + EntityCeiling + EntityActor +) + +func TestMap(t *testing.T) { + m := NewMap() + + e := NewEntity(EntityFloor) + m.Add(e, 0, 0, 0) + + c := m.Contents() + found := 0 + for position, entity := range c { + if entity.Is(EntityFloor) { + if position != "0,0,0" { + t.Errorf("unexpected position: wanted %s, got %s", "0,0,0", position) + } + found++ + } + } + if found != 1 { + t.Errorf("unexpected number of floor tiles: wanted %d, got %d", 1, found) + } +}