public void Step() { _recoveryFlag = false; _haltFlag = false; if (InstructionPointer < 0 || InstructionPointer >= _program.Count) { _haltFlag = true; return; } var instruction = _program[(int)InstructionPointer]; var disasseblyA = ""; long valueA = 0; if (instruction.ValueA.HasValue) { valueA = instruction.ValueA.Value; disasseblyA = valueA.ToString(); } if (instruction.RegisterA.HasValue) { valueA = GetRegister(instruction.RegisterA.Value); disasseblyA = instruction.RegisterA.Value.ToString(); } var disasseblyB = ""; long valueB = 0; if (instruction.ValueB.HasValue) { valueB = instruction.ValueB.Value; disasseblyB = valueB.ToString(); } if (instruction.RegisterB.HasValue) { valueB = GetRegister(instruction.RegisterB.Value); disasseblyB = instruction.RegisterB.Value.ToString(); } if (Disassembly) { Console.WriteLine(InstructionPointer + ": " + _opcodesLookup.Single(i => i.Value == instruction.Opcode).Key + " " + disasseblyA + " " + disasseblyB); } switch (instruction.Opcode) { case Opcode.Snd: SendCount++; _recoveryFrequency = valueA; Send.Add(_recoveryFrequency); //Console.WriteLine($"sound: {_recoveryFrequency}"); break; case Opcode.Set: SetRegister(instruction.RegisterA.Value, valueB); break; case Opcode.Add: var add = valueA; add += valueB; SetRegister(instruction.RegisterA.Value, add); break; case Opcode.Sub: var sub = valueA; sub -= valueB; SetRegister(instruction.RegisterA.Value, sub); break; case Opcode.Mul: MulCount++; var mul = valueA; mul *= valueB; SetRegister(instruction.RegisterA.Value, mul); break; case Opcode.Mod: var mod = valueA; mod %= valueB; SetRegister(instruction.RegisterA.Value, mod); break; case Opcode.Rcv: if (valueA != 0) { if (_recoveryFrequency > 0) { _recoveryFlag = true;//part 1 } } if (Received.Any()) { _recoveryFlag = false; var received = Received.First(); Received.RemoveAt(0); SetRegister(instruction.RegisterA.Value, received); } else//If { //Return, skipping increment of instruction ptr _recoveryFlag = true; return; } break; case Opcode.Jgz: if (valueA > 0) { InstructionPointer += valueB; } else { InstructionPointer++; } break; case Opcode.Jnz: if (valueA != 0) { InstructionPointer += valueB; } else { InstructionPointer++; } break; default: throw new Exception(); } if (instruction.Opcode != Opcode.Jgz && instruction.Opcode != Opcode.Jnz) { InstructionPointer++; } StepCount++; }