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); }
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); }