Reference: “Artificial Intelligence for Games”, Ian Millington.

Slides:



Advertisements
Similar presentations
Heuristic Search techniques
Advertisements

Problem solving with graph search
An Introduction to Artificial Intelligence
Artificial Intelligence By Mr. Ejaz CIIT Sahiwal.
Introduction to Algorithms Lecture 12 Prof. Constantinos Daskalakis CLRS
CSE 380 – Computer Game Programming Pathfinding AI
Using Search in Problem Solving
Using Search in Problem Solving
Backtracking.
Graphs II Robin Burke GAM 376. Admin Skip the Lua topic.
1 Game AI Path Finding. A Common Situation of Game AI A Common Situation of Game AI Path Planning Path Planning –From a start position to a destination.
Artificial Intelligence in Game Design
GRAPHS
WAES 3308 Numerical Methods for AI
Dr.Abeer Mahmoud ARTIFICIAL INTELLIGENCE (CS 461D) Dr. Abeer Mahmoud Computer science Department Princess Nora University Faculty of Computer & Information.
Artificial Intelligence in Game Design Dynamic Path Planning Algorithms.
WORLD NAVIGATION Don’t Fall Asleep Through These Topics  Tile Graphs  Points of Visibility  NavMesh  Path Smoothing  Hierarchical Pathfinding.
Graphs – Part II CS 367 – Introduction to Data Structures.
Review: Tree search Initialize the frontier using the starting state While the frontier is not empty – Choose a frontier node to expand according to search.
REFERENCE: “ARTIFICIAL INTELLIGENCE FOR GAMES”, IAN MILLINGTON. A* (A-STAR)
Graph Algorithms GAM 376 Robin Burke Fall Outline Graphs Theory Data structures Graph search Algorithms DFS BFS Project #1 Soccer Break Lab.
A* Reference: “Artificial Intelligence for Games”, Ian Millington.
Source: CSE 214 – Computer Science II Graphs.
A* Reference: “Artificial Intelligence for Games”, Ian Millington.
Artificial Intelligence Solving problems by searching.
Dept. Computer Science, Korea Univ. Intelligent Information System Lab A I (Artificial Intelligence) Professor I. J. Chung.
Graphs A New Data Structure
Lecture 3: Uninformed Search
CSG3F3/ Desain dan Analisis Algoritma
Review: Tree search Initialize the frontier using the starting state
Uniformed Search (cont.) Computer Science cpsc322, Lecture 6
Chapter 5.4 Artificial Intelligence: Pathfinding
Traveling Salesperson Problem
BackTracking CS255.
Graphs Representation, BFS, DFS
Heuristic Search Introduction to Artificial Intelligence
CSE 2331/5331 Topic 9: Basic Graph Alg.
Artificial Intelligence (CS 370D)
Maze Implementation, Analysis and Design to find Shortest Paths
Uniformed Search (cont.) Computer Science cpsc322, Lecture 6
Algorithms for Exploration
Uninformed Search Introduction to Artificial Intelligence
Graphs Representation, BFS, DFS
Teach A level Computing: Algorithms and Data Structures
Chapter 22: Elementary Graph Algorithms I
Graphs.
Team 17c ****** Pathfinding
Graphs Part 2 Adjacency Matrix
Tree Searching.
Artificial Intelligence
A General Backtracking Algorithm
CO Games Development 1 Week 8 Depth-first search, Combinatorial Explosion, Heuristics, Hill-Climbing Gareth Bellaby.
CPSC 322 Introduction to Artificial Intelligence
Chap 4: Searching Techniques
HW 1: Warmup Missionaries and Cannibals
GRAPHS G=<V,E> Adjacent vertices Undirected graph
Informed Search Idea: be smart about what paths to try.
Graphs.
Graphs.
State-Space Searches.
Graphs.
State-Space Searches.
3.2 Graph Traversal.
HW 1: Warmup Missionaries and Cannibals
Graphs.
Graph Search in C++ Andrew Lindsay.
State-Space Searches.
Informed Search Idea: be smart about what paths to try.
Lecture 4: Tree Search Strategies
Presentation transcript:

Reference: “Artificial Intelligence for Games”, Ian Millington. Pathfinding Reference: “Artificial Intelligence for Games”, Ian Millington.

Goals Find a “pretty-short” path from point A to point B. The best path is often prohibitively expensive to find. G S

Nav-Meshes A common way to represent: Key Ideas: Walkable areas of a map. Cover-spots Jumping-points (to cross a chasm) Ladders Save points, ammo drops, etc. Key Ideas: Not usually visible Usually much lower poly-count than the actual ground We’ll use these in this lab to represent the search graph.

Nav-Meshes, cont. Display Mesh (16541 faces) Nav Mesh (301 faces)

Nav-Meshes, cont. We can use these for pathfinding… Nodes are faces (their center?) Edges are connections between neighboring faces Cost is just the euclidean distance between centers. Probably best done off-line Finding neighbors can be costly.

Graph-based algorithm Vertices (Nodes) Edges Single edge Double edge Cost (For map traversal), distance is the norm Cost multiplier (>1) for rough terrain. Representation Adjacency Matrix Adjacency List [Connections to NavMesh]

Graph Nodes vs. Search Nodes 6.0 1.0 2 3 4 3.0 2.0 3 4 4.0 9.0 1 1 3.0 4.0 5 5 6 6 Graph Search Tree There are usually many search trees for the same graph. Start == 0, Goal == 6

Graph Nodes vs. Search Nodes, cont. Recommended approach: GraphNode class: [Any map-related data] Neighbor_pointers = […] SearchNode class (I actually just used a tuple here): GraphNode reference [optional] Heuristic value (later in A*) Cost-so-far value SearchTree map Key = GraphNode reference Value = parent GraphNode reference (or null for root) I actually stored this plus the depth and heuristic. Create SearchNodes and add to map as you explore the map. Positive: Easy to tell if you’ve visited a node – it’s in the map. Positive: Easy to restart the search – just throw out the map DON’T make any references to the search in the GraphNodes!

Actual Search Start with initial node, add it to the map Which node do we visit next? Depth-First Search Breadth-First Search Djikstra Search A* Search …

Depth-First P.C. # Could be faster w/ a stack (non-recursive) def dfs(curSNode, parentMap, mainGraph, g2sMap): for n in curSNode.GNode.neighbors: # [optional] early termination if n is goal. if n not in g2sMap: newCost = curSNode.costSoFar + mainGraph.edgeCost(curSNode.GNode, n) newSNode = new SNode(n, newCost) parentMap[newSNode] = curSNode g2sMap[n] = newSNode dfs(newSNode, parentMap, mainGraph, g2sMap) initSNode = new SNode(start, 0) searchTree = {initSNode : null} graph2searchMap = {start : initSNode} mapGraph = … dfs(initSNode, searchTree, mapGraph, graph2searchMap)

Depth-first search 2 S 6 3 8 Total=38.5 5 4 7 G 1 10.0 2 S 5.0 6 3.5 4.0 6.0 4.5 5.0 3 4.5 7.5 2.0 8 Total=38.5 5 3.5 5.0 2.0 3.0 4 7 1.5 3.0 G 1 6.0 The path we get will, in general, not be the best

Breadth-First Search P.C. initSNode = new SNode(start, 0) searchTree = {initSNode : null} graph2searchMap = {start : initSNode} mapGraph = … frontier = [initSNode] while len(frontier) != 0: new_frontier = [] for cur in frontier: # [optional] early termination if # cur is the goal for n in cur.GNode.neighbors: if n not in graph2searchMap: newCost = cur.costSoFar + mapGraph.edgeCost(s.GNode, n) newSNode = new SNode(n, newCost) searchTree[newSNode] = cur graph2searchMap[n] = newSNode new_frontier.append(newSNode) frontier = new_frontier

Breadth-first search 2 S 6 3 8 5 4 7 G 1 8 6 3 5 4 7 1 2 G 10.0 3.5 4.5 2.0 3.0 6.0 5.0 4.0 7.5 1.5 Again, we don’t necessarily get the “best” path.

Greedy-First Just like BFS, but pick the node that appears to take us closer to goal For this, we need some way to calculate a heuristic: a guess at distance to goal This is usually an under-estimate – see why? Problem: http://theory.stanford.edu/~amitp/GameProgramming/AStarComparison.html

DJIKSTRA’s ALGORITHM P.C. Like BFS also, but solves the greedy-first problem. But…does more work than necessary. # … everything else as with BFS for n in cur.GNode.neighbors: newCost = cur.costSoFar + mapGraph.edgeCost(s.GNode, n) if n not in graph2searchMap: newSNode = new SNode(n, newCost) searchTree[newSNode] = cur graph2searchMap[n] = newSNode elif newCost < graph2searchMap[n].costSoFar: searchTree[graph2searchMap[n]] = cur graph2searchMap[n].costSoFar = newCost Better than BFS because we re-route parent pointers if we find a better path. We aren’t guaranteed the absolute optimal solution, but it’s a pretty-good soln.

A* Algorithm Rather than looking at all neighbors in turn, pick the one we think will lie on the best path. A combination of actual_cost + heuristic cost Note how greedy-first only considered heuristic cost. f(x) = g(x) + h(x) # Total = actual + heuristic It is vital that the heuristic be consistent: i.e. less than or equal to the actual cost Otherwise, nodes we’ve visited must be re-examined. We also don’t want the hueristic to be too low: otherwise we’ll look at too many nodes. Re-route visited nodes, like Djikstra

A* P.C. initSNode = new SNode(start, 0) searchTree = {initSNode : null} open = new MinHeap() # Of SearchNode’s. Order by totalCost (actual + heuristic) open.push(initSNode) closed = new set() graph2searchMap = {start : initSNode} mapGraph = … while !open.empty(): cur = open.pop() closed.add(cur) # [not optional here] Early termination if cur is the goal for n in cur.GNode.neighbors: newCost = cur.costSoFar + mapGraph.edgeCost(s.GNode, n) if n not in graph2searchMap: newSNode = new SNode(n, newCost) searchTree[newSNode] = cur graph2searchMap[n] = newSNode open.push(newSNode) elif n not in closed and newCost < graph2searchMap[n].costSoFar: # Better path through us – like Djikstra’s graph2searchNode[n].costSoFar = newCost searchTree[graph2searchNode[n]] = cur # Important: reheapify open! # Not necessary if your heuristic is consistent. If not, we need to re-open # closed nodes # elif newCost < graph2searchMap[n].costSoFar: # graph2searchNode[n].costSoFar = newCost # searchTree[graph2searchNode[n]] = cur # closed.remove(graph2searchNode[n]) # open.add(graph2searchNode[n]) return failure

Another application of A*

The “new” A* ? Jump-Point Search seems to be gaining popularity in game programming. Good reference: https://harablog.wordpress.com/2011/09/07/jump-point-search/ Makes many improvements, but only works on square-grids. Can we make this work with nav-meshes?