コード例 #1
0
	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;
	}
コード例 #2
0
    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);
    }