private FillInfo[,] GenerateRefillTrendMap(Container2D_Rectangular container) { var ret = new FillInfo[container.Height, container.Width]; var slots = container.WrapperRect; Action<int, int, List<SlotWrapper2D>> picker = (x, y, list)=>{ if (x < 0 || x >= container.Width) return; if (y < 0 || y >= container.Height) return; if (null != slots[y, x].slotAttribute && slots[y, x].slotAttribute.category == SlotAttribute.Category.INSULATOR) { return; } list.Add(slots[y, x]); }; Action<int, int> exitMarker = (x, y)=>{ if (null == ret[y, x]) { ret[y, x] = new FillInfo(); ret[y, x].ancestorPos = new Pos2D(x, y + 1); } }; container.ForeachSlot((x, y, slot)=>{ if (null != ret[y, x]) return; if (null != slot.slotAttribute && slot.slotAttribute.category == SlotAttribute.Category.INSULATOR) return; var ctx = new AStar.Context<SlotWrapper2D>(); ctx.start = slots[y, x]; ctx.procTrait = (s)=>{ return s.Trait; }; ctx.procWeight = (SlotWrapper2D from, SlotWrapper2D to)=>{ foreach (var t in surroundingOffsets){ if (to.pos.x == from.pos.x + t.item1 && to.pos.y == from.pos.y + t.item2){ return t.item3; } } throw new NotImplementedException(); }; ctx.procTermination = (SlotWrapper2D s)=>{ return s.pos.y == container.Height - 1; }; ctx.procDistanceEstimator = (SlotWrapper2D s)=>{ return (container.Height - 1 - s.pos.y) * 1.0001f; }; ctx.procAdjacencies = (SlotWrapper2D s)=>{ var list = new List<SlotWrapper2D>(); foreach (var t in surroundingOffsets){ picker.Invoke(s.pos.x + t.item1, s.pos.y + t.item2, list); } return list; }; if (AStar.Evaluate(ctx)) { var result = ctx.path; if (result.Count <= 0) { exitMarker.Invoke(x, y); } else { result.Reverse(); for (int i = 0, len = result.Count - 1; i < len; i++) { if (null != ret[result[i].pos.y, result[i].pos.x]) continue; var t = new FillInfo(); t.ancestorPos = new Pos2D(result[i + 1].pos.x, result[i + 1].pos.y); ret[result[i].pos.y, result[i].pos.x] = t; } exitMarker(result[result.Count - 1].pos.x, result[result.Count - 1].pos.y); } } else { ret[y, x] = new FillInfo(); } }); for (int y = 0; y < container.Height; y++) { for (int x = 0; x < container.Width; x++) { var fi = ret[y, x]; if (null == fi) continue; if (fi.IsOnSpot) continue; fi.childrenPos = new List<Pos2D>(); foreach (var t in surroundingOffsets) { var sx = x + t.item1; var sy = y + t.item2; if (!container.IsLegalPosition(sx, sy)) { continue; } var slot = container.GetSlot(sx, sy); if (null != slot && null != slot.slotAttribute && slot.slotAttribute.category == SlotAttribute.Category.INSULATOR) { continue; } var touch = ret[sy, sx]; if (null != touch.ancestorPos && touch.ancestorPos.x == x && touch.ancestorPos.y == y) { fi.childrenPos.Add(new Pos2D(sx, sy)); } } } } return ret; }
private FillInfo[,] GenerateRefillTrendMap(Container2D_Rectangular container) { var ret = new FillInfo[container.Height, container.Width]; var slots = container.WrapperRect; Action <int, int, List <SlotWrapper2D> > picker = (x, y, list) => { if (x < 0 || x >= container.Width) { return; } if (y < 0 || y >= container.Height) { return; } if (null != slots[y, x].slotAttribute && slots[y, x].slotAttribute.category == SlotAttribute.Category.INSULATOR) { return; } list.Add(slots[y, x]); }; Action <int, int> exitMarker = (x, y) => { if (null == ret[y, x]) { ret[y, x] = new FillInfo(); ret[y, x].ancestorPos = new Pos2D(x, y + 1); } }; container.ForeachSlot((x, y, slot) => { if (null != ret[y, x]) { return; } if (null != slot.slotAttribute && slot.slotAttribute.category == SlotAttribute.Category.INSULATOR) { return; } var ctx = new AStar.Context <SlotWrapper2D>(); ctx.start = slots[y, x]; ctx.procTrait = (s) => { return(s.Trait); }; ctx.procWeight = (SlotWrapper2D from, SlotWrapper2D to) => { foreach (var t in surroundingOffsets) { if (to.pos.x == from.pos.x + t.item1 && to.pos.y == from.pos.y + t.item2) { return(t.item3); } } throw new NotImplementedException(); }; ctx.procTermination = (SlotWrapper2D s) => { return(s.pos.y == container.Height - 1); }; ctx.procDistanceEstimator = (SlotWrapper2D s) => { return((container.Height - 1 - s.pos.y) * 1.0001f); }; ctx.procAdjacencies = (SlotWrapper2D s) => { var list = new List <SlotWrapper2D>(); foreach (var t in surroundingOffsets) { picker.Invoke(s.pos.x + t.item1, s.pos.y + t.item2, list); } return(list); }; if (AStar.Evaluate(ctx)) { var result = ctx.path; if (result.Count <= 0) { exitMarker.Invoke(x, y); } else { result.Reverse(); for (int i = 0, len = result.Count - 1; i < len; i++) { if (null != ret[result[i].pos.y, result[i].pos.x]) { continue; } var t = new FillInfo(); t.ancestorPos = new Pos2D(result[i + 1].pos.x, result[i + 1].pos.y); ret[result[i].pos.y, result[i].pos.x] = t; } exitMarker(result[result.Count - 1].pos.x, result[result.Count - 1].pos.y); } } else { ret[y, x] = new FillInfo(); } }); for (int y = 0; y < container.Height; y++) { for (int x = 0; x < container.Width; x++) { var fi = ret[y, x]; if (null == fi) { continue; } if (fi.IsOnSpot) { continue; } fi.childrenPos = new List <Pos2D>(); foreach (var t in surroundingOffsets) { var sx = x + t.item1; var sy = y + t.item2; if (!container.IsLegalPosition(sx, sy)) { continue; } var slot = container.GetSlot(sx, sy); if (null != slot && null != slot.slotAttribute && slot.slotAttribute.category == SlotAttribute.Category.INSULATOR) { continue; } var touch = ret[sy, sx]; if (null != touch.ancestorPos && touch.ancestorPos.x == x && touch.ancestorPos.y == y) { fi.childrenPos.Add(new Pos2D(sx, sy)); } } } } return(ret); }