protected internal override bool perform() { Bpoint from = new Bpoint{ x = p.LocX, y = p.LocY}; Bpoint to = new Bpoint { x = p.g.b.player.LocX, y = p.g.b.player.LocY}; p.trasa = p.g.b.GetShortestPath(from, to); return true; }
protected internal override bool perform() { if (Math.Abs(p.LocX - p.g.b.player.LocX) < 5 && Math.Abs(p.LocY - p.g.b.player.LocY) < 5) { Bpoint from = new Bpoint{ x = p.LocX, y = p.LocY}; Bpoint to = new Bpoint { x = p.g.b.player.LocX, y = p.g.b.player.LocY}; p.trasa = p.g.b.GetShortestPath(from, to); } else { int x = p.LocX; int y = p.LocY; Board.Board b = p.g.b; if (p.InMove()) return true; Random r = new Random(); for (int i = Math.Max(0,y-1); i <= Math.Min(y+1, b.Height -1); i++) for (int j = Math.Max(x - 1, 0); j <= Math.Min(x + 1, b.Width - 1); j++) { if ((j == x || i == y) && !(i == y && j == x)) { if (!p.g.b.IsFree(j, i)) continue; int los = r.Next() % 4; if (los == 0) { p.gotox = j; p.gotoy = i; return true; } } } } return true; }
public static bool equals(Bpoint a, Bpoint b) { if (a.x != b.x) return false; if (a.y != b.y) return false; return true; }
public List<Bpoint> ReconstructPath(Bpoint[,] come_from, Bpoint goal) { List<Bpoint> path = new List<Bpoint>(); Bpoint precedence = come_from[goal.y, goal.x]; if (precedence != null) path.AddRange(ReconstructPath(come_from, precedence)); path.Add(goal); return path; }
public int HeuristicEstimate(Bpoint from, Bpoint to) { double diffx = Math.Abs(from.x - to.x); double diffy = Math.Abs(from.y - to.y); return (int)(diffx + diffy); // metryka taksówkowa //return (int)Math.Sqrt(diffx * diffx + diffy * diffy); }
public List<Bpoint> GetShortestPath(Bpoint from, Bpoint to) { List<Bpoint> path = new List<Bpoint>(); List<Bpoint> closedset = new List<Bpoint>(); List<Bpoint> openset = new List<Bpoint>(); int[,] g_score = new int[Height, Width]; int[,] h_score = new int[Height, Width]; int[,] f_score = new int[Height, Width]; Bpoint[,] come_from = new Bpoint[Height,Width]; Bpoint[,] nodes = new Bpoint[Height, Width]; for (int i = 0; i < Height; i++) for (int j = 0; j < Width; j++) { nodes[i, j] = new Bpoint { x = j, y = i }; } openset.Add(nodes[from.y, from.x]); g_score[from.y, from.x] = 0; h_score[from.y, from.x] = HeuristicEstimate(from, to); f_score[from.y,from.x] = g_score[from.y, from.x] + h_score[from.y, from.x]; while (openset.Count != 0) { int koszt_minimalny = int.MaxValue; Bpoint current = null; // znajdź element z najmniejszym kosztem for (int i = 0; i < Height; i++) for (int j = 0; j < Width; j++) { if (openset.Contains(nodes[i,j])) { if (koszt_minimalny > f_score[i, j]) { koszt_minimalny = f_score[i, j]; current = nodes[i, j]; } } } // mamy current if (current == nodes[to.y, to.x]) { // zrekonstruuj path path = ReconstructPath(come_from, nodes[to.y, to.x]); return path; } bool tentative_is_better = false; openset.Remove(current); closedset.Add(current); for (int i = Math.Max(current.y - 1, 0); i <= Math.Min(current.y + 1, Height - 1); i++) for (int j = Math.Max(current.x - 1, 0); j <= Math.Min(current.x + 1, Width - 1); j++) { if (i == current.y && j == current.x) continue; if (i == current.y || j == current.x) { // łapią się wszyscy sąsiedzi if (IsFree(j, i)) { Bpoint neighbour = nodes[i, j]; if (closedset.Contains(neighbour)) continue; int tentative_g_score = g_score[current.y, current.x] + 1; if (!openset.Contains(neighbour)) { openset.Add(neighbour); h_score[neighbour.y, neighbour.x] = HeuristicEstimate(neighbour, to); tentative_is_better = true; } else { if (tentative_g_score < g_score[neighbour.y, neighbour.x]) tentative_is_better = true; else tentative_is_better = false; } if (tentative_is_better) { come_from[neighbour.y, neighbour.x] = current; g_score[neighbour.y, neighbour.x] = tentative_g_score; f_score[neighbour.y, neighbour.x] = g_score[neighbour.y, neighbour.x] + h_score[neighbour.y, neighbour.x]; } } } } } return null; }