bgneal@4: // Copyright (C) 2012 by Brian Neal. bgneal@4: // This file is part of Cpp-Enigma, the Enigma Machine simulation. bgneal@4: // Cpp-Enigma is released under the MIT License (see License.txt). bgneal@4: // bgneal@4: // machine.cpp - The implementation file for the main Enigma machine class. bgneal@4: bgneal@4: #include bgneal@4: #include "machine.h" bgneal@4: #include "rotor.h" bgneal@4: #include "rotor_factory.h" bgneal@4: bgneal@4: using namespace enigma; bgneal@4: bgneal@4: //////////////////////////////////////////////////////////////////////////////// bgneal@4: bgneal@4: enigma_machine::enigma_machine( bgneal@4: rotor_vector rv, bgneal@4: std::unique_ptr reflector, bgneal@4: const plugboard& pb) bgneal@4: : rotors(std::move(rv)), bgneal@4: reflector(std::move(reflector)), bgneal@4: pb(pb), bgneal@4: r_rotor(0), bgneal@4: m_rotor(0), bgneal@4: l_rotor(0) bgneal@4: { bgneal@4: rotor_count_check(); bgneal@4: } bgneal@4: bgneal@4: //////////////////////////////////////////////////////////////////////////////// bgneal@4: bgneal@4: enigma_machine::enigma_machine( bgneal@4: rotor_vector rv, bgneal@4: std::unique_ptr reflector) bgneal@4: : rotors(std::move(rv)), bgneal@4: reflector(std::move(reflector)), bgneal@4: pb(), bgneal@4: r_rotor(0), bgneal@4: m_rotor(0), bgneal@4: l_rotor(0) bgneal@4: { bgneal@4: rotor_count_check(); bgneal@4: } bgneal@4: bgneal@4: //////////////////////////////////////////////////////////////////////////////// bgneal@4: bgneal@4: enigma_machine::enigma_machine( bgneal@4: const std::vector& rotor_types, bgneal@4: const std::vector& ring_settings, bgneal@4: const std::string& reflector_name, bgneal@4: const std::string& plugboard_settings) bgneal@4: : rotors(), bgneal@4: reflector(create_reflector(reflector_name.c_str())), bgneal@4: pb(plugboard_settings), bgneal@4: r_rotor(0), bgneal@4: m_rotor(0), bgneal@4: l_rotor(0) bgneal@4: { bgneal@4: for (const auto& name : rotor_types) bgneal@4: { bgneal@4: rotors.push_back(create_rotor(name.c_str())); bgneal@4: } bgneal@4: rotor_count_check(); bgneal@4: bgneal@4: // if ring settings are supplied, there has to be one for each rotor bgneal@4: if (!ring_settings.empty()) bgneal@4: { bgneal@4: if (rotors.size() != ring_settings.size()) bgneal@4: { bgneal@4: throw enigma_machine_error("rotor/ring setting count mismatch"); bgneal@4: } bgneal@4: bgneal@4: for (std::size_t i = 0; i < rotors.size(); ++i) bgneal@4: { bgneal@4: rotors[i]->set_ring_setting(ring_settings[i]); bgneal@4: } bgneal@4: } bgneal@4: } bgneal@4: bgneal@4: //////////////////////////////////////////////////////////////////////////////// bgneal@4: bgneal@4: void enigma_machine::rotor_count_check() bgneal@4: { bgneal@4: if (rotors.size() != 3 && rotors.size() != 4) bgneal@4: { bgneal@4: throw enigma_machine_error("rotor count"); bgneal@4: } bgneal@4: bgneal@4: if (rotors.size() == 3) bgneal@4: { bgneal@4: r_rotor = rotors[2].get(); bgneal@4: m_rotor = rotors[1].get(); bgneal@4: l_rotor = rotors[0].get(); bgneal@4: } bgneal@4: else bgneal@4: { bgneal@4: r_rotor = rotors[3].get(); bgneal@4: m_rotor = rotors[2].get(); bgneal@4: l_rotor = rotors[1].get(); bgneal@4: } bgneal@4: }