예제 #1
0
        // 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);
            }
        }