diff options
Diffstat (limited to 'go')
| -rw-r--r-- | go/.gitignore | 1 | ||||
| -rw-r--r-- | go/Makefile | 11 | ||||
| -rw-r--r-- | go/game/map.go | 75 | ||||
| -rw-r--r-- | go/game/map_test.go | 10 | ||||
| -rw-r--r-- | go/webtools/main.go | 45 |
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) +} |
