Mercurial > public > cpp-enigma
changeset 16:280facb82b80
Add the ability to change ring settings at the machine level.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 07 Jul 2012 11:42:31 -0500 (2012-07-07) |
parents | 9e02d8696e67 |
children | b04dea5f71a3 |
files | enigma/machine.h enigma/tests/test_machine.t.h |
diffstat | 2 files changed, 122 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/enigma/machine.h Wed Jul 04 19:52:41 2012 -0500 +++ b/enigma/machine.h Sat Jul 07 11:42:31 2012 -0500 @@ -6,10 +6,12 @@ // // machine.h - This file contains the main Enigma machine class. +#include <algorithm> #include <memory> #include <string> #include <vector> #include <cassert> +#include <cstddef> #include "enigma_types.h" #include "rotor.h" #include "plugboard.h" @@ -97,6 +99,66 @@ return result; } + // Returns the number of rotors in the machine (this count does not include + // the reflector). + std::size_t num_rotors() const + { + return rotors.size() - 1; + } + + // For changing the ring setting on a rotor inside the machine. + // Parameters: + // rotor - identifies the rotor to change the ring setting; must be + // in the range 0 - (num_rotors() - 1). 0 is the leftmost rotor. + // ring_setting - the ring setting value, 0-25 + // + void set_ring_setting(int rotor, int ring_setting) + { + rotors[rotor + 1].set_ring_setting(ring_setting); + } + + // For getting the ring setting on a rotor inside the machine. + // Parameters: + // rotor - identifies the rotor to change the ring setting; must be + // in the range 0 - (num_rotors() - 1). 0 is the leftmost rotor. + // + int get_ring_setting(int rotor) const + { + return rotors[rotor + 1].get_ring_setting(); + } + + // For changing the ring settings on all rotors inside the machine. + // Parameters: + // settings - a vector of ring settings, 0-25. The size of this + // vector must match num_rotors(). + // + void set_ring_settings(const std::vector<int>& settings) + { + if (settings.size() == num_rotors()) + { + rotor* r = &rotors[1]; // skip the reflector; + for (auto s : settings) + { + r->set_ring_setting(s); + ++r; + } + } + else + { + throw enigma_machine_error("set_ring_settings rotor/settings size mismatch"); + } + } + + // For getting the ring settings as a vector of integers. Element 0 corresponds + // to the leftmost rotor. + std::vector<int> get_ring_settings() const + { + std::vector<int> result(num_rotors()); + std::transform(rotors.begin() + 1, rotors.end(), result.begin(), + [](const rotor& r) { return r.get_ring_setting(); }); + return result; + } + // simulate front panel key press; returns the lamp character that is lit char key_press(char c) { @@ -120,6 +182,7 @@ } } + // Process a buffer of text from a string, returning the result as a string. std::string process_text(const std::string& input) { std::string result;
--- a/enigma/tests/test_machine.t.h Wed Jul 04 19:52:41 2012 -0500 +++ b/enigma/tests/test_machine.t.h Sat Jul 07 11:42:31 2012 -0500 @@ -253,3 +253,62 @@ } }; + +class ring_settings_test_suite : public CxxTest::TestSuite +{ +public: + + void test_ring_settings() + { + enigma_machine machine({"Beta", "II", "IV", "I"}, {0, 2, 8, 21}, "B-Thin"); + + TS_ASSERT_EQUALS(machine.get_ring_setting(0), 0); + TS_ASSERT_EQUALS(machine.get_ring_setting(1), 2); + TS_ASSERT_EQUALS(machine.get_ring_setting(2), 8); + TS_ASSERT_EQUALS(machine.get_ring_setting(3), 21); + + std::vector<int> rings(machine.get_ring_settings()); + std::vector<int> expected{ 0, 2, 8, 21 }; + TS_ASSERT_EQUALS(rings, expected); + + machine.set_ring_setting(0, 25); + TS_ASSERT_EQUALS(machine.get_ring_setting(0), 25); + TS_ASSERT_EQUALS(machine.get_ring_setting(1), 2); + TS_ASSERT_EQUALS(machine.get_ring_setting(2), 8); + TS_ASSERT_EQUALS(machine.get_ring_setting(3), 21); + + expected = { 25, 2, 8, 21 }; + TS_ASSERT_EQUALS(machine.get_ring_settings(), expected); + + machine.set_ring_setting(1, 18); + TS_ASSERT_EQUALS(machine.get_ring_setting(0), 25); + TS_ASSERT_EQUALS(machine.get_ring_setting(1), 18); + TS_ASSERT_EQUALS(machine.get_ring_setting(2), 8); + TS_ASSERT_EQUALS(machine.get_ring_setting(3), 21); + + expected = { 25, 18, 8, 21 }; + TS_ASSERT_EQUALS(machine.get_ring_settings(), expected); + + machine.set_ring_setting(2, 11); + TS_ASSERT_EQUALS(machine.get_ring_setting(0), 25); + TS_ASSERT_EQUALS(machine.get_ring_setting(1), 18); + TS_ASSERT_EQUALS(machine.get_ring_setting(2), 11); + TS_ASSERT_EQUALS(machine.get_ring_setting(3), 21); + + expected = { 25, 18, 11, 21 }; + TS_ASSERT_EQUALS(machine.get_ring_settings(), expected); + + machine.set_ring_setting(3, 3); + TS_ASSERT_EQUALS(machine.get_ring_setting(0), 25); + TS_ASSERT_EQUALS(machine.get_ring_setting(1), 18); + TS_ASSERT_EQUALS(machine.get_ring_setting(2), 11); + TS_ASSERT_EQUALS(machine.get_ring_setting(3), 3); + + expected = { 25, 18, 11, 3 }; + TS_ASSERT_EQUALS(machine.get_ring_settings(), expected); + + expected = { 8, 9, 10, 11 }; + machine.set_ring_settings(expected); + TS_ASSERT_EQUALS(machine.get_ring_settings(), expected); + } +};