I've tried designing a Turing Machine model, it works quite well, however I think it could be confusing to maintain on in the future, and I'm not sure what of best practices. Can I get some feedback on my code?

Turing Machine Namespace
------------------------

```
using System;
using System.Collections.Generic;

namespace TuringMachineNS
{
    public class TuringMachine
    {
        byte[] tape;
        public bool hasTerminated;
        int currentIndex;
        int currentCard;
        List<ControlCard> cards;

        public TuringMachine() : this(500) { }

        public TuringMachine(int size) : this(size, null) { }

        public TuringMachine(int size, List<ControlCard> cards)
        {
            this.hasTerminated = false;
            this.tape = new byte[size];
            this.currentIndex = tape.Length / 2;
            this.cards = cards;
            this.currentCard = 1;
        }

        public void NextInstruction()
        {
            if (this.currentCard == 0)
            {
                hasTerminated = true;
                return;
            }
            if (this.currentIndex > this.tape.Length || this.currentIndex < 0)
            {
                hasTerminated = true;
                return;
            }
            int value = this.tape[this.currentIndex];
            Instruction Inst = this.cards[this.currentCard].GetInstruction(value);
            this.ExecuteInstruction(Inst);
        }

        private void ExecuteInstruction(Instruction inst)
        {
            if (inst.ActionInst == RWInstructions.WRITE0)
            {
                this.tape[currentIndex] = 0;
            }
            else if (inst.ActionInst == RWInstructions.WRITE1)
            {
                this.tape[currentIndex] = 1;
            }

            if (inst.MovementInst == LRInstructions.MOVELEFT)
            {
                this.currentIndex--;
            }
            else if(inst.MovementInst == LRInstructions.MOVERIGHT)
            {
                this.currentIndex++;
            }

            this.currentCard = inst.NextCardToUse;
        }

        public override string ToString()
        {
            string tapeString = "";
            foreach (var item in this.tape)
            {
                tapeString += item;
            }
            string secondLine = "";
            for (int i = 0; i < this.currentIndex; i++)
            {
                secondLine += " ";
            }
            secondLine += "^";
            return $"{tapeString}\n{secondLine}\n";
        }
    }

    public class ControlCard
    {
        Instruction IfZero;
        Instruction IfOne;

        public ControlCard(Instruction zero, Instruction one)
        {
            this.IfZero = zero;
            this.IfOne = one;
        }

        public Instruction GetInstruction(int value)
        {
            return value == 0 ? this.IfZero : this.IfOne;
        }
    }

    public struct Instruction
    {
        public RWInstructions ActionInst;
        public LRInstructions MovementInst;
        public int NextCardToUse;
    }

    public enum RWInstructions
    {
        WRITE1,
        WRITE0,
        UNCHANGED
    }

    public enum LRInstructions
    {
        MOVERIGHT,
        MOVELEFT,
        DONOTMOVE
    }
}

```

Example Usage
-------------

```
using System;
using System.Collections.Generic;
using TuringMachineNS;

class Program
    {
        static void Main(string[] args)
        {
            Instruction instr0 = default(Instruction);
            instr0.ActionInst = RWInstructions.WRITE1;
            instr0.MovementInst = LRInstructions.MOVELEFT;
            instr0.NextCardToUse = 1;
            Instruction inst1 = default(Instruction);
            ControlCard controlCard = new ControlCard(instr0, inst1);
            List<ControlCard> cardsList = new List<ControlCard>() { null, controlCard };
            TuringMachine tm = new TuringMachine(20, cardsList);
            Console.WriteLine(tm);
            while(!tm.hasTerminated)
            {
                tm.NextInstruction();
                Console.WriteLine(tm);
            }

        }
    }

```

Example Output
--------------

```
00000000000000000000
          ^

00000000001000000000
         ^

00000000011000000000
        ^

00000000111000000000
       ^

00000001111000000000
      ^

00000011111000000000
     ^

00000111111000000000
    ^

00001111111000000000
   ^

00011111111000000000
  ^

00111111111000000000
 ^

01111111111000000000
^

11111111111000000000
^

11111111111000000000
^

```