annotate enigma/machine.cpp @ 10:232dbe7a3fe0

Added plugboard::unplug_all().
author Brian Neal <bgneal@gmail.com>
date Fri, 29 Jun 2012 21:26:24 -0500
parents b90a41f0cd94
children da231533c5c7
rev   line source
bgneal@4 1 // Copyright (C) 2012 by Brian Neal.
bgneal@4 2 // This file is part of Cpp-Enigma, the Enigma Machine simulation.
bgneal@4 3 // Cpp-Enigma is released under the MIT License (see License.txt).
bgneal@4 4 //
bgneal@4 5 // machine.cpp - The implementation file for the main Enigma machine class.
bgneal@4 6
bgneal@4 7 #include <cstddef>
bgneal@8 8 #include <sstream>
bgneal@4 9 #include "machine.h"
bgneal@4 10 #include "rotor.h"
bgneal@4 11 #include "rotor_factory.h"
bgneal@4 12
bgneal@4 13 using namespace enigma;
bgneal@4 14
bgneal@4 15 ////////////////////////////////////////////////////////////////////////////////
bgneal@4 16
bgneal@4 17 enigma_machine::enigma_machine(
bgneal@4 18 rotor_vector rv,
bgneal@4 19 std::unique_ptr<rotor> reflector,
bgneal@4 20 const plugboard& pb)
bgneal@4 21 : rotors(std::move(rv)),
bgneal@4 22 reflector(std::move(reflector)),
bgneal@4 23 pb(pb),
bgneal@4 24 r_rotor(0),
bgneal@4 25 m_rotor(0),
bgneal@4 26 l_rotor(0)
bgneal@4 27 {
bgneal@4 28 rotor_count_check();
bgneal@4 29 }
bgneal@4 30
bgneal@4 31 ////////////////////////////////////////////////////////////////////////////////
bgneal@4 32
bgneal@4 33 enigma_machine::enigma_machine(
bgneal@4 34 rotor_vector rv,
bgneal@4 35 std::unique_ptr<rotor> reflector)
bgneal@4 36 : rotors(std::move(rv)),
bgneal@4 37 reflector(std::move(reflector)),
bgneal@4 38 pb(),
bgneal@4 39 r_rotor(0),
bgneal@4 40 m_rotor(0),
bgneal@4 41 l_rotor(0)
bgneal@4 42 {
bgneal@4 43 rotor_count_check();
bgneal@4 44 }
bgneal@4 45
bgneal@4 46 ////////////////////////////////////////////////////////////////////////////////
bgneal@4 47
bgneal@4 48 enigma_machine::enigma_machine(
bgneal@4 49 const std::vector<std::string>& rotor_types,
bgneal@4 50 const std::vector<int>& ring_settings,
bgneal@4 51 const std::string& reflector_name,
bgneal@4 52 const std::string& plugboard_settings)
bgneal@4 53 : rotors(),
bgneal@4 54 reflector(create_reflector(reflector_name.c_str())),
bgneal@4 55 pb(plugboard_settings),
bgneal@4 56 r_rotor(0),
bgneal@4 57 m_rotor(0),
bgneal@4 58 l_rotor(0)
bgneal@4 59 {
bgneal@4 60 for (const auto& name : rotor_types)
bgneal@4 61 {
bgneal@4 62 rotors.push_back(create_rotor(name.c_str()));
bgneal@4 63 }
bgneal@4 64 rotor_count_check();
bgneal@4 65
bgneal@4 66 // if ring settings are supplied, there has to be one for each rotor
bgneal@4 67 if (!ring_settings.empty())
bgneal@4 68 {
bgneal@4 69 if (rotors.size() != ring_settings.size())
bgneal@4 70 {
bgneal@4 71 throw enigma_machine_error("rotor/ring setting count mismatch");
bgneal@4 72 }
bgneal@4 73
bgneal@4 74 for (std::size_t i = 0; i < rotors.size(); ++i)
bgneal@4 75 {
bgneal@4 76 rotors[i]->set_ring_setting(ring_settings[i]);
bgneal@4 77 }
bgneal@4 78 }
bgneal@4 79 }
bgneal@4 80
bgneal@4 81 ////////////////////////////////////////////////////////////////////////////////
bgneal@4 82
bgneal@4 83 void enigma_machine::rotor_count_check()
bgneal@4 84 {
bgneal@4 85 if (rotors.size() != 3 && rotors.size() != 4)
bgneal@4 86 {
bgneal@4 87 throw enigma_machine_error("rotor count");
bgneal@4 88 }
bgneal@4 89
bgneal@4 90 if (rotors.size() == 3)
bgneal@4 91 {
bgneal@4 92 r_rotor = rotors[2].get();
bgneal@4 93 m_rotor = rotors[1].get();
bgneal@4 94 l_rotor = rotors[0].get();
bgneal@4 95 }
bgneal@4 96 else
bgneal@4 97 {
bgneal@4 98 r_rotor = rotors[3].get();
bgneal@4 99 m_rotor = rotors[2].get();
bgneal@4 100 l_rotor = rotors[1].get();
bgneal@4 101 }
bgneal@4 102 }
bgneal@8 103
bgneal@8 104 ////////////////////////////////////////////////////////////////////////////////
bgneal@8 105
bgneal@8 106 std::string enigma_machine::str(bool army) const
bgneal@8 107 {
bgneal@8 108 std::ostringstream os;
bgneal@8 109
bgneal@8 110 os << reflector->name() << ' ';
bgneal@8 111
bgneal@8 112 for (const auto& r : rotors)
bgneal@8 113 {
bgneal@8 114 os << r->name() << '/' << r->get_ring_setting() << ' ';
bgneal@8 115 }
bgneal@8 116
bgneal@8 117 os << get_display() << ' ' << (army ? pb.army_str() : pb.navy_str());
bgneal@8 118
bgneal@8 119 return os.str();
bgneal@8 120 }
bgneal@8 121