示例#1
0
        public int Compatible(Hole other)
        {
            int alignLow()
            {
                return(this.LowBound - other.LowBound);
            }

            int alignHigh()
            {
                return(this.HighBound - other.HighBound);
            }

            if (other.Side == ScreenDirection.Up && this.Side != ScreenDirection.Up && this.Side != ScreenDirection.Left)
            {
                return(-other.Compatible(this));
            }
            if (other.Side == ScreenDirection.Left && this.Side != ScreenDirection.Left && this.Side != ScreenDirection.Up)
            {
                return(-other.Compatible(this));
            }

            if (this.Side == ScreenDirection.Up && other.Side == ScreenDirection.Down)
            {
                var oneWayUp    = this.Kind == HoleKind.Out || other.Kind == HoleKind.In || other.Kind == HoleKind.Unknown;
                var oneWayDown  = this.Kind == HoleKind.In || this.Kind == HoleKind.Unknown || other.Kind == HoleKind.Out;
                var topIsLarger = this.Size <= other.Size;
                // Vertical transitions
                if (this.Launch != null)
                {
                    if (other.Launch != null)
                    {
                        if (other.Launch == -1)
                        {
                            return(INCOMPATIBLE);
                        }
                        return(this.Launch.Value - other.Launch.Value);
                    }
                    else if (other.Closed)
                    {
                        return(this.Launch.Value - (other.LowBound + other.HighBound) / 2);
                    }
                    else if (other.HighOpen)
                    {
                        return(this.Launch.Value - (other.LowBound + 2));
                    }
                    else if (other.LowOpen)
                    {
                        return(this.Launch.Value - (other.HighBound - 2));
                    }
                }
                else if (this.BothOpen || other.BothOpen)
                {
                    // if either is open on both ends, they must line up perfectly
                    if (this.BothOpen && other.BothOpen && this.Size == other.Size)
                    {
                        return(0);
                    }
                }
                else if (this.HalfOpen || other.HalfOpen)
                {
                    // if either is half-open, they must be the same half open
                    // alternatively, as long as they're not open on different sides (i.e. one is closed)
                    // then it's okay if it's one way and the target hole is larger
                    if (this.LowOpen == other.LowOpen)
                    {
                        return(this.LowOpen ? alignHigh() : alignLow());
                    }
                    else if (this.LowOpen != other.HighOpen)
                    {
                        if ((oneWayUp && topIsLarger) || (oneWayDown && !topIsLarger))
                        {
                            return((this.LowOpen || other.LowOpen) ? alignHigh() : alignLow());
                        }
                    }
                }
                else
                {
                    // Only remaining option is both closed. they must be the same size
                    // alternately, same trick with oneways
                    if (this.Size == other.Size)
                    {
                        return(alignLow());
                    }
                    else if ((oneWayUp && topIsLarger) || (oneWayDown && !topIsLarger))
                    {
                        // pick alignment at random
                        return((this.Size + other.Size) % 2 == 0 ? alignLow() : alignHigh());
                    }
                }
            }
            if (this.Side == ScreenDirection.Left && other.Side == ScreenDirection.Right)
            {
                // Horizontal transitions
                if (this.HighOpen || other.HighOpen)
                {
                    // if either is open on the bottom, they both must be open on the bottom and we align the death planes
                    // this is kind of a questionable choice all around tbh
                    // maybe additionally restrict that sizes must be the same?
                    if (this.HighOpen && other.HighOpen)
                    {
                        return(alignHigh());
                    }
                }
                else if (this.LowOpen || other.LowOpen)
                {
                    // if either is open on the top, the other must also be open on the top OR it must be sufficiently tall
                    if (this.LowOpen && other.LowOpen)
                    {
                        return(alignHigh());
                    }
                    else if (this.Closed && this.Size > 2)
                    {
                        return(alignHigh());
                    }
                    else if (other.Closed && other.Size > 2)
                    {
                        return(alignHigh());
                    }
                }
                else
                {
                    // only remaining option is both closed. they must be the same size OR sufficiently tall
                    if (this.Size == other.Size)
                    {
                        return(alignHigh());
                    }
                    else if (this.Size > 2 && other.Size > 2)
                    {
                        return(alignHigh());
                    }
                }
            }
            return(INCOMPATIBLE);
        }
示例#2
0
        public int Compatible(Hole other)
        {
            int alignLow()
            {
                return(this.LowBound - other.LowBound);
            }

            int alignHigh()
            {
                return(this.HighBound - other.HighBound);
            }

            if (other.Side == ScreenDirection.Up && this.Side != ScreenDirection.Up && this.Side != ScreenDirection.Left)
            {
                return(-other.Compatible(this));
            }
            if (other.Side == ScreenDirection.Left && this.Side != ScreenDirection.Left && this.Side != ScreenDirection.Up)
            {
                return(-other.Compatible(this));
            }

            if (this.Side == ScreenDirection.Up && other.Side == ScreenDirection.Down)
            {
                // Vertical transitions
                if (this.Launch != null)
                {
                    if (other.Launch != null)
                    {
                        return(this.Launch.Value - other.Launch.Value);
                    }
                    else if (other.Closed)
                    {
                        return(this.Launch.Value - (other.LowBound + other.HighBound) / 2);
                    }
                    else if (other.HighOpen)
                    {
                        return(this.Launch.Value - (other.LowBound + 2));
                    }
                    else if (other.LowOpen)
                    {
                        return(this.Launch.Value - (other.HighBound - 2));
                    }
                }
                else if (this.BothOpen || other.BothOpen)
                {
                    // if either is open on both ends, they must line up perfectly
                    if (this.BothOpen && other.BothOpen && this.Size == other.Size)
                    {
                        return(0);
                    }
                }
                else if (this.HalfOpen || other.HalfOpen)
                {
                    // if either is half-open, they must be the same half open
                    if (this.LowOpen == other.LowOpen)
                    {
                        return(this.LowOpen ? alignHigh() : alignLow());
                    }
                }
                else
                {
                    // Only remaining option is both closed. they must be the same size
                    if (this.Size == other.Size)
                    {
                        return(alignLow());
                    }
                }
            }
            if (this.Side == ScreenDirection.Left && other.Side == ScreenDirection.Right)
            {
                // Horizontal transitions
                if (this.HighOpen || other.HighOpen)
                {
                    // if either is open on the bottom, they both must be open on the bottom and we align the death planes
                    // this is kind of a questionable choice all around tbh
                    // maybe additionally restrict that sizes must be the same?
                    if (this.HighOpen && other.HighOpen)
                    {
                        return(alignHigh());
                    }
                }
                else if (this.LowOpen || other.LowOpen)
                {
                    // if either is open on the top, the other must also be open on the top OR it must be sufficiently tall
                    if (this.LowOpen && other.LowOpen)
                    {
                        return(alignHigh());
                    }
                    else if (this.Closed && this.Size > 3)
                    {
                        return(alignHigh());
                    }
                    else if (other.Closed && other.Size > 3)
                    {
                        return(alignHigh());
                    }
                }
                else
                {
                    // only remaining option is both closed. they must be the same size OR sufficiently tall
                    if (this.Size == other.Size)
                    {
                        return(alignHigh());
                    }
                    else if (this.Size > 3 && other.Size > 3)
                    {
                        return(alignHigh());
                    }
                }
            }
            return(INCOMPATIBLE);
        }