Advertisement
caLLowCreation

Pathfinder 2D in VB

Oct 20th, 2015
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 7.50 KB | None | 0 0
  1. Imports System.Drawing
  2.  
  3. Public Class Pathfinder
  4.     Dim Nodes As List(Of Node)
  5.     Public PathList As List(Of Node)
  6.     Public OpenList As List(Of Node)
  7.     Public CloseList As List(Of Node)
  8.  
  9.     Dim Start As Point
  10.     Dim Goal As Point
  11.  
  12.     Public UseCutCorners As Boolean
  13.     Public UseManhattan As Boolean
  14.     Public UseDiagonal As Boolean
  15.  
  16.     Public Sub New(Nodes As List(Of Node))
  17.         Me.Nodes = Nodes
  18.         Me.OpenList = New List(Of Node)
  19.         Me.CloseList = New List(Of Node)
  20.         Me.PathList = New List(Of Node)
  21.         Me.UseCutCorners = False
  22.         Me.UseManhattan = True
  23.         Me.UseDiagonal = True
  24.     End Sub
  25.  
  26.     Public Sub ClearResults()
  27.         Me.OpenList.Clear()
  28.         Me.CloseList.Clear()
  29.         Me.PathList.Clear()
  30.     End Sub
  31.  
  32.     Public Sub FindPath(start As Point, goal As Point)
  33.         Me.Start = start
  34.         Me.Goal = goal
  35.         ClearResults()
  36.  
  37.         Dim HCost As Double = GetHeuristic(start, goal, UseManhattan)
  38.         Dim current As New Node(start, Nothing, 0, HCost, 0)
  39.  
  40.         OpenList.Add(current)
  41.  
  42.         While OpenList.Count > 0
  43.             OpenList = OpenList.OrderBy(Function(n) n.FCost).ToList()
  44.             current = OpenList(0)
  45.             If current.Tile = goal Then
  46.                 While current.Parent IsNot Nothing ' the ONLY null parent is the start node
  47.                     PathList.Add(current)
  48.                     current = current.Parent
  49.                 End While
  50.                 Return
  51.             End If
  52.             OpenList.Remove(current)
  53.             CloseList.Add(current)
  54.             For x As Integer = -1 To 1
  55.                 For y As Integer = -1 To 1
  56.                     Dim xi As Integer = current.Tile.X + x
  57.                     Dim yi As Integer = current.Tile.Y + y
  58.  
  59.                     'No Diagonal
  60.                     If GetUseDiagonal(x, y, UseDiagonal) Then
  61.                         Continue For
  62.                     End If
  63.  
  64.                     Dim at As Node = GetNode(xi, yi)
  65.                     If at Is Nothing Then
  66.                         Continue For
  67.                     End If
  68.  
  69.  
  70.                     If at.Weight > 0 Then
  71.                         Continue For
  72.                     End If
  73.  
  74.                     Dim a As New Point(xi, yi)
  75.  
  76.                     'at.Parent = current
  77.                     If GetCutCorner(x, y, current, Me.UseCutCorners) Then
  78.                         Continue For
  79.                     End If
  80.  
  81.                     Dim g_cost As Double = current.GCost + GetDistance(current.Tile, a) 'use 10 or 14 instead of getdistance here
  82.                     Dim h_cost As Double = GetHeuristic(a, goal, UseManhattan)
  83.  
  84.                     Dim newNode As New Node(a, current, g_cost, h_cost, at.Weight)
  85.                     If OnCloseList(newNode) And g_cost >= newNode.GCost Then
  86.                         Continue For
  87.                     End If
  88.  
  89.                     If Not OnOpenList(newNode) Or g_cost < newNode.GCost Then
  90.                         OpenList.Add(newNode)
  91.                     End If
  92.                 Next
  93.             Next
  94.         End While
  95.     End Sub
  96.  
  97.     Public Function OnOpenList(ByVal checking As Node) As Boolean
  98.         Return OpenList.Find(Function(n) n.Tile = checking.Tile) IsNot Nothing
  99.     End Function
  100.  
  101.     Public Function OnCloseList(ByVal checking As Node) As Boolean
  102.         Return CloseList.Find(Function(n) n.Tile = checking.Tile) IsNot Nothing
  103.     End Function
  104.  
  105.     Public Function OnPathList(ByVal checking As Node) As Boolean
  106.         Return PathList.Find(Function(n) n.Tile = checking.Tile) IsNot Nothing
  107.     End Function
  108.  
  109.     Private Function GetUseDiagonal(ByVal x As Integer, ByVal y As Integer, ByVal useDiagonal As Boolean) As Boolean
  110.         'No Diagonal
  111.         If Not useDiagonal And ((x = -1 And y = -1) Or (x = 1 And y = 1) Or (x = -1 And y = 1) Or (x = 1 And y = -1)) Then
  112.             Return True
  113.         End If
  114.         Return False
  115.     End Function
  116.  
  117.     Private Function GetCutCorner(ByVal x As Integer, ByVal y As Integer, checking As Node, ByVal useCutCorners As Boolean) As Boolean
  118.         If Not useCutCorners Then
  119.             'No corner cutting
  120.             If x = 1 And y = 1 Then 'checking down right
  121.                 Dim rightNode As Node = GetNode(checking.Tile.X + 1, checking.Tile.Y) 'parent right
  122.                 If rightNode IsNot Nothing Then
  123.                     If rightNode.Weight > 0 Then
  124.                         Return True
  125.                     End If
  126.                 End If
  127.                 Dim bottomNode As Node = GetNode(checking.Tile.X, checking.Tile.Y + 1) 'parent down
  128.                 If bottomNode IsNot Nothing Then
  129.                     If bottomNode.Weight > 0 Then
  130.                         Return True
  131.                     End If
  132.                 End If
  133.             End If
  134.  
  135.             If x = 1 And y = -1 Then 'checking up right
  136.                 Dim rightNode As Node = GetNode(checking.Tile.X + 1, checking.Tile.Y) 'parent right
  137.                 If rightNode IsNot Nothing Then
  138.                     If rightNode.Weight > 0 Then
  139.                         Return True
  140.                     End If
  141.                 End If
  142.                 Dim upNode As Node = GetNode(checking.Tile.X, checking.Tile.Y - 1) 'parent up
  143.                 If upNode IsNot Nothing Then
  144.                     If upNode.Weight > 0 Then
  145.                         Return True
  146.                     End If
  147.                 End If
  148.             End If
  149.  
  150.             If x = -1 And y = 1 Then 'checking down left
  151.                 Dim leftNode As Node = GetNode(checking.Tile.X - 1, checking.Tile.Y)
  152.                 If leftNode IsNot Nothing Then
  153.                     If leftNode.Weight > 0 Then
  154.                         Return True
  155.                     End If
  156.                 End If
  157.                 Dim bottomNode As Node = GetNode(checking.Tile.X, checking.Tile.Y + 1) 'parent down
  158.                 If bottomNode IsNot Nothing Then
  159.                     If bottomNode.Weight > 0 Then
  160.                         Return True
  161.                     End If
  162.                 End If
  163.             End If
  164.  
  165.             If x = -1 And y = -1 Then 'checking up left
  166.                 Dim leftNode As Node = GetNode(checking.Tile.X - 1, checking.Tile.Y)
  167.                 If leftNode IsNot Nothing Then
  168.                     If leftNode.Weight > 0 Then
  169.                         Return True
  170.                     End If
  171.                 End If
  172.                 Dim upNode As Node = GetNode(checking.Tile.X, checking.Tile.Y - 1) 'parent up
  173.                 If upNode IsNot Nothing Then
  174.                     If upNode.Weight > 0 Then
  175.                         Return True
  176.                     End If
  177.                 End If
  178.             End If
  179.         End If
  180.         Return False
  181.     End Function
  182.  
  183.     Private Function GetHeuristic(start As Point, goal As Point, ByVal useManhattan As Boolean) As Double
  184.         If useManhattan Then
  185.             Return GetManhatnan(start, goal)
  186.         Else
  187.             Return GetDistance(start, goal)
  188.         End If
  189.  
  190.     End Function
  191.  
  192.     Private Function GetManhatnan(start As Point, goal As Point)
  193.         Return Math.Abs(goal.X - start.X) + Math.Abs(goal.Y - start.Y)
  194.     End Function
  195.  
  196.     Private Function GetDistance(start As Point, goal As Point) As Double
  197.         Dim dx As Double = start.X - goal.X
  198.         Dim dy As Double = start.Y - goal.Y
  199.         Return Math.Sqrt(dx * dx + dy * dy)
  200.     End Function
  201.  
  202.     Public Function GetNode(x As Integer, y As Integer) As Node
  203.         Return Nodes.Find(Function(n) n.Tile.X = x And n.Tile.Y = y)
  204.     End Function
  205.  
  206.  
  207. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement