Mercurial > public > cpp-enigma
comparison 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 |
comparison
equal
deleted
inserted
replaced
12:424111a36ed7 | 13:b9d124a15926 |
---|---|
16 | 16 |
17 enigma_machine::enigma_machine( | 17 enigma_machine::enigma_machine( |
18 const rotor_vector& rv, | 18 const rotor_vector& rv, |
19 std::shared_ptr<rotor> reflector, | 19 std::shared_ptr<rotor> reflector, |
20 const plugboard& pb) | 20 const plugboard& pb) |
21 : rotors(rv), | 21 : rotors(), |
22 reflector(reflector), | |
23 pb(pb) | 22 pb(pb) |
24 { | 23 { |
24 rotors.push_back(*reflector); | |
25 for (const auto& r : rv) | |
26 { | |
27 rotors.push_back(*r); | |
28 } | |
25 rotor_count_check(); | 29 rotor_count_check(); |
26 } | 30 } |
27 | 31 |
28 //////////////////////////////////////////////////////////////////////////////// | 32 //////////////////////////////////////////////////////////////////////////////// |
29 | 33 |
30 enigma_machine::enigma_machine( | 34 enigma_machine::enigma_machine( |
31 const rotor_vector& rv, | 35 const rotor_vector& rv, |
32 std::shared_ptr<rotor> reflector) | 36 std::shared_ptr<rotor> reflector) |
33 : rotors(rv), | 37 : rotors(), |
34 reflector(reflector), | |
35 pb() | 38 pb() |
36 { | 39 { |
40 rotors.push_back(*reflector); | |
41 for (const auto& r : rv) | |
42 { | |
43 rotors.push_back(*r); | |
44 } | |
37 rotor_count_check(); | 45 rotor_count_check(); |
38 } | 46 } |
39 | 47 |
40 //////////////////////////////////////////////////////////////////////////////// | 48 //////////////////////////////////////////////////////////////////////////////// |
41 | 49 |
43 const std::vector<std::string>& rotor_types, | 51 const std::vector<std::string>& rotor_types, |
44 const std::vector<int>& ring_settings, | 52 const std::vector<int>& ring_settings, |
45 const std::string& reflector_name, | 53 const std::string& reflector_name, |
46 const std::string& plugboard_settings) | 54 const std::string& plugboard_settings) |
47 : rotors(), | 55 : rotors(), |
48 reflector(create_reflector(reflector_name.c_str())), | |
49 pb(plugboard_settings) | 56 pb(plugboard_settings) |
50 { | 57 { |
58 const auto ukw(create_reflector(reflector_name.c_str())); | |
59 rotors.push_back(*ukw); | |
51 for (const auto& name : rotor_types) | 60 for (const auto& name : rotor_types) |
52 { | 61 { |
53 rotors.push_back(create_rotor(name.c_str())); | 62 const auto r(create_rotor(name.c_str())); |
63 rotors.push_back(*r); | |
54 } | 64 } |
55 rotor_count_check(); | 65 rotor_count_check(); |
56 | 66 |
57 // if ring settings are supplied, there has to be one for each rotor | 67 // if ring settings are supplied, there has to be one for each rotor |
58 if (!ring_settings.empty()) | 68 if (!ring_settings.empty()) |
59 { | 69 { |
60 if (rotors.size() != ring_settings.size()) | 70 if (rotors.size() - 1 != ring_settings.size()) |
61 { | 71 { |
62 throw enigma_machine_error("rotor/ring setting count mismatch"); | 72 throw enigma_machine_error("rotor/ring setting count mismatch"); |
63 } | 73 } |
64 | 74 |
65 for (std::size_t i = 0; i < rotors.size(); ++i) | 75 for (std::size_t i = 1; i < rotors.size(); ++i) |
66 { | 76 { |
67 rotors[i]->set_ring_setting(ring_settings[i]); | 77 rotors[i].set_ring_setting(ring_settings[i - 1]); |
68 } | 78 } |
69 } | 79 } |
70 } | 80 } |
71 | 81 |
72 //////////////////////////////////////////////////////////////////////////////// | 82 //////////////////////////////////////////////////////////////////////////////// |
73 | 83 |
74 void enigma_machine::rotor_count_check() | 84 void enigma_machine::rotor_count_check() |
75 { | 85 { |
76 if (rotors.size() != 3 && rotors.size() != 4) | 86 // the first rotor is actually the reflector; so we should have a total |
87 // of 4 or 5 rotors | |
88 if (rotors.size() != 4 && rotors.size() != 5) | |
77 { | 89 { |
78 throw enigma_machine_error("rotor count"); | 90 throw enigma_machine_error("rotor count"); |
79 } | 91 } |
80 | 92 |
81 if (rotors.size() == 3) | 93 if (rotors.size() == 4) |
82 { | 94 { |
83 r_rotor = rotors[2].get(); | 95 r_rotor = &rotors[3]; |
84 m_rotor = rotors[1].get(); | 96 m_rotor = &rotors[2]; |
85 l_rotor = rotors[0].get(); | 97 l_rotor = &rotors[1]; |
86 } | 98 } |
87 else | 99 else |
88 { | 100 { |
89 r_rotor = rotors[3].get(); | 101 r_rotor = &rotors[4]; |
90 m_rotor = rotors[2].get(); | 102 m_rotor = &rotors[3]; |
91 l_rotor = rotors[1].get(); | 103 l_rotor = &rotors[2]; |
92 } | 104 } |
93 } | 105 } |
94 | 106 |
95 //////////////////////////////////////////////////////////////////////////////// | 107 //////////////////////////////////////////////////////////////////////////////// |
96 | 108 |
97 std::string enigma_machine::str(bool army) const | 109 std::string enigma_machine::str(bool army) const |
98 { | 110 { |
99 std::ostringstream os; | 111 std::ostringstream os; |
100 | 112 |
101 os << reflector->name() << ' '; | 113 os << rotors[0].name() << ' '; |
102 | 114 |
103 for (const auto& r : rotors) | 115 for (std::size_t i = 1; i < rotors.size(); ++i) |
104 { | 116 { |
105 os << r->name() << '/' << r->get_ring_setting() << ' '; | 117 os << rotors[i].name() << '/' << rotors[i].get_ring_setting() << ' '; |
106 } | 118 } |
107 | 119 |
108 os << get_display() << ' ' << (army ? pb.army_str() : pb.navy_str()); | 120 os << get_display() << ' ' << (army ? pb.army_str() : pb.navy_str()); |
109 | 121 |
110 return os.str(); | 122 return os.str(); |