// Do one step: change state, write letter, move. public void DoOneStep() { if (Halted) { // If machine has halted, do nothing at all. return; } int previousLetter = Cursor.Value; int previousState = State; // Update machine state. State = definition.TransitionMatrix(previousState, 3 * previousLetter); // Write new letter. Cursor.Value = definition.TransitionMatrix(previousState, 3 * previousLetter + 1); // Move. int direction = definition.TransitionMatrix(previousState, 3 * previousLetter + 2); switch (direction) { case 0: // We don't move. break; case 1: { // We will move to the right, so future position is next node in linked list. LinkedListNode <int> futurePosition = Cursor.Next; // If we are on the left end of the tape, and we have written a blank // on current position, then "cut" this position from the tape. // (to save RAM) if ((Cursor.Previous == null) && (Cursor.Value == definition.Blank)) { Tape.RemoveFirst(); } // Now check if the current position is not the right end of the tape, // if it is, we must add a piece of tape to the right. if (futurePosition == null) { Tape.AddLast(definition.Blank); futurePosition = Tape.Last; } // Now move. Cursor = futurePosition; } break; case -1: { // We will move to the left, so future position is previous node in linked list. LinkedListNode <int> futurePosition = Cursor.Previous; // If we are on the right end of the tape, and we have written a blank // on current position, then "cut" this position from the tape. // (to save RAM) if ((Cursor.Next == null) && (Cursor.Value == definition.Blank)) { Tape.RemoveLast(); } // Now check if the current position is not the left end of the tape, // if it is, we must add a piece of tape to the left. if (futurePosition == null) { Tape.AddFirst(definition.Blank); futurePosition = Tape.First; } // Now move. Cursor = futurePosition; } break; default: throw new FiniteStateMachineException("Internal error, direction = " + direction); } }