func (p *Player) UpdateVisibility(g *Game, ants []game.AntMove, np int, seen *[]torus.Location) { copy(p.Visible, _false[:len(p.Visible)]) if false && np == 0 { game.DumpAntMove(g.Map, ants, np, g.Turn) } for i := range ants { if ants[i].Player == np && ants[i].To > -1 { g.ApplyOffsets(ants[i].To, &g.ViewMask.Offsets, func(l torus.Location) { p.Visible[l] = true if !p.Seen[l] { p.Seen[l] = true *seen = append(*seen, l) } }) } } if false && np == 0 { sort.Sort(torus.LocationSlice(*seen)) log.Printf("t %d Seen %v", g.Turn, g.ToPoints(*seen)) } return }
// Generate the Turn output for each player given a collection of ant locations func (g *Game) GenerateTurn(ants [][]game.AntMove, hills []game.PlayerLoc, food []torus.Location, canonicalorder bool) []*game.Turn { turns := make([]*game.Turn, len(g.Players)) // Handle Combat for the passed locations. g.C.Reset() moves, spawn := g.C.SetupReplay(ants) // NB: This is very tricky - we are avoiding allocating new slices so we // are cutting up ants in place into live and dead, but that means // appending to dead would overwrite live. live, dead := g.C.Resolve(moves) if canonicalorder { sort.Sort(game.AntMoveSlice(dead)) sort.Sort(game.PlayerLocSlice(hills)) sort.Sort(torus.LocationSlice(food)) } // Handle Razes // Handle Spawns live = append(live, spawn...) // NB see Resolve above wrt live slice. // Handle Gather // Update visibility, generating new water, all ants (updating IdMap), hills, and food seen seen := make([]torus.Location, 0, 300) for np, p := range g.Players { t := &game.Turn{Map: g.Map} seen = seen[0:0] p.UpdateVisibility(g, live, np, &seen) // newly visible water for _, loc := range seen { if g.Map.Grid[loc] == maps.WATER { t.W = append(t.W, loc) } } // visible live ants for i := range live { if p.Visible[live[i].To] { if p.IdMap[live[i].Player] < 0 { p.AddIdMap(live[i].Player) } t.A = append(t.A, game.PlayerLoc{Loc: live[i].To, Player: p.IdMap[live[i].Player]}) } } for i := range dead { if p.Visible[dead[i].To] || dead[i].Player == np { if p.IdMap[dead[i].Player] < 0 { p.AddIdMap(dead[i].Player) } t.D = append(t.D, game.PlayerLoc{Loc: dead[i].To, Player: p.IdMap[dead[i].Player]}) } } // visible hills for _, h := range hills { if p.Visible[h.Loc] { if p.IdMap[h.Player] < 0 { p.AddIdMap(h.Player) } t.H = append(t.H, game.PlayerLoc{Loc: h.Loc, Player: p.IdMap[h.Player]}) } } // visible food for _, loc := range food { if p.Visible[loc] { t.F = append(t.F, loc) } } if canonicalorder { // got t.D, t.H and t.F by sorting inputs. sort.Sort(torus.LocationSlice(t.W)) sort.Sort(game.PlayerLocSlice(t.A)) } turns[np] = t } return turns }