func ReachableDestinationsSpec(c gospec.Context) { b := [][]int{ []int{1, 2, 9, 4, 0, 2, 1}, // 0 - 6 []int{0, 0, 0, 0, 0, 1, 1}, // 7 - 13 []int{2, 1, 5, 5, 0, 2, 1}, // 14 - 20 []int{1, 1, 1, 9, 0, 1, 1}, // 21 - 27 } c.Specify("Check reachability", func() { reachable := algorithm.ReachableDestinations(board(b), []int{14}, []int{0, 2, 5, 13, 17, 22}) c.Expect(reachable, ContainsInOrder, []int{17, 22}) reachable = algorithm.ReachableDestinations(board(b), []int{1, 26}, []int{0, 2, 5, 13, 17, 22}) c.Expect(reachable, ContainsInOrder, []int{0, 2, 5, 13}) }) }
// Returns an array of all points that can be reached by walking from a // specific location that end in a certain general area. Assumes that a 1x1 // unit is doing the walking. // Format: // points = AllPathablePoints(src, dst, min, max) // // Inputs: // src - table[x,y] - Where the path starts. // dst - table[x,y] - Another point near where the path should go. // min - integer - Minimum distance from dst that the path should end at. // max - integer - Maximum distance from dst that the path should end at. // // Outputs: // points - array[table[x,y]] func AllPathablePointsFunc(a *Ai) lua.GoFunction { return func(L *lua.State) int { if !game.LuaCheckParamsOk(L, "AllPathablePoints", game.LuaPoint, game.LuaPoint, game.LuaInteger, game.LuaInteger) { return 0 } min := L.ToInteger(-2) max := L.ToInteger(-1) x1, y1 := game.LuaToPoint(L, -4) x2, y2 := game.LuaToPoint(L, -3) a.ent.Game().DetermineLos(x2, y2, max, grid) var dst []int for x := x2 - max; x <= x2+max; x++ { for y := y2 - max; y <= y2+max; y++ { if x > x2-min && x < x2+min && y > y2-min && y < y2+min { continue } if x < 0 || y < 0 || x >= len(grid) || y >= len(grid[0]) { continue } if !grid[x][y] { continue } dst = append(dst, a.ent.Game().ToVertex(x, y)) } } vis := 0 for i := range grid { for j := range grid[i] { if grid[i][j] { vis++ } } } base.Log().Printf("Visible: %d", vis) graph := a.ent.Game().Graph(a.ent.Side(), true, nil) src := []int{a.ent.Game().ToVertex(x1, y1)} reachable := algorithm.ReachableDestinations(graph, src, dst) L.NewTable() base.Log().Printf("%d/%d reachable from (%d, %d) -> (%d, %d)", len(reachable), len(dst), x1, y1, x2, y2) for i, v := range reachable { _, x, y := a.ent.Game().FromVertex(v) L.PushInteger(i + 1) game.LuaPushPoint(L, x, y) L.SetTable(-3) } return 1 } }