//main initializes the state and starts the processing loop func main() { var s ants.State err := s.Start() if err != nil { log.Panicf("Start() failed (%s)", err) } mb := NewBot(&s) err = s.Loop(mb, func() { //if you want to do other between-turn debugging things, you can do them here }) if err != nil && err != io.EOF { log.Panicf("Loop() failed (%s)", err) } }
//DoTurn is where you should do your bot's actual work. func (mb *MyBot) DoTurn(s *ants.State) error { dirs := []ants.Direction{ants.North, ants.East, ants.South, ants.West} for loc, ant := range s.Map.Ants { if ant != ants.MY_ANT { continue } //try each direction in a random order p := rand.Perm(4) for _, i := range p { d := dirs[i] loc2 := s.Map.Move(loc, d) if s.Map.SafeDestination(loc2) { s.IssueOrderLoc(loc, d) //there's also an s.IssueOrderRowCol if you don't have a Location handy break } } } //returning an error will halt the whole program! return nil }
// DoTurn is where you should do your bot's actual work. func (bot *Bot) DoTurn(s *ants.State) error { const ( friendlyScore = -1 foodScore = 3 myHillScore = -2 enemyHillScore = 1 ) // Score the possible moves for each ant. dirs := []ants.Direction{ants.North, ants.East, ants.South, ants.West, ants.NoMovement} for _, loc1 := range myAnts(s.Map.Ants) { // Create moves and scores for each direction the ant can move. moves := make([]ants.Direction, 0) scores := make([]float64, 0) for i, dir := range dirs { // Don't include this move if it is not legal. newLoc := s.Map.Move(loc1, dir) if !s.Map.SafeDestination(newLoc) { continue } var score float64 c1 := s.Map.ToCoordinate(newLoc) // Update the move scores for friendly ant proximity. for _, loc2 := range myAnts(s.Map.Ants) { if loc1 != loc2 { c2 := s.Map.ToCoordinate(loc2) dist := grid.ManhattanDistance(s.Map, c1, c2) score += friendlyScore / float64(1+dist) } } // Update the move scores for food proximity. for loc2, _ := range s.Map.Food { c2 := s.Map.ToCoordinate(loc2) dist := grid.ManhattanDistance(s.Map, c1, c2) score += foodScore / float64(1+dist) } // Update the move scores for hill proximity. for loc2, hill := range s.Map.Hills { c2 := s.Map.ToCoordinate(loc2) dist := grid.ManhattanDistance(s.Map, c1, c2) if hill == ants.MY_HILL { score += myHillScore / float64(1+dist) } else { score += enemyHillScore / float64(1+dist) } } moves = append(moves, dirs[i]) scores = append(scores, score) } // Make the scores all positive. for i := 0; i < len(scores); i++ { scores[i] = math.Exp(scores[i]) } // Randomly select a move using scores as weights. if len(scores) > 0 { index := rand.RandSelect(scores) move := moves[index] if move != ants.NoMovement { s.IssueOrderLoc(loc1, move) } } } // returning an error will halt the whole program! return nil }