Esempio n. 1
0
func (a *Move) AiMoveToPos(ent *game.Entity, dst []int, max_ap int) game.ActionExec {
	base.Log().Printf("PATH: Request move to %v", dst)
	graph := ent.Game().Graph(ent.Side(), false, nil)
	src := []int{ent.Game().ToVertex(ent.Pos())}
	_, path := algorithm.Dijkstra(graph, src, dst)
	base.Log().Printf("PATH: Found path of length %d", len(path))
	ppx, ppy := ent.Pos()
	if path == nil {
		return nil
	}
	_, xx, yy := ent.Game().FromVertex(path[len(path)-1])
	base.Log().Printf("PATH: %d,%d -> %d,%d", ppx, ppy, xx, yy)
	if ent.Stats.ApCur() < max_ap {
		max_ap = ent.Stats.ApCur()
	}
	path = limitPath(ent, src[0], path, max_ap)
	_, xx, yy = ent.Game().FromVertex(path[len(path)-1])
	base.Log().Printf("PATH: (limited) %d,%d -> %d,%d", ppx, ppy, xx, yy)
	if len(path) <= 1 {
		return nil
	}
	var exec moveExec
	exec.SetBasicData(ent, a)
	exec.Path = path
	return &exec
}
Esempio n. 2
0
// Returns a list of rooms representing a path from src to dst.  The path will
// not include src, but will include dst.  This function will return nil if
// the path requires going through more than a single unexplored room, this
// means that you can use this to path to an unexplored room, but you cannot
// use it to path to a room further in the house than that.
// rooms.
//    Format
//    path = roomPath(src, dst)
//
//    Input:
//    src - Room to start the path from.
//    dst - Room to end the path at.
//
//    Output:
//    path - array - A list of rooms that connect src to dst, excluding src
//    but including dst.
func RoomPathFunc(a *Ai) lua.GoFunction {
	return func(L *lua.State) int {
		if !game.LuaCheckParamsOk(L, "roomPath", game.LuaRoom, game.LuaRoom) {
			return 0
		}

		me := a.ent
		g := me.Game()
		graph := g.RoomGraph()
		r1 := game.LuaToRoom(L, g, -2)
		r2 := game.LuaToRoom(L, g, -1)
		if r1 == nil || r2 == nil {
			game.LuaDoError(L, fmt.Sprintf("Referenced one or more invalid rooms."))
			return 0
		}

		L.PushString("room")
		L.GetTable(-3)
		r1_index := L.ToInteger(-1)
		L.Pop(1)

		L.PushString("room")
		L.GetTable(-2)
		r2_index := L.ToInteger(-1)
		L.Pop(1)

		cost, path := algorithm.Dijkstra(graph, []int{r1_index}, []int{r2_index})
		if cost == -1 {
			L.PushNil()
			return 1
		}
		num_unexplored := 0
		for _, v := range path {
			if !me.Info.RoomsExplored[v] {
				num_unexplored++
			}
		}
		if num_unexplored > 1 {
			L.PushNil()
			return 1
		}
		L.NewTable()
		for i, v := range path {
			if i == 0 {
				continue
			} // Skip this one because we're in it already
			L.PushInteger(i)
			game.LuaPushRoom(L, g, g.House.Floors[0].Rooms[v])
			L.SetTable(-3)
		}
		return 1
	}
}
Esempio n. 3
0
func DijkstraSpec(c gospec.Context) {
	b := [][]int{
		[]int{1, 2, 9, 4, 3, 2, 1}, // 0 - 6
		[]int{9, 2, 9, 4, 3, 1, 1}, // 7 - 13
		[]int{2, 1, 5, 5, 5, 2, 1}, // 14 - 20
		[]int{1, 1, 1, 1, 1, 1, 1}, // 21 - 27
	}
	c.Specify("Check Dijkstra's gives the right path and weight", func() {
		weight, path := algorithm.Dijkstra(board(b), []int{0}, []int{11})
		c.Expect(weight, Equals, 16.0)
		c.Expect(path, ContainsInOrder, []int{0, 1, 8, 15, 22, 23, 24, 25, 26, 19, 12, 11})
	})
	c.Specify("Check multiple sources", func() {
		weight, path := algorithm.Dijkstra(board(b), []int{0, 1, 7, 2}, []int{11})
		c.Expect(weight, Equals, 10.0)
		c.Expect(path, ContainsInOrder, []int{2, 3, 4, 11})
	})
	c.Specify("Check multiple destinations", func() {
		weight, path := algorithm.Dijkstra(board(b), []int{0}, []int{6, 11, 21})
		c.Expect(weight, Equals, 7.0)
		c.Expect(path, ContainsInOrder, []int{0, 1, 8, 15, 22, 21})
	})
}
Esempio n. 4
0
func (a *Move) findPath(ent *game.Entity, x, y int) {
	g := ent.Game()
	dst := g.ToVertex(x, y)
	if dst != a.dst || !a.calculated {
		a.dst = dst
		a.calculated = true
		src := g.ToVertex(a.ent.Pos())
		graph := g.Graph(ent.Side(), true, nil)
		cost, path := algorithm.Dijkstra(graph, []int{src}, []int{dst})
		if len(path) <= 1 {
			return
		}
		a.path = algorithm.Map(path, [][2]int{}, func(a interface{}) interface{} {
			_, x, y := g.FromVertex(a.(int))
			return [2]int{int(x), int(y)}
		}).([][2]int)
		a.cost = int(cost)

		if path_tex != nil {
			pix := path_tex.Pix()
			for i := range pix {
				for j := range pix[i] {
					pix[i][j] = 0
				}
			}
			current := 0.0
			for i := 1; i < len(a.path); i++ {
				src := g.ToVertex(a.path[i-1][0], a.path[i-1][1])
				dst := g.ToVertex(a.path[i][0], a.path[i][1])
				v, cost := graph.Adjacent(src)
				for j := range v {
					if v[j] == dst {
						current += cost[j]
						break
					}
				}
				pix[a.path[i][1]][a.path[i][0]] += byte(current)
			}
			path_tex.Remap()
		}
	}
}
Esempio n. 5
0
func (a *Move) findPath(ent *game.Entity, x, y int) {
	g := ent.Game()
	dst := g.ToVertex(x, y)
	if dst != a.dst || !a.calculated {
		a.dst = dst
		a.calculated = true
		src := g.ToVertex(a.ent.Pos())
		graph := g.Graph(ent.Side(), true, nil)
		cost, path := algorithm.Dijkstra(graph, []int{src}, []int{dst})
		if len(path) <= 1 {
			return
		}
		a.path = algorithm.Map(path, [][2]int{}, func(a interface{}) interface{} {
			_, x, y := g.FromVertex(a.(int))
			return [2]int{int(x), int(y)}
		}).([][2]int)
		a.cost = int(cost)
		a.drawPath(ent, g, graph, src)
	}
}
Esempio n. 6
0
// If this returns a path with length 0 it means there wasn't a valid path
func (s *Sprite) findPathForCmd(cmd command, anim_node *yed.Node) []*yed.Node {
	var node_path []*yed.Node
	for _, name := range cmd.names {
		g := pathingGraph{shared: s.shared, start: anim_node, cmd: name}
		var end []int
		for i := 0; i < s.shared.anim.NumEdges(); i++ {
			edge := s.shared.anim.Edge(i)
			if s.shared.edge_data[edge].cmd == name {
				end = append(end, edge.Dst().Id())
			}
		}
		_, path := algorithm.Dijkstra(g, []int{s.shared.anim.NumNodes()}, end)
		for _, id := range path[1:] {
			node_path = append(node_path, s.shared.anim.Node(id))
		}
		if len(node_path) > 0 {
			anim_node = node_path[len(node_path)-1]
		}
	}

	return node_path
}