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@4
|
8 #include "machine.h"
|
bgneal@4
|
9 #include "rotor.h"
|
bgneal@4
|
10 #include "rotor_factory.h"
|
bgneal@4
|
11
|
bgneal@4
|
12 using namespace enigma;
|
bgneal@4
|
13
|
bgneal@4
|
14 ////////////////////////////////////////////////////////////////////////////////
|
bgneal@4
|
15
|
bgneal@4
|
16 enigma_machine::enigma_machine(
|
bgneal@4
|
17 rotor_vector rv,
|
bgneal@4
|
18 std::unique_ptr<rotor> reflector,
|
bgneal@4
|
19 const plugboard& pb)
|
bgneal@4
|
20 : rotors(std::move(rv)),
|
bgneal@4
|
21 reflector(std::move(reflector)),
|
bgneal@4
|
22 pb(pb),
|
bgneal@4
|
23 r_rotor(0),
|
bgneal@4
|
24 m_rotor(0),
|
bgneal@4
|
25 l_rotor(0)
|
bgneal@4
|
26 {
|
bgneal@4
|
27 rotor_count_check();
|
bgneal@4
|
28 }
|
bgneal@4
|
29
|
bgneal@4
|
30 ////////////////////////////////////////////////////////////////////////////////
|
bgneal@4
|
31
|
bgneal@4
|
32 enigma_machine::enigma_machine(
|
bgneal@4
|
33 rotor_vector rv,
|
bgneal@4
|
34 std::unique_ptr<rotor> reflector)
|
bgneal@4
|
35 : rotors(std::move(rv)),
|
bgneal@4
|
36 reflector(std::move(reflector)),
|
bgneal@4
|
37 pb(),
|
bgneal@4
|
38 r_rotor(0),
|
bgneal@4
|
39 m_rotor(0),
|
bgneal@4
|
40 l_rotor(0)
|
bgneal@4
|
41 {
|
bgneal@4
|
42 rotor_count_check();
|
bgneal@4
|
43 }
|
bgneal@4
|
44
|
bgneal@4
|
45 ////////////////////////////////////////////////////////////////////////////////
|
bgneal@4
|
46
|
bgneal@4
|
47 enigma_machine::enigma_machine(
|
bgneal@4
|
48 const std::vector<std::string>& rotor_types,
|
bgneal@4
|
49 const std::vector<int>& ring_settings,
|
bgneal@4
|
50 const std::string& reflector_name,
|
bgneal@4
|
51 const std::string& plugboard_settings)
|
bgneal@4
|
52 : rotors(),
|
bgneal@4
|
53 reflector(create_reflector(reflector_name.c_str())),
|
bgneal@4
|
54 pb(plugboard_settings),
|
bgneal@4
|
55 r_rotor(0),
|
bgneal@4
|
56 m_rotor(0),
|
bgneal@4
|
57 l_rotor(0)
|
bgneal@4
|
58 {
|
bgneal@4
|
59 for (const auto& name : rotor_types)
|
bgneal@4
|
60 {
|
bgneal@4
|
61 rotors.push_back(create_rotor(name.c_str()));
|
bgneal@4
|
62 }
|
bgneal@4
|
63 rotor_count_check();
|
bgneal@4
|
64
|
bgneal@4
|
65 // if ring settings are supplied, there has to be one for each rotor
|
bgneal@4
|
66 if (!ring_settings.empty())
|
bgneal@4
|
67 {
|
bgneal@4
|
68 if (rotors.size() != ring_settings.size())
|
bgneal@4
|
69 {
|
bgneal@4
|
70 throw enigma_machine_error("rotor/ring setting count mismatch");
|
bgneal@4
|
71 }
|
bgneal@4
|
72
|
bgneal@4
|
73 for (std::size_t i = 0; i < rotors.size(); ++i)
|
bgneal@4
|
74 {
|
bgneal@4
|
75 rotors[i]->set_ring_setting(ring_settings[i]);
|
bgneal@4
|
76 }
|
bgneal@4
|
77 }
|
bgneal@4
|
78 }
|
bgneal@4
|
79
|
bgneal@4
|
80 ////////////////////////////////////////////////////////////////////////////////
|
bgneal@4
|
81
|
bgneal@4
|
82 void enigma_machine::rotor_count_check()
|
bgneal@4
|
83 {
|
bgneal@4
|
84 if (rotors.size() != 3 && rotors.size() != 4)
|
bgneal@4
|
85 {
|
bgneal@4
|
86 throw enigma_machine_error("rotor count");
|
bgneal@4
|
87 }
|
bgneal@4
|
88
|
bgneal@4
|
89 if (rotors.size() == 3)
|
bgneal@4
|
90 {
|
bgneal@4
|
91 r_rotor = rotors[2].get();
|
bgneal@4
|
92 m_rotor = rotors[1].get();
|
bgneal@4
|
93 l_rotor = rotors[0].get();
|
bgneal@4
|
94 }
|
bgneal@4
|
95 else
|
bgneal@4
|
96 {
|
bgneal@4
|
97 r_rotor = rotors[3].get();
|
bgneal@4
|
98 m_rotor = rotors[2].get();
|
bgneal@4
|
99 l_rotor = rotors[1].get();
|
bgneal@4
|
100 }
|
bgneal@4
|
101 }
|