コード例 #1
0
ファイル: Field.cs プロジェクト: skdhayal/avalonpipemania
        public SimplePipe this[int x, int y]
        {
            get
            {
                var v = ByIndex(x, y).FirstOrDefault(k => !k.Value.IsVirtualPipe);

                if (v == null)
                    return null;

                return v.Value;
            }
            set
            {
                // assigning null currently does not register spill detection

                var IsVirtualPipe = false;

                if (value != null)
                    IsVirtualPipe = value.IsVirtualPipe;

                #region Spill
                Action<int, int, SimplePipeOnTheField> Spill =
                    (ox, oy, SpillTarget) =>
                    {
                        if (SpillTarget.Value.Output[ox, oy] == null)
                            if (SpillTarget.Value.SupportedOutput[ox, oy] != null)
                            {
                                // once the water gets here we need to spill it on the floor
                                // it can happen when the pipe is not there or even when the pipe does not accept input

                                // when the correct pipe is built this event is effectevly detatched
                                SpillTarget.Value.Output[ox, oy] =
                                    delegate
                                    {
                                        // SpillTarget has filled itself with water
                                        // and needs to continue on the next pipe
                                        // but as we are inside here there is no matching pipe there

                                        var s = new SimplePipe.Missing();

                                        this[SpillTarget.X + ox, SpillTarget.Y + oy] = s;

                                        RefreshPipes();

                                        s.Output.Spill =
                                            delegate
                                            {
                                                // game over!!!
                                            };

                                        // we need to trigger the event
                                        s.Input[-ox, -oy]();

                                        // and when the water hits the floor
                                        // we should trigger end game
                                    };
                            }
                    };
                #endregion

                var DemolitionCost = 0;

                if (!IsVirtualPipe)
                {
                    #region remove old pipe
                    PipesList.Where(k => k.Y == y).Where(k => k.X == x).ToArray().ForEach(
                        target =>
                        {
                            DemolitionCost += target.Value.DemolitionCost;

                            Console.WriteLine("remove: " + new { target.Value.GetType().Name, target.X, target.Y });

                            target.Value.Dispose();

                            PipesList.Remove(target);

                            new FindSiblings
                            {
                                FoundLeft = Left =>
                                {
                                    Left.Value.Output.Right = null;

                                    if (value != null)
                                        value.Output.Left = null;

                                    Spill(1, 0, Left);
                                },
                                FoundRight = Right =>
                                {
                                    Right.Value.Output.Left = null;
                                    if (value != null)
                                        value.Output.Right = null;

                                    Spill(-1, 0, Right);
                                },
                                FoundTop = Top =>
                                {
                                    Top.Value.Output.Bottom = null;
                                    if (value != null)
                                        value.Output.Top = null;

                                    Spill(0, 1, Top);
                                },
                                FoundBottom = Bottom =>
                                {
                                    Bottom.Value.Output.Top = null;
                                    if (value != null)
                                        value.Output.Bottom = null;

                                    Spill(0, -1, Bottom);
                                }
                            }.Apply(PipesList, target);
                        }
                    );
                    #endregion
                }

                if (value != null)
                {
                    value.PipeParts.ForEach(k => k.Color = this.DefaultPipeColor);

                    var target =
                        new SimplePipeOnTheField
                        {
                            Value = value,
                            X = x,
                            Y = y
                        };

                    PipesList.Add(
                        target
                    );

                    Console.WriteLine("add: " + new { target.Value.GetType().Name, target.X, target.Y });

                    var px = x * Tile.Size + Tile.ShadowBorder;
                    var py = (1 + y) * Tile.SurfaceHeight + Tile.ShadowBorder - Tile.Size;

                    value.Container.AttachTo(this.Pipes).MoveTo(px, py);
                    value.InfoOverlay.AttachTo(this.InfoOverlay).MoveTo(px, py);

                    if (!IsVirtualPipe)
                    {

                        new FindSiblings
                        {
                            FoundLeft = Left =>
                            {
                                Left.Value.Output.Right = value.Input.Left;
                                value.Output.Left = Left.Value.Input.Right;

                                Spill(1, 0, Left);
                            },
                            FoundRight = Right =>
                            {
                                Right.Value.Output.Left = value.Input.Right;
                                value.Output.Right = Right.Value.Input.Left;

                                Spill(-1, 0, Right);
                            },
                            FoundTop = Top =>
                            {
                                Top.Value.Output.Bottom = value.Input.Top;
                                value.Output.Top = Top.Value.Input.Bottom;

                                Spill(0, 1, Top);
                            },
                            FoundBottom = Bottom =>
                            {
                                Bottom.Value.Output.Top = value.Input.Bottom;
                                value.Output.Bottom = Bottom.Value.Input.Top;

                                Spill(0, -1, Bottom);
                            }
                        }.Apply(PipesList, target);

                        Spill(1, 0, target);
                        Spill(-1, 0, target);
                        Spill(0, 1, target);
                        Spill(0, -1, target);

                        value.ShowBonusPoints(DemolitionCost);
                    }
                }

            }
        }
コード例 #2
0
ファイル: Field.cs プロジェクト: skdhayal/avalonpipemania
            public void Apply(IEnumerable<SimplePipeOnTheField> source, SimplePipeOnTheField target)
            {
                source.Where(k => k.Y == target.Y).FirstOrDefault(k => k.X == target.X - 1).DoIfAny(
                    FoundLeft
                );

                source.Where(k => k.Y == target.Y).FirstOrDefault(k => k.X == target.X + 1).DoIfAny(
                    FoundRight
                );

                source.Where(k => k.X == target.X).FirstOrDefault(k => k.Y == target.Y - 1).DoIfAny(
                    FoundTop
                );

                source.Where(k => k.X == target.X).FirstOrDefault(k => k.Y == target.Y + 1).DoIfAny(
                    FoundBottom
                );
            }