From 41d16fb4910fc0402b6b081302c953f7dabc8cf9 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Wed, 28 Dec 2022 16:17:06 +0100 Subject: add random tile selection from map to the web tools --- go/.gitignore | 1 + go/Makefile | 11 +- go/game/map.go | 75 +++++-- go/game/map_test.go | 10 +- go/webtools/main.go | 45 +++++ html/Makefile | 19 +- html/tools.html | 62 ++++-- html/wasm_exec.js | 554 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 730 insertions(+), 47 deletions(-) create mode 100644 go/webtools/main.go create mode 100644 html/wasm_exec.js 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) +} diff --git a/html/Makefile b/html/Makefile index 3c969595..9188c4a5 100644 --- a/html/Makefile +++ b/html/Makefile @@ -10,6 +10,7 @@ MAKEFILE_DIR := $(dir $(MAKEFILE_PATH)) HTML_ROOT := $(MAKEFILE_DIR) GAME_ROOT := $(MAKEFILE_DIR).. +GO_ROOT := $(GAME_ROOT)/go RULES_ROOT := $(GAME_ROOT)/rules MAPS_ROOT := $(GAME_ROOT)/maps DATA_ROOT := $(GAME_ROOT)/data @@ -55,12 +56,21 @@ CARDS_YAML := $(foreach dir,$(SETS_SOURCEDIRS),$(wildcard $(dir)/*.yml)) MAKEFILE_LIST := Makefile +FILES_TO_COPY := wasm_exec.js hover-placeholder.png tools.html +FILES_TO_COPY_TARGETS := $(addprefix $(BUILDDIR)/,$(FILES_TO_COPY)) + .PHONY: all clean maps misc all: $(HTML) $(RULES_HTML) maps misc $(BLOG_POSTS_HTML) -misc: $(BUILDDIR)/latex-build $(BUILDDIR)/cards-data $(BUILDDIR)/hover-placeholder.png +misc: $(BUILDDIR)/latex-build $(BUILDDIR)/cards-data $(FILES_TO_COPY_TARGETS) \ + $(BUILDDIR)/webtools.wasm + +$(BUILDDIR)/webtools.wasm: + @echo "creating symlink $@" + @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi + ln -s $(GO_ROOT)/webtools/webtools.wasm $@ -$(BUILDDIR)/hover-placeholder.png: hover-placeholder.png +$(FILES_TO_COPY_TARGETS): $(BUILDDIR)/%: % @echo "copying $@" @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi $(VERBOSE) cp $< $@ @@ -73,11 +83,6 @@ maps: $(VERBOSE) ln -sfT $(MAPS_ROOT) $(BUILDDIR)/maps $(VERBOSE) $(MAKE) -C $(MAPS_ROOT) -$(BUILDDIR)/tools.html: tools.html - @echo "copying $@" - @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi - $(VERBOSE) cp $< $@ - $(BUILDDIR)/latex-build: @echo "render cards" $(VERBOSE) $(MAKE) -C $(LATEX_ROOT) diff --git a/html/tools.html b/html/tools.html index 5d638ef5..caca608e 100644 --- a/html/tools.html +++ b/html/tools.html @@ -68,6 +68,15 @@ body { } + + + +