// if ant is holding a grain it must drop it so that it can be counted func finalise(ants []*Ant) { Loop: for _, ant := range ants { if ant.carrying < 0 { continue } // if current location is empty, count it here if drop(ant, ant.row, ant.col) { continue } // if cell we picked it up from is empty, count it there if drop(ant, ant.pickupRow, ant.pickupCol) { continue } // find next free space for xoff := 1; xoff < ant.grid.cols; xoff++ { x := util.Mod(ant.col+xoff, ant.grid.cols) for yoff := 0; yoff <= xoff; yoff++ { y := util.Mod(ant.row+yoff, ant.grid.rows) if drop(ant, y, x) { continue Loop } if yoff > 0 { y := util.Mod(ant.row-yoff, ant.grid.rows) if drop(ant, y, x) { continue Loop } } } } panic("nowhere to drop the sand!") } }
// turn left or left func turn(dir int) func(*Ant) { return func(ant *Ant) { if ant.moves < ant.maxMoves { ant.moves++ ant.dir = util.Mod(ant.dir+dir, 4) ant.grid[ant.row][ant.col] = TRAIL } } }
// get next position func (g *Grid) next(row, col, dir int) (nRow, nCol int) { nRow = util.Mod(row+[]int{1, 0, -1, 0}[dir], g.rows) nCol = util.Mod(col+[]int{0, 1, 0, -1}[dir], g.cols) return }
// grid methods func (g Grid) Next(row, col, dir int) (nRow, nCol int) { rows, cols := len(g), len(g[0]) nRow = util.Mod(row+[]int{1, 0, -1, 0}[dir], rows) nCol = util.Mod(col+[]int{0, 1, 0, -1}[dir], cols) return }