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
^