diff enigma/machine.cpp @ 4:2792ca4ffa84

Created enigma_machine class and tests.
author Brian Neal <bgneal@gmail.com>
date Sun, 24 Jun 2012 18:39:05 -0500
parents
children b90a41f0cd94
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enigma/machine.cpp	Sun Jun 24 18:39:05 2012 -0500
@@ -0,0 +1,101 @@
+// Copyright (C) 2012 by Brian Neal.
+// This file is part of Cpp-Enigma, the Enigma Machine simulation.
+// Cpp-Enigma is released under the MIT License (see License.txt).
+//
+// machine.cpp - The implementation file for the main Enigma machine class.
+
+#include <cstddef>
+#include "machine.h"
+#include "rotor.h"
+#include "rotor_factory.h"
+
+using namespace enigma;
+
+////////////////////////////////////////////////////////////////////////////////
+
+enigma_machine::enigma_machine(
+      rotor_vector rv,
+      std::unique_ptr<rotor> reflector,
+      const plugboard& pb)
+ : rotors(std::move(rv)),
+   reflector(std::move(reflector)),
+   pb(pb),
+   r_rotor(0),
+   m_rotor(0),
+   l_rotor(0)
+{
+   rotor_count_check();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+enigma_machine::enigma_machine(
+      rotor_vector rv,
+      std::unique_ptr<rotor> reflector)
+ : rotors(std::move(rv)),
+   reflector(std::move(reflector)),
+   pb(),
+   r_rotor(0),
+   m_rotor(0),
+   l_rotor(0)
+{
+   rotor_count_check();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+enigma_machine::enigma_machine(
+      const std::vector<std::string>& rotor_types,
+      const std::vector<int>& ring_settings,
+      const std::string& reflector_name,
+      const std::string& plugboard_settings)
+ : rotors(),
+   reflector(create_reflector(reflector_name.c_str())),
+   pb(plugboard_settings),
+   r_rotor(0),
+   m_rotor(0),
+   l_rotor(0)
+{
+   for (const auto& name : rotor_types)
+   {
+      rotors.push_back(create_rotor(name.c_str()));
+   }
+   rotor_count_check();
+
+   // if ring settings are supplied, there has to be one for each rotor
+   if (!ring_settings.empty())
+   {
+      if (rotors.size() != ring_settings.size())
+      {
+         throw enigma_machine_error("rotor/ring setting count mismatch");
+      }
+
+      for (std::size_t i = 0; i < rotors.size(); ++i)
+      {
+         rotors[i]->set_ring_setting(ring_settings[i]);
+      }
+   }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void enigma_machine::rotor_count_check()
+{
+   if (rotors.size() != 3 && rotors.size() != 4)
+   {
+      throw enigma_machine_error("rotor count");
+   }
+
+   if (rotors.size() == 3)
+   {
+      r_rotor = rotors[2].get();
+      m_rotor = rotors[1].get();
+      l_rotor = rotors[0].get();
+   }
+   else
+   {
+      r_rotor = rotors[3].get();
+      m_rotor = rotors[2].get();
+      l_rotor = rotors[1].get();
+   }
+}