public TrackEnds[] getTrackEnds() { TrackEnds[] result = new TrackEnds[4]; for (TrackSide side = TrackSide.North; side <= TrackSide.West; side++) { result[(int)side] = getEndOnSide(side); } #if DEBUG //sanity check! int aCount = 0; int bCount = 0; foreach (var item in result) { if (item == TrackEnds.A) { aCount++; } else if (item == TrackEnds.B) { bCount++; } } if (aCount != bCount) { throw new InvalidOperationException(aCount + "!=" + bCount); } #endif return(result); }
/// <summary> /// (For multi-piece support) /// Returns the piece that connects to the given side or null if there is none /// </summary> /// <returns>The piece on side.</returns> /// <param name="side">Side.</param> public virtual AbstractTrackBlock getPieceOnSide(TrackSide side) { TrackEnds trackEnd = getEndOnSide(side); if (trackEnd == TrackEnds.None) { return(null); } return(this); }
public override AbstractTrackBlock getPieceOnSide(TrackSide side) { TrackEnds end = a.getEndOnSide(side); if (end == TrackEnds.None) { return(b); } return(a); }
/// <summary> /// Get the train block adjacent to this one, optionally only if it /// connects to this one. Returns null if one was not found or if /// <code>connectingOnly</code> and the found one is not connected. /// </summary> /// <returns>The adjacent block.</returns> /// <param name="source">Source.</param> /// <param name="direction">Direction.</param> private AbstractTrackBlock getAdjacentBlock(AbstractTrackBlock source, TrackSide direction, bool connectingOnly) { TrackEnds side = source.getEndOnSide(direction); if (connectingOnly && side == TrackEnds.None) { return(null); } AbstractTrackBlock result; switch (direction) { case TrackSide.North: if (source.y == 0) { return(null); } result = this[source.x, source.y - 1]; break; case TrackSide.East: if (source.x == 0) { return(null); } result = this[source.x - 1, source.y]; break; case TrackSide.South: if (source.y == EngineOptions.gridHeight - 1) { return(null); } result = this[source.x, source.y + 1]; break; case TrackSide.West: if (source.x == EngineOptions.gridWidth - 1) { return(null); } result = this[source.x + 1, source.y]; break; default: throw new ArgumentOutOfRangeException(); } if (!connectingOnly) { return(result); } TrackSide otherSide = invertSide(direction); TrackEnds otherEnd = result.getEndOnSide(otherSide); if (otherEnd == TrackEnds.None) { return(null); } return(result); }
private void moveTrain() { int speed = speeds[curSpeedIndex]; AbstractTrainCar crashCar = null; foreach (var item in trainList) { int sections = item.progress; sections += speed; AbstractTrackBlock curBlock = this[item.x, item.y]; TrackSide entry = item.entry; while (sections > EngineOptions.blockSections) { sections -= EngineOptions.blockSections; TrackSide entrySide = entry; //discover the output edge AbstractTrackBlock subBlock = curBlock.getPieceOnSide( entrySide); TrackEnds endOnSide = subBlock.getEndOnSide(entrySide); //find the side the other end is on TrackEnds otherEnd = endOnSide == TrackEnds.A ? TrackEnds.B : TrackEnds.A; TrackSide exit = (TrackSide)(-1); TrackEnds[] ends = subBlock.getTrackEnds(); for (int i = 0; i < (int)TrackSide.West + 1; i++) { if (ends[i] == otherEnd) { exit = (TrackSide)i; break; } } AbstractTrackBlock nextBlock = getAdjacentBlock( curBlock, exit, true); if (nextBlock == null) { //crash crashCar = item; //so other blocks will travel the right distance... speed -= sections; sections = EngineOptions.blockSections; } else { curBlock = nextBlock; entry = invertSide(exit); } } item.progress = sections; item.x = curBlock.x; item.y = curBlock.y; item.entry = entry; debugLog("Car " + item.trainIndex + " is now at " + item.x + "," + item.y + " and " + item.progress + "sections entering " + "from side " + item.entry + "."); } if (crashCar != null) { gameOverHappened = true; throw new GameOverException(crashCar); } }