C
C#5mo ago
YouWouldnt

✅ A* Algorithm Get Node where x and y is 1 less (Neigbour)

Any idea how to get the neighbours? ive tried to grab the neighbour pathnode item by subtracting 1 from x. Either im not doing it correctly or the list needs to be formatted better but all the ways i have tried are not seeming to work so help?.
c#
public class PathNode
{
private double width;
private double height;
public double x;
public double y;
//private List<double> neighbours;
private bool closed = false;
private bool walkable = true;
public PathNode(double width, double height, double x, double y)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public bool barrierNode()
{
return walkable = false;
}
public void updateNeighbours(List<PathNode> panelNodes)
{
if (x < width - 1 /* Code Here to get the pathnode with x - 1 and y -1*/ )
{

}
}
}
c#
public class PathNode
{
private double width;
private double height;
public double x;
public double y;
//private List<double> neighbours;
private bool closed = false;
private bool walkable = true;
public PathNode(double width, double height, double x, double y)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public bool barrierNode()
{
return walkable = false;
}
public void updateNeighbours(List<PathNode> panelNodes)
{
if (x < width - 1 /* Code Here to get the pathnode with x - 1 and y -1*/ )
{

}
}
}
72 Replies
Duath
Duath5mo ago
hi, what does panelNodes argument hold and, whatever it is, is it ordered? not knowing pretty much anything, would "Dictionary" or anything "Hash.."ed be a better (easier) choice?
YouWouldnt
YouWouldnt5mo ago
panelNodes holds all the Nodes in the A* Grid. It’s a 1201x601 size Grid with each coordinate being 1 singular instance of the “PathNode” class Given the amount of classes due to the grid size…it’s definitely gonna be a class I don’t call until needed. #performancematters 😂
Duath
Duath5mo ago
so without changing the data and without knowing the order of the nodes a very crude way would be var mx = this.x - 1; var my = this.y - 1; var x_neighbour = panelNodes.FirstOrDefault(n => n.x == mx); var y_neighbour = panelNodes.FirstOrDefault(n => n.y == my); but it will hurst perf hurt*
YouWouldnt
YouWouldnt5mo ago
Do you want me to show you the code creating the nodes?
Duath
Duath5mo ago
simplest ways, either change the List<> or change the PathNode class adding pointers to neighours, basically implementing your own "true" list yes, paste it
YouWouldnt
YouWouldnt5mo ago
Okay 2 secs
Duath
Duath5mo ago
but the code above will find what you need, or null it doesnt care about duplicates nor anything else basically 😛
YouWouldnt
YouWouldnt5mo ago
c#
public class PanelGrid
{
public double width;
public double height;
public double[,] gridArray;
private Canvas panelImport;
public List<PathNode> panelNodes = new List<PathNode>();
public PanelGrid(Canvas panelImport)
{
this.panelImport = panelImport;
width = panelImport.Width;
height = panelImport.Height;

gridArray = new double[(int)width, (int)height];

int i = 0;
for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
panelNodes.Add(new PathNode(width, height, x, y));
i++;
}
}
}
}
c#
public class PanelGrid
{
public double width;
public double height;
public double[,] gridArray;
private Canvas panelImport;
public List<PathNode> panelNodes = new List<PathNode>();
public PanelGrid(Canvas panelImport)
{
this.panelImport = panelImport;
width = panelImport.Width;
height = panelImport.Height;

gridArray = new double[(int)width, (int)height];

int i = 0;
for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
panelNodes.Add(new PathNode(width, height, x, y));
i++;
}
}
}
}
only use for "Canvas panelImport" is just to get the width and height for the grid also i++ was used for testing i just forgot to remove it 🤣
Duath
Duath5mo ago
yeah that private field is not needed, but it's a very minor point 😛
YouWouldnt
YouWouldnt5mo ago
yea i was using it to edit stuff earlier.
c#
public void updateNeighbours(List<PathNode> panelNodes)
{
var mx = x - 1;
var my = y - 1;
var panelNeighbour = panelNodes.FirstOrDefault(n => n.x == mx & n.y == my);
//var yNeighbour = panelNodes.FirstOrDefault(n => n.y == my);
if (x < width - 1 && !panelNeighbour.barrierNode())
{

}
}
c#
public void updateNeighbours(List<PathNode> panelNodes)
{
var mx = x - 1;
var my = y - 1;
var panelNeighbour = panelNodes.FirstOrDefault(n => n.x == mx & n.y == my);
//var yNeighbour = panelNodes.FirstOrDefault(n => n.y == my);
if (x < width - 1 && !panelNeighbour.barrierNode())
{

}
}
all things considered. this should get the .barrierNode return value from that list item right? i combined it because i need to get a singular coord
Duath
Duath5mo ago
wait a sec 🙂
YouWouldnt
YouWouldnt5mo ago
yes?
Duath
Duath5mo ago
just gimme a sec xD
YouWouldnt
YouWouldnt5mo ago
haha your good dw xD
Duath
Duath5mo ago
& is a bit operator, && is a boolean operato, but what you want there is a || iun that lambda
YouWouldnt
YouWouldnt5mo ago
facepalm rookie mistake. i didnt even click that i did that lol
Duath
Duath5mo ago
something like that if you want to run once like above - panelNodes.Where(n=> n.x | x.y).ToList(); yyes those are my nemesis as well, misslicks, ctrl+c, ctrl+v.. even ctrl+s can ef you over 😛 but then Where can return null, one or two items.. where two is the expected one 🙂 but im thinking about the second solution i mentioned
YouWouldnt
YouWouldnt5mo ago
?
Duath
Duath5mo ago
where PathNode holsd references to its neighbours*
YouWouldnt
YouWouldnt5mo ago
Oh yea so I have that in there already…it’s just commented out. “neighbours” But before you get all “why didn’t you tell me” 😂 I hadn’t created a search into that yet.
Duath
Duath5mo ago
show me then 😛
YouWouldnt
YouWouldnt5mo ago
It’s literally just “private list neighbours” Obviously coded correctly
c#
//private List<double> neighbours;
c#
//private List<double> neighbours;
thats inside the "PathNode" class
Duath
Duath5mo ago
how do you create such a list?
YouWouldnt
YouWouldnt5mo ago
reason why i havent implemented it is because i dont want to get all the grid members. just the ones surrounding it for better performance
Duath
Duath5mo ago
or you dont? yet 😛
YouWouldnt
YouWouldnt5mo ago
yep havent yet
Duath
Duath5mo ago
well it's just a reference, not a value object 😛
YouWouldnt
YouWouldnt5mo ago
no point in me piling the whole grid into 7 billion classes when i just want the 8 nodes that are surrounding the node
Duath
Duath5mo ago
you wouldn't, but yes memory would rise, but..
YouWouldnt
YouWouldnt5mo ago
oh i know. dont worry i know i havent made it into a new list. i commented it out for that reason because i wasnt sure what i was gonna do with it
Duath
Duath5mo ago
x and y is a tuple.. basically and it is unique, from what i rember about A* right> ?
YouWouldnt
YouWouldnt5mo ago
my x and y is in double[,] format but i can switch back to tuple cuz i did have it there earlier. yes the x and y are unique to each cord in the grid sorry x and y are both double type variables. they are not combined in an array by default
Duath
Duath5mo ago
well you can always create your own "tuple" class, but now you dont have to well what dotnet version do yo use? 😉
YouWouldnt
YouWouldnt5mo ago
6.0 i believe it is
YouWouldnt
YouWouldnt5mo ago
No description
Duath
Duath5mo ago
because (double x, double y) node = (0.1, 0.2);
YouWouldnt
YouWouldnt5mo ago
7.0 actually
Duath
Duath5mo ago
which is a new tuple supoprts == and != its a value type though
YouWouldnt
YouWouldnt5mo ago
not quite following you
Duath
Duath5mo ago
so i dont know about a performance with dictionaries, but dictionaries 🙂 insdtead of a list
YouWouldnt
YouWouldnt5mo ago
what...so switch out my x and y type from double to dictionary? oh instrad of list
Duath
Duath5mo ago
use Dictionary<"tuple", PathNode> ddict than you can find any node in a O(1) time 🙂 in an easy way
YouWouldnt
YouWouldnt5mo ago
c#
public List<PathNode> panelNodes = new List<PathNode>();
c#
public List<PathNode> panelNodes = new List<PathNode>();
you talking about switching this out?
Duath
Duath5mo ago
yes exactly to a dictionarty with a key including both x and y 🙂 you can use tyuple or new tuples or wrote your won tupe class and overridfe hascode method
YouWouldnt
YouWouldnt5mo ago
c#
public Dictionary<"tuple", PathNode> panelNodes = new Dictionary<"tuple", PathNode>;
c#
public Dictionary<"tuple", PathNode> panelNodes = new Dictionary<"tuple", PathNode>;
either im stupid and not reading this properly or its just my never used dictionary class before....."tuple" is red underlined
Duath
Duath5mo ago
where: "tuple" is class for axample publis class MyTuple { public int x; public int y; public MyTuple(int argX, int argY) { x = argX; y = argY;}}
YouWouldnt
YouWouldnt5mo ago
2 secs
Duath
Duath5mo ago
and use it both as a composite field in the PathNode class
YouWouldnt
YouWouldnt5mo ago
c#
namespace Birds_Eye.Views.Resources.Functions
{
public class PanelGrid
{
public double width;
public double height;
public double[,] gridArray;
private Canvas panelImport;
public Dictionary<panelTuple, PathNode> panelNodes = new Dictionary<panelTuple, PathNode>();
public PanelGrid(Canvas panelImport)
{
this.panelImport = panelImport;
width = panelImport.Width;
height = panelImport.Height;

gridArray = new double[(int)width, (int)height];

for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
panelNodes.Add(new PathNode(width, height, x, y));
}
}
}
}
}

namespace Birds_Eye.Views.Resources.Functions
{
public class panelTuple
{
public int x;
public int y;
public panelTuple(int x, int y)
{
this.x = x;
this.y = y;
}
}
}
c#
namespace Birds_Eye.Views.Resources.Functions
{
public class PanelGrid
{
public double width;
public double height;
public double[,] gridArray;
private Canvas panelImport;
public Dictionary<panelTuple, PathNode> panelNodes = new Dictionary<panelTuple, PathNode>();
public PanelGrid(Canvas panelImport)
{
this.panelImport = panelImport;
width = panelImport.Width;
height = panelImport.Height;

gridArray = new double[(int)width, (int)height];

for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
panelNodes.Add(new PathNode(width, height, x, y));
}
}
}
}
}

namespace Birds_Eye.Views.Resources.Functions
{
public class panelTuple
{
public int x;
public int y;
public panelTuple(int x, int y)
{
this.x = x;
this.y = y;
}
}
}
i got you now.
Duath
Duath5mo ago
do not forget to overridre hashcode method in that tuple class use this one 🙂 HashCode.Combine you can store it as a private field (the hashCode) but do not persist it, cause of problems 😛 Add method you ned to provide a key and a value check its header 🙂
YouWouldnt
YouWouldnt5mo ago
i need to do some reading on dictionaries and tuples...god damn. sorry can you show me the method lol i know its public override
Duath
Duath5mo ago
wait a sec public class MyTuple { private int _hashCode; public MyTuple(...) { // your code _hashCode = HashCode.Combine<int, int>(x, y); } //somewhere down there public override GetHashCode() { return _hashCode; } } for (int y = 0; y < gridArray.GetLength(1); y++) { panelNodes.Add(new MyTuple(x, y), new PathNode(width, height, x, y)); } this part is in a Grid class 😛 then in : public void updateNeighbours(List<PathNode> panelNodes) { var mx = x - 1; var my = y - 1; MyTuple predicate = new(x-1, y-1); if (panelNodes.CintainsKey(predicate)) { // access it by panelNodes[predicate] } } do not store _hashCode anywhere outside of the memory 😛 public override INT GetHashCode() * 😛
YouWouldnt
YouWouldnt5mo ago
c#
MyTuple predicate = new(x-1, y-1);
c#
MyTuple predicate = new(x-1, y-1);
doesnt work nor when i change to
c#
MyTuple predicate = new MyTuple(x-1, y-1);
c#
MyTuple predicate = new MyTuple(x-1, y-1);
Duath
Duath5mo ago
doesnt comple the not working part.. some details? 😛
YouWouldnt
YouWouldnt5mo ago
double needed to be casted to int lol
Duath
Duath5mo ago
aaa my bnad
YouWouldnt
YouWouldnt5mo ago
c#
panelTuple predicate = new panelTuple((int)x - 1,(int) y - 1);
c#
panelTuple predicate = new panelTuple((int)x - 1,(int) y - 1);
Duath
Duath5mo ago
change it to double of course wherever i use int
YouWouldnt
YouWouldnt5mo ago
got it tho
Duath
Duath5mo ago
mybad 😛
YouWouldnt
YouWouldnt5mo ago
haha alg casting is annoying and easy to forget
Duath
Duath5mo ago
no dont cast it it a waste of tie and memory 😛 in this case just use double as types bouth in mytupel and in dictionery's key where dicts key is ourt calss so you dont have to 😛 i should have done it
YouWouldnt
YouWouldnt5mo ago
oh right i can just change the tuple x type. im an egg
Duath
Duath5mo ago
yes you have the power here 😛 you are the captain now 😄 HashCode.Combine<double, double> as well
YouWouldnt
YouWouldnt5mo ago
yep changed that
Duath
Duath5mo ago
casting int to double looses data, so it would not work anyway
YouWouldnt
YouWouldnt5mo ago
c#
namespace Birds_Eye.Views.Resources.Functions
{
public class PathNode
{
private double width;
private double height;
public double x;
public double y;
//private List<double> neighbours;
private bool closed = false;
private bool walkable = true;
public PathNode(double width, double height, double x, double y)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public double[,] getPosition()
{
return new double[(int)x, (int)y];
}
public bool isClosed()
{
return closed = true;
}
public bool isOpen()
{
return closed = false;
}
public void closeNode()
{
closed = true;
}
public void openNode()
{
closed = false;
}
public bool barrierNode()
{
return walkable = false;
}
public void updateNeighbours(Dictionary<panelTuple, PathNode> panelNodes)
{
var mx = x - 1;
var my = y - 1;
panelTuple predicate = new panelTuple(x - 1, y - 1);
if (panelNodes.ContainsKey(predicate))
{
if (x < width - 1 && panelNodes[predicate].barrierNode())
{

}
}
}
}
}

namespace Birds_Eye.Views.Resources.Functions
{
public class PanelGrid
{
private double width;
private double height;
private double[,] gridArray;
public Dictionary<panelTuple, PathNode> panelNodes = new Dictionary<panelTuple, PathNode>();
public PanelGrid(Canvas panelImport)
{
width = panelImport.Width;
height = panelImport.Height;

gridArray = new double[(int)width, (int)height];

for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
panelNodes.Add(new panelTuple(x, y), new PathNode(width, height, x, y));
}
}
}
}
}

namespace Birds_Eye.Views.Resources.Functions
{
public class panelTuple
{
public double x;
public double y;
private int _hashCode;
public panelTuple(double x, double y)
{
this.x = x;
this.y = y;
_hashCode = HashCode.Combine(x, y);
}
public override int GetHashCode()
{
return _hashCode;
}
}
}
c#
namespace Birds_Eye.Views.Resources.Functions
{
public class PathNode
{
private double width;
private double height;
public double x;
public double y;
//private List<double> neighbours;
private bool closed = false;
private bool walkable = true;
public PathNode(double width, double height, double x, double y)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public double[,] getPosition()
{
return new double[(int)x, (int)y];
}
public bool isClosed()
{
return closed = true;
}
public bool isOpen()
{
return closed = false;
}
public void closeNode()
{
closed = true;
}
public void openNode()
{
closed = false;
}
public bool barrierNode()
{
return walkable = false;
}
public void updateNeighbours(Dictionary<panelTuple, PathNode> panelNodes)
{
var mx = x - 1;
var my = y - 1;
panelTuple predicate = new panelTuple(x - 1, y - 1);
if (panelNodes.ContainsKey(predicate))
{
if (x < width - 1 && panelNodes[predicate].barrierNode())
{

}
}
}
}
}

namespace Birds_Eye.Views.Resources.Functions
{
public class PanelGrid
{
private double width;
private double height;
private double[,] gridArray;
public Dictionary<panelTuple, PathNode> panelNodes = new Dictionary<panelTuple, PathNode>();
public PanelGrid(Canvas panelImport)
{
width = panelImport.Width;
height = panelImport.Height;

gridArray = new double[(int)width, (int)height];

for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
panelNodes.Add(new panelTuple(x, y), new PathNode(width, height, x, y));
}
}
}
}
}

namespace Birds_Eye.Views.Resources.Functions
{
public class panelTuple
{
public double x;
public double y;
private int _hashCode;
public panelTuple(double x, double y)
{
this.x = x;
this.y = y;
_hashCode = HashCode.Combine(x, y);
}
public override int GetHashCode()
{
return _hashCode;
}
}
}
Much better 🙂 couple bits of garbage now to clean up but now i have the neighbour and more importantly can access their return method functions 🙂
Duath
Duath5mo ago
its actually quite fast as well no boxing issues i think 😛
YouWouldnt
YouWouldnt5mo ago
legendary man. i added you......in case i have more errors....... but thank you for that.
Duath
Duath5mo ago
should do the job no prob
YouWouldnt
YouWouldnt5mo ago
ill let you know how it goes. Thanks bro 🙂
Duath
Duath5mo ago
"return walkable = false;" will assign false to walkable and then return false always 😛