// Single-file Kobaltmeer starter: protocol helpers and editable collection policy. package main import ( "bufio" "encoding/json" "fmt" "os" "sort" ) type Point struct { X, Y int } type Rules struct { Size int `json:"size"`; Turns int `json:"turns"`; Capacity int `json:"capacity"`; ShipCost int `json:"ship_cost"`; MoveDivisor int `json:"move_divisor"`; FloorMoveCost bool `json:"floor_move_cost"` } type Ship struct { ID int `json:"id"`; Owner int `json:"owner"`; X int `json:"x"`; Y int `json:"y"`; Cargo int `json:"cargo"` } type Site struct { Owner int `json:"owner"`; X int `json:"x"`; Y int `json:"y"` } type Player struct { Bank int `json:"bank"`; Yard [2]int `json:"yard"` } type State struct { Turn int `json:"turn"`; Resource [][]int `json:"resource"`; Ships []Ship `json:"ships"`; Sites []Site `json:"sites"`; Players []Player `json:"players"` } type Request struct { Type string `json:"type"`; Protocol string `json:"protocol"`; Seed uint64 `json:"seed"`; Player int `json:"player"`; Rules Rules `json:"rules"`; State State `json:"state"` } type Debug struct { Ship int `json:"ship"`; Target [2]int `json:"target"`; Reason string `json:"reason"` } type Orders struct { Type string `json:"type"`; Ships map[string]string `json:"ships"`; Spawn bool `json:"spawn"`; Debug []Debug `json:"debug"` } func abs(x int) int { if x<0{return -x};return x } func min(x,y int) int { if xfleet[j].Cargo}) for _,ship:=range fleet { pos:=Point{ship.X,ship.Y};delete(occupied,pos);home:=harbors[0] for _,h:=range harbors {if distance(pos,h,r.Size)=r.Capacity*3/4 || (ship.Cargo>0 && r.Turns-s.Turn<=distance(pos,home,r.Size)+6){returning[ship.ID]=true} value:=s.Resource[pos.Y][pos.X];fuel:=(value+r.MoveDivisor-1)/r.MoveDivisor;if r.FloorMoveCost {fuel=value/r.MoveDivisor} chosen,best:="O",-1e30 for _,action:=range []string{"O","N","E","S","W"} { target:=destination(pos,action,r.Size);if (action!="O"&&ship.Cargobest {best=score;chosen=action} } target:=destination(pos,chosen,r.Size);reserved[target]=true;out.Ships[fmt.Sprint(ship.ID)]=chosen reason:="Go: Nachbarfeld oder Abbau";if returning[ship.ID]{target=home;reason="Go: Fracht abliefern"} out.Debug=append(out.Debug,Debug{ship.ID,[2]int{target.X,target.Y},reason}) } out.Spawn=len(fleet)<8&&s.Turn*100=r.ShipCost&&!reserved[yard] return out } func run() error { reader:=json.NewDecoder(bufio.NewReader(os.Stdin));writer:=bufio.NewWriter(os.Stdout);encoder:=json.NewEncoder(writer) var init Request;if err:=reader.Decode(&init);err!=nil{return err};if init.Type!="init"||init.Protocol!="kobaltmeer-bot-v1"{return fmt.Errorf("unsupported protocol")} if err:=encoder.Encode(map[string]string{"type":"ready","name":"Go Sammler"});err!=nil{return err};writer.Flush() // init.Seed is available for reproducible random decisions; this example is deterministic. returning:=map[int]bool{} for {var input Request;if err:=reader.Decode(&input);err!=nil{return nil};if input.Type=="close"{return nil};if input.Type!="turn"{return fmt.Errorf("expected turn")};if err:=encoder.Encode(decide(input,returning));err!=nil{return err};if err:=writer.Flush();err!=nil{return err}} } func main(){if err:=run();err!=nil{fmt.Fprintln(os.Stderr,err);os.Exit(1)}}