- cmd/acb-maps-loader/main.go - wasm/bots/guardian/main.go - wasm/bots/hunter/main.go - wasm/bots/random/main.go - web/package-lock.json (npm ci update)
80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
//go:build js && wasm
|
|
|
|
// Package main compiles to random.wasm for the browser sandbox.
|
|
// RandomBot makes uniformly random valid moves.
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"math/rand"
|
|
"syscall/js"
|
|
|
|
"github.com/aicodebattle/acb/engine"
|
|
)
|
|
|
|
var (
|
|
cfg engine.Config
|
|
rng *rand.Rand
|
|
visible *engine.VisibleState
|
|
)
|
|
|
|
// jsInit initializes the bot with game config.
|
|
func jsInit(_ js.Value, args []js.Value) interface{} {
|
|
if len(args) < 1 {
|
|
return jsErr("configJSON argument required")
|
|
}
|
|
if err := json.Unmarshal([]byte(args[0].String()), &cfg); err != nil {
|
|
return jsErr("parse config: " + err.Error())
|
|
}
|
|
rng = rand.New(rand.NewSource(42))
|
|
visible = &engine.VisibleState{}
|
|
return map[string]interface{}{"ok": true}
|
|
}
|
|
|
|
// jsComputeMoves returns random moves.
|
|
func jsComputeMoves(_ js.Value, args []js.Value) interface{} {
|
|
if len(args) < 1 {
|
|
return "[]"
|
|
}
|
|
if err := json.Unmarshal([]byte(args[0].String()), visible); err != nil {
|
|
return "[]"
|
|
}
|
|
|
|
moves := getMoves(visible)
|
|
json, _ := json.Marshal(moves)
|
|
return string(json)
|
|
}
|
|
|
|
// jsFreeResult is a no-op.
|
|
func jsFreeResult(_ js.Value, _ []js.Value) interface{} {
|
|
return nil
|
|
}
|
|
|
|
// getMoves implements RandomBot strategy.
|
|
func getMoves(state *engine.VisibleState) []engine.Move {
|
|
myID := state.You.ID
|
|
allDirs := []engine.Direction{engine.DirN, engine.DirE, engine.DirS, engine.DirW}
|
|
var moves []engine.Move
|
|
for _, bot := range state.Bots {
|
|
if bot.Owner != myID {
|
|
continue
|
|
}
|
|
dir := allDirs[rng.Intn(4)]
|
|
moves = append(moves, engine.Move{Position: bot.Position, Direction: dir})
|
|
}
|
|
return moves
|
|
}
|
|
|
|
func main() {
|
|
js.Global().Set("randomBot", js.ValueOf(map[string]interface{}{
|
|
"init": js.FuncOf(jsInit),
|
|
"compute_moves": js.FuncOf(jsComputeMoves),
|
|
"free_result": js.FuncOf(jsFreeResult),
|
|
"version": "1.0.0",
|
|
}))
|
|
select {}
|
|
}
|
|
|
|
func jsErr(msg string) map[string]interface{} {
|
|
return map[string]interface{}{"ok": false, "error": msg}
|
|
}
|