//--------------------------------------------------------------------- void _NewStep(EbAstarStep step) { for (int idx = 0; idx < step.RoundSteps.Count; ++idx) { EbAstarRoundStep roundStep = step.RoundSteps[idx]; EbAstarStep childStep = roundStep.node; if (childStep.IsClose) { continue; } float newG = roundStep.cost + step.G; if (childStep.IsOpen) { if (childStep.G > newG) { childStep.G = newG; childStep.Key = childStep.G + childStep.H; childStep.Parent = step; } } else { childStep.G = newG; childStep.H = EbAstarStep.Distance(childStep, mStepDest); childStep.Key = childStep.G + childStep.H; childStep.Parent = step; _AddToOpen(childStep); } } }
//--------------------------------------------------------------------- public static float Distance(EbAstarStep from, EbAstarStep to) { float delta_x = from.Pos.x - to.Pos.x; float delta_y = from.Pos.y - to.Pos.y; return((float)Math.Sqrt(delta_x * delta_x + delta_y * delta_y)); }
//--------------------------------------------------------------------- void _fresh(int x, int y) { EbAstarStep step = mListStep[x + y * mSizeX]; if (step.Cost > 0f) { return; } for (int yIdx = y - 1; yIdx < y + 2; ++yIdx) { for (int xIdx = x - 1; xIdx < x + 2; ++xIdx) { if (xIdx == x && yIdx == y) { continue; } EbAstarStep roundStep = mListStep[xIdx + yIdx * mSizeX]; if (roundStep.Cost == 0f) { EbAstarRoundStep node = new EbAstarRoundStep(); node.node = roundStep; float deltaX = x - xIdx; float deltaY = y - yIdx; node.cost = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY); step.RoundSteps.Add(node); } else { roundStep.Cost = 1f; } } } }
//--------------------------------------------------------------------- public void MakeRoute(List <EbAstarStep> list_step) { int dir = 1 + (1 << 2); EbAstarStep next = mStepBest; if (next == null) { return; } while (true) { EbAstarStep fromStep = next; next = next.Parent; if (next != null) { EbAstarStep toStep = next; int deltaX = toStep.Pos.x - fromStep.Pos.x + 1; int deltaY = (toStep.Pos.y - fromStep.Pos.y + 1) << 2; int delta = deltaY + deltaX; if (delta != dir) { list_step.Insert(0, fromStep); dir = delta; } } else { list_step.Insert(0, fromStep); break; } } }
//--------------------------------------------------------------------- public void clipRoute(List <EbAstarStep> complex, List <EbVector2> simple) { if (complex.Count <= 2) { for (int idx = 0; idx < complex.Count; ++idx) { EbAstarStep pre = complex[idx]; simple.Add(new EbVector2(pre.Pos.x, pre.Pos.y)); } return; } EbAstarStep from = complex[0]; simple.Add(new EbVector2(from.Pos.x, from.Pos.y)); for (int idx = 1; idx < complex.Count; ++idx) { EbAstarStep pre = complex[idx - 1]; EbAstarStep current = complex[idx]; if (pick(from.Pos.x, from.Pos.y, current.Pos.x, current.Pos.y)) { simple.Add(new EbVector2(pre.Pos.x, pre.Pos.y)); from = pre; } } EbAstarStep back = complex[complex.Count - 1]; simple.Add(new EbVector2(back.Pos.x, back.Pos.y)); }
//--------------------------------------------------------------------- public void blockStart(int size_x, int size_y) { mSizeX = size_x; mSizeY = size_y; mListStep = new EbAstarStep[mSizeX * mSizeY]; for (int y = 0; y < mSizeY; ++y) { for (int x = 0; x < mSizeX; ++x) { EbAstarStep step = new EbAstarStep(); step.Cost = 0f; step.Pos.x = x; step.Pos.y = y; mListStep[x + y * mSizeX] = step; } } }
//--------------------------------------------------------------------- public bool Search(EbAstarStep src, EbAstarStep dest) { src.G = 0; src.H = EbAstarStep.Distance(src, dest); src.Key = src.G + src.H; mStepStart = src; mStepBest = src; mStepStart.Clear(); mStepDest = dest; mStepCnt = 0; _AddToOpen(src); while (mOpenHeap.Size > 0) { mStepCurrent = mOpenHeap.Pop(); if (DestChecker.isDest(mStepCurrent)) { mStepBest = mStepCurrent; return(true); } if (mStepCnt > mStepCntMax) { return(false); } if (mStepCurrent.H < mStepBest.H) { mStepBest = mStepCurrent; } ++mStepCnt; _NewStep(mStepCurrent); mStepCurrent.AttachNode.Detach(); _AddToClose(mStepCurrent); } return(false); }
//--------------------------------------------------------------------- public bool search(int src_x, int src_y, int dst_x, int dst_y, uint max_step) { mRoute.Clear(); if ((src_x < mSizeX && src_y < mSizeY) == false || (dst_x < mSizeX && dst_y < mSizeY) == false) { return(false); } getRound(src_x, src_y, 0f, 100, ref src_x, ref src_y); if (src_x == dst_x && src_y == dst_y) { mRoute.Add(new EbVector2(src_x, src_y)); mRoute.Add(new EbVector2(dst_x, dst_y)); return(true); } if (!pick(src_x, src_y, dst_x, dst_y)) { mRoute.Add(new EbVector2(src_x, src_y)); mRoute.Add(new EbVector2(dst_x, dst_y)); return(true); } EbAstarStep src_step = mListStep[src_x + src_y * mSizeX]; EbAstarStep dst_step = mListStep[dst_x + dst_y * mSizeX]; mAstar0.DestChecker.Dest = dst_step; mAstar0.StepCntMax = max_step; bool reach_dest = mAstar0.Search(src_step, dst_step); mStepPool.Clear(); mAstar0.MakeRoute(mStepPool); mAstar0.Reset(); clipRoute(mStepPool, mRoute); return(reach_dest); }
//--------------------------------------------------------------------- public bool search(int src_x, int src_y, int dst_x, int dst_y, float diff, uint max_step) { if ((src_x < mSizeX && src_y < mSizeY) == false || (dst_x < mSizeX && dst_y < mSizeY) == false) { return(false); } getRound(src_x, src_y, 0f, 100, ref src_x, ref src_y); EbAstarStep src_step = mListStep[src_x + src_y * mSizeX]; EbAstarStep dst_step = mListStep[dst_x + dst_y * mSizeX]; mAstar1.DestChecker.Dest = dst_step; mAstar1.DestChecker.Diff = diff; mAstar1.StepCntMax = max_step; bool reach_dst = mAstar1.Search(src_step, dst_step); mRoute.Clear(); mStepPool.Clear(); mAstar1.MakeRoute(mStepPool); mAstar1.Reset(); clipRoute(mStepPool, mRoute); return(reach_dst); }
//--------------------------------------------------------------------- public virtual bool isDest(EbAstarStep step) { return(true); }
//--------------------------------------------------------------------- public void Clear() { G = 0; mParent = null; State = _eEbAstarStepState.NONE; }
//--------------------------------------------------------------------- void _AddToClose(EbAstarStep step) { step.State = _eEbAstarStepState.CLOSE; mCloseList.PushBack(step.AttachNode); }
//--------------------------------------------------------------------- void _AddToOpen(EbAstarStep step) { mOpenList.PushBack(step.AttachNode); step.State = _eEbAstarStepState.OPEN; mOpenHeap.Push(step); }
//------------------------------------------------------------------------- public override bool isDest(EbAstarStep step) { return(EbAstarStep.Distance(step, Dest) < Diff); }
//------------------------------------------------------------------------- public override bool isDest(EbAstarStep step) { return(Object.ReferenceEquals(step, Dest)); }