private IntPath FindInToOutPath(RectangularGridObject rect, IntPair start, IntPair end) { IntPair outterEntrance; IntPair innerEntrance; GetNearestEntrancePosition(rect, start, out outterEntrance, out innerEntrance); return(FindInsidePath(rect, start, innerEntrance) + IntPathFactory.MakeXLinePath(innerEntrance, outterEntrance) + FindOutsidePath(rect, outterEntrance, end)); }
private IntPath FindInsidePath(RectangularGridObject rect, IntPair start, IntPair end) { if (!clearanceValid) { RecalculateClearance(); } Func <IntPair, bool> isClear = (p) => { int diagSize = Mathf.Min(rect.gridSizeX, rect.gridSizeY); if (!IsInsideShop(p)) { return(false); } for (int i = 0; i < diagSize; i++) { if (IsInsideShop(p + new IntPair(i, i)) && !(xClearance [p.x + i, p.y + i] >= rect.gridSizeX && yClearance [p.x + i, p.y + i] >= rect.gridSizeY)) { return(false); } } return(true); }; IntPair[] path = null; lock (occupied) { path = AStar <IntPair> .Solve((p) => { var p1 = new IntPair(p.x + 1, p.y); var p2 = new IntPair(p.x - 1, p.y); var p3 = new IntPair(p.x, p.y + 1); var p4 = new IntPair(p.x, p.y - 1); List <AStar <IntPair> .EdgeType> edges = new List <AStar <IntPair> .EdgeType> (); if (isClear(p1)) { edges.Add(new AStar <IntPair> .EdgeType(p, p1, 1)); } if (isClear(p2)) { edges.Add(new AStar <IntPair> .EdgeType(p, p2, 1)); } if (isClear(p3)) { edges.Add(new AStar <IntPair> .EdgeType(p, p3, 1)); } if (isClear(p4)) { edges.Add(new AStar <IntPair> .EdgeType(p, p4, 1)); } return(edges); }, (p) => Mathf.Abs (p.x - end.x) + Mathf.Abs(p.y - end.y), start, end); } return(IntPathFactory.MakePathFromArray(path)); }
private IntPath FindOutsidePath(RectangularGridObject rect, IntPair start, IntPair end) { int firstXAboveShop = shopSizeX; int firstXBelowShop = -rect.gridSizeX; int firstYAboveShop = shopSizeY; int firstYBelowShop = -rect.gridSizeY; if (end.x > firstXBelowShop && end.x < 0 && end.y < firstYAboveShop && end.y > firstYBelowShop) { end = new IntPair(firstXBelowShop, end.y); } if (end.y > firstYBelowShop && end.y < 0 && end.x < firstXAboveShop && end.x > firstXBelowShop) { end = new IntPair(end.x, firstYBelowShop); } Func <IntPair, bool> corner00 = (f) => f.x <= firstXBelowShop && f.y <= firstYBelowShop; Func <IntPair, bool> cornerX0 = (f) => f.x >= firstXAboveShop && f.y <= firstYBelowShop; Func <IntPair, bool> corner0Y = (f) => f.x <= firstXBelowShop && f.y >= firstYAboveShop; Func <IntPair, bool> cornerXY = (f) => f.x >= firstXAboveShop && f.y >= firstYAboveShop; Func <IntPair, bool> corner = (f) => corner00(f) || cornerX0(f) || corner0Y(f) || cornerXY(f); bool sameX = (start.x <= firstXBelowShop && end.x <= firstXBelowShop) || (start.x >= firstXAboveShop && end.x >= firstXAboveShop); bool sameY = (start.y <= firstYBelowShop && end.y <= firstYBelowShop) || (start.y >= firstYAboveShop && end.y >= firstYAboveShop); bool oppX = (start.x <= firstXBelowShop && end.x >= firstXAboveShop) || (start.x >= firstXAboveShop && end.x <= firstXBelowShop); bool oppY = (start.y <= firstYBelowShop && end.y >= firstYAboveShop) || (start.y >= firstYAboveShop && end.y <= firstYBelowShop); if (sameX || sameY) { return(IntPathFactory.MakeCornerPath(start, end)); } if (corner(start)) { if (corner(end)) { return(IntPathFactory.MakeCornerPath(start, end)); } if (oppX) { return(IntPathFactory.MakeCornerPathXFirst(start, end)); } else { return(IntPathFactory.MakeCornerPathYFirst(start, end)); } } if (corner(end)) { if (oppX) { return(IntPathFactory.MakeCornerPathYFirst(start, end)); } else { return(IntPathFactory.MakeCornerPathXFirst(start, end)); } } if (oppX) { // go around shop on the Y axis int minYPath = Mathf.Abs(start.y - firstYBelowShop) + Mathf.Abs(end.y - firstYBelowShop); int maxYPath = Mathf.Abs(start.y - firstYAboveShop) + Mathf.Abs(end.y - firstYAboveShop); IntPair midY; if (minYPath < maxYPath) { midY = new IntPair(start.x, firstYBelowShop); } else { midY = new IntPair(start.x, firstYAboveShop); } return(IntPathFactory.MakeCPath(start, midY, end)); } else if (oppY) { // go around shop on the X axis int minXPath = Mathf.Abs(start.y - firstYBelowShop) + Mathf.Abs(end.y - firstYBelowShop); int maxXPath = Mathf.Abs(start.y - firstYAboveShop) + Mathf.Abs(end.y - firstYAboveShop); IntPair midX; if (minXPath < maxXPath) { midX = new IntPair(firstXBelowShop, start.y); } else { midX = new IntPair(firstXAboveShop, start.y); } return(IntPathFactory.MakeCPath(start, midX, end)); } if (start.x <= firstXBelowShop || start.x >= firstXAboveShop) { return(IntPathFactory.MakeCornerPathYFirst(start, end)); } else { return(IntPathFactory.MakeCornerPathXFirst(start, end)); } }
public static IntPath operator +(IntPath p1, IntPath p2) { return(IntPathFactory.AddPaths(p1, p2)); }