Mercurial > public > cpp-enigma
view enigma/machine.cpp @ 13:b9d124a15926
To improve cache performance, the enigma machine rotors are now stored
together with the reflector in a vector.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Mon, 02 Jul 2012 19:14:36 -0500 |
parents | da231533c5c7 |
children | 919b7a0d1802 |
line wrap: on
line source
// 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 <sstream> #include "machine.h" #include "rotor.h" #include "rotor_factory.h" using namespace enigma; //////////////////////////////////////////////////////////////////////////////// enigma_machine::enigma_machine( const rotor_vector& rv, std::shared_ptr<rotor> reflector, const plugboard& pb) : rotors(), pb(pb) { rotors.push_back(*reflector); for (const auto& r : rv) { rotors.push_back(*r); } rotor_count_check(); } //////////////////////////////////////////////////////////////////////////////// enigma_machine::enigma_machine( const rotor_vector& rv, std::shared_ptr<rotor> reflector) : rotors(), pb() { rotors.push_back(*reflector); for (const auto& r : rv) { rotors.push_back(*r); } 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(), pb(plugboard_settings) { const auto ukw(create_reflector(reflector_name.c_str())); rotors.push_back(*ukw); for (const auto& name : rotor_types) { const auto r(create_rotor(name.c_str())); rotors.push_back(*r); } rotor_count_check(); // if ring settings are supplied, there has to be one for each rotor if (!ring_settings.empty()) { if (rotors.size() - 1 != ring_settings.size()) { throw enigma_machine_error("rotor/ring setting count mismatch"); } for (std::size_t i = 1; i < rotors.size(); ++i) { rotors[i].set_ring_setting(ring_settings[i - 1]); } } } //////////////////////////////////////////////////////////////////////////////// void enigma_machine::rotor_count_check() { // the first rotor is actually the reflector; so we should have a total // of 4 or 5 rotors if (rotors.size() != 4 && rotors.size() != 5) { throw enigma_machine_error("rotor count"); } if (rotors.size() == 4) { r_rotor = &rotors[3]; m_rotor = &rotors[2]; l_rotor = &rotors[1]; } else { r_rotor = &rotors[4]; m_rotor = &rotors[3]; l_rotor = &rotors[2]; } } //////////////////////////////////////////////////////////////////////////////// std::string enigma_machine::str(bool army) const { std::ostringstream os; os << rotors[0].name() << ' '; for (std::size_t i = 1; i < rotors.size(); ++i) { os << rotors[i].name() << '/' << rotors[i].get_ring_setting() << ' '; } os << get_display() << ' ' << (army ? pb.army_str() : pb.navy_str()); return os.str(); }