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@8: #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@11: const rotor_vector& rv, bgneal@11: std::shared_ptr reflector, bgneal@4: const plugboard& pb) bgneal@11: : rotors(rv), bgneal@11: reflector(reflector), bgneal@11: pb(pb) bgneal@4: { bgneal@4: rotor_count_check(); bgneal@4: } bgneal@4: bgneal@4: //////////////////////////////////////////////////////////////////////////////// bgneal@4: bgneal@4: enigma_machine::enigma_machine( bgneal@11: const rotor_vector& rv, bgneal@11: std::shared_ptr reflector) bgneal@11: : rotors(rv), bgneal@11: reflector(reflector), bgneal@11: pb() 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@11: pb(plugboard_settings) 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: } bgneal@8: bgneal@8: //////////////////////////////////////////////////////////////////////////////// bgneal@8: bgneal@8: std::string enigma_machine::str(bool army) const bgneal@8: { bgneal@8: std::ostringstream os; bgneal@8: bgneal@8: os << reflector->name() << ' '; bgneal@8: bgneal@8: for (const auto& r : rotors) bgneal@8: { bgneal@8: os << r->name() << '/' << r->get_ring_setting() << ' '; bgneal@8: } bgneal@8: bgneal@8: os << get_display() << ' ' << (army ? pb.army_str() : pb.navy_str()); bgneal@8: bgneal@8: return os.str(); bgneal@8: } bgneal@8: