aboutsummaryrefslogtreecommitdiff
path: root/go
diff options
context:
space:
mode:
Diffstat (limited to 'go')
-rw-r--r--go/.gitignore1
-rw-r--r--go/Makefile11
-rw-r--r--go/game/map.go75
-rw-r--r--go/game/map_test.go10
-rw-r--r--go/webtools/main.go45
5 files changed, 123 insertions, 19 deletions
diff --git a/go/.gitignore b/go/.gitignore
index eff64396..6e729d48 100644
--- a/go/.gitignore
+++ b/go/.gitignore
@@ -1,3 +1,4 @@
client/client
client/client.wasm
server/server
+webtools/webtools.wasm
diff --git a/go/Makefile b/go/Makefile
index 220a1022..0744d6c9 100644
--- a/go/Makefile
+++ b/go/Makefile
@@ -1,10 +1,11 @@
-PACKAGES := assets game server client
+PACKAGES := assets game server client webtools
APPS := server client
OBJS := $(foreach app,$(APPS),$(app)/$(app))
+WASM := client/client.wasm webtools/webtools.wasm
-.PHONY: all fmt test server/server client/client client/client.wasm
-all: $(OBJS)
+.PHONY: all fmt test $(OBJS) $(WASM)
+all: $(OBJS) $(WASM)
server/server:
@echo Building Server ...
@@ -18,6 +19,10 @@ client/client.wasm:
@echo Building Client.wasm ...
pushd $(@D) >/dev/null; env GOOS=js GOARCH=wasm go build -o $(@F); popd >/dev/null
+webtools/webtools.wasm:
+ @echo Building Webtools.wasm ...
+ pushd $(@D) >/dev/null; env GOOS=js GOARCH=wasm go build -o $(@F); popd >/dev/null
+
fmt:
for package in $(PACKAGES); do pushd $$package >/dev/null; go fmt; popd >/dev/null; done
diff --git a/go/game/map.go b/go/game/map.go
index 0b6fe87c..cecce9ca 100644
--- a/go/game/map.go
+++ b/go/game/map.go
@@ -2,12 +2,15 @@ package game
import (
"fmt"
+ "errors"
"io"
"log"
+ "math/rand"
"net/http"
"os"
"path"
"strings"
+ "time"
"gopkg.in/yaml.v3"
)
@@ -27,25 +30,30 @@ type MapYml struct {
type Map struct {
Tiles [][]Tile
+ symbols map[string]string
RessourceGain int
}
-func parseMap(r io.Reader) (*Map, error) {
+func readMap(r io.Reader) (*Map, error) {
data, err := io.ReadAll(r)
if err != nil {
return nil, err
}
+ return ParseMap(data)
+}
+
+func ParseMap(data []byte) (*Map, error) {
mapYml := MapYml{}
- err = yaml.Unmarshal(data, &mapYml)
+ err := yaml.Unmarshal(data, &mapYml)
if err != nil {
return nil, err
}
- m := &Map{[][]Tile{}, DEFAULT_RESSOURCE_GAIN}
-
mapYml.Symbols[" "] = "neutral"
+ m := &Map{[][]Tile{}, mapYml.Symbols, DEFAULT_RESSOURCE_GAIN}
+
rows := strings.Split(mapYml.Map, "\n")
for y := 0; y < len(rows); y++ {
m.Tiles = append(m.Tiles, []Tile{})
@@ -111,19 +119,19 @@ func (m *Map) FindAnyConnections(x, y int) (connections int, left, right, above,
leftT, rightT, aboveT, belowT := m.FindNeighbours(x, y)
connections = 0
- if leftT.Type != TileTypes.Neutral {
+ if leftT != nil && leftT.Type != TileTypes.Neutral {
left = true
connections += 1
}
- if rightT.Type != TileTypes.Neutral {
+ if rightT != nil && rightT.Type != TileTypes.Neutral {
right = true
connections += 1
}
- if aboveT.Type != TileTypes.Neutral {
+ if aboveT != nil && aboveT.Type != TileTypes.Neutral {
above = true
connections += 1
}
- if belowT.Type != TileTypes.Neutral {
+ if belowT != nil && belowT.Type != TileTypes.Neutral {
below = true
connections += 1
}
@@ -135,19 +143,19 @@ func (m *Map) FindStreetConnections(x int, y int) (connections int, left, right,
leftT, rightT, aboveT, belowT := m.FindNeighbours(x, y)
connections = 0
- if leftT.Type == TileTypes.Street {
+ if leftT != nil && leftT.Type == TileTypes.Street {
left = true
connections += 1
}
- if rightT.Type == TileTypes.Street {
+ if rightT != nil && rightT.Type == TileTypes.Street {
right = true
connections += 1
}
- if aboveT.Type == TileTypes.Street {
+ if aboveT != nil && aboveT.Type == TileTypes.Street {
above = true
connections += 1
}
- if belowT.Type == TileTypes.Street {
+ if belowT != nil && belowT.Type == TileTypes.Street {
below = true
connections += 1
}
@@ -163,19 +171,56 @@ func GetMap(name string) (*Map, error) {
log.Fatal(err)
}
defer resp.Body.Close()
- return parseMap(resp.Body)
+ return readMap(resp.Body)
}
func LoadMap(file string) (*Map, error) {
- f, err := os.Open("/tmp/123")
+ f, err := os.Open(file)
if err != nil {
log.Fatal("Opening map ", file, " failed: ", err)
}
defer f.Close()
- return parseMap(f)
+ return readMap(f)
}
func (m *Map) TileAt(p Position) *Tile {
return &m.Tiles[p.Y][p.X]
}
+
+func (m *Map) RandomTile(types []TileType) Position {
+ candidates := []Position{}
+ for y := 0; y < len(m.Tiles); y++ {
+ for x := 0; x < len(m.Tiles[y]); x++ {
+ candidate := m.Tiles[y][x]
+ for _, t := range types {
+ if candidate.Type == t {
+ candidates = append(candidates, candidate.Position)
+ break
+ }
+ }
+ }
+ }
+
+ r := rand.New(rand.NewSource(time.Now().UnixNano()))
+ randIdx := r.Intn(len(candidates))
+ return candidates[randIdx]
+}
+
+func (m *Map) RandomTileFromSymbols(symbols []string) (Position, error) {
+ types := make([]TileType, 0, len(symbols))
+ for _, symbol := range symbols {
+ tileString, ok := m.symbols[symbol]
+ if !ok {
+ return INVALID_POSITION(), errors.New(fmt.Sprintf("symbol %s not in the map symbols %v", symbol, m.symbols))
+ }
+
+ tileType, ok := TileNames[tileString]
+ if !ok {
+ return INVALID_POSITION(), errors.New("tile type unknown")
+ }
+
+ types = append(types, tileType)
+ }
+ return m.RandomTile(types), nil
+}
diff --git a/go/game/map_test.go b/go/game/map_test.go
index 732c8b86..8212f648 100644
--- a/go/game/map_test.go
+++ b/go/game/map_test.go
@@ -30,7 +30,7 @@ kings:
- (9,1)`
r := strings.NewReader(s)
- m, err := parseMap(r)
+ m, err := readMap(r)
if err != nil {
t.Fatalf("Parsing failed with: %v", err)
}
@@ -51,3 +51,11 @@ kings:
t.Fatalf("ressource gain is not the default one")
}
}
+
+func TestLoadingAllMaps(T *testing.T) {
+ maps := []string{"the-tyrant", "2P-ring-street", "2P-river-king", "3P-ring-street", "4P-islands", "the-kraken"}
+
+ for _, m := range maps {
+ LoadMap("../../maps/" + m + ".yml")
+ }
+}
diff --git a/go/webtools/main.go b/go/webtools/main.go
new file mode 100644
index 00000000..03fc9e37
--- /dev/null
+++ b/go/webtools/main.go
@@ -0,0 +1,45 @@
+package main
+
+import (
+ "syscall/js"
+
+ "muhq.space/muhqs-game/go/game"
+)
+
+const ()
+
+func jSRandomTileFromMap() js.Func {
+ jsonFunc := js.FuncOf(func(this js.Value, args []js.Value) any {
+ if len(args) != 2 {
+ return "Invalid number of arguments passed"
+ }
+
+ mapData := args[0].String()
+
+ symbols := make([]string, 0, args[1].Length())
+ for i := 0; i < args[1].Length(); i++ {
+ symbol := args[1].Index(i).String()
+ symbols = append(symbols, symbol)
+ }
+
+ position, err := randomTileFromMap(mapData, symbols)
+ if err != nil {
+ return err.Error()
+ }
+ return map[string]interface{}{"y": position.Y + 1, "x": position.X + 1}
+ })
+ return jsonFunc
+}
+
+func randomTileFromMap(mapData string, symbols []string) (game.Position, error) {
+ m, err := game.ParseMap([]byte(mapData))
+ if err != nil {
+ return game.INVALID_POSITION(), err
+ }
+ return m.RandomTileFromSymbols(symbols)
+}
+
+func main() {
+ js.Global().Set("randomTileFromSymbol", jSRandomTileFromMap())
+ <-make(chan bool)
+}