26 std::vector<RotorConfig> defaultRotors(
rotorCount);
35RotorBox::RotorBox(
const std::vector<AlphabetIndex>& rotorPositions,
const std::vector<RotorConfig>& rotors,
39 throw std::invalid_argument(
"Error: Number of rotors and number of rotor positions do not match.");
48 transformers.at(i)->setPosition(this->rotorPositions.at(i));
52RotorBox::RotorBox(std::vector<AlphabetIndex>&& rotorPositions, std::vector<RotorConfig>&& rotors,
54 : rotorCount((int)rotorPositions.size()), rotorPositions(std::move(rotorPositions)), logger(logger) {
55 if (std::cmp_not_equal(this->
rotorPositions.size(), rotors.size())) {
56 throw std::invalid_argument(
"Error: Number of rotors and number of rotor positions do not match.");
61 for (
auto& rotorConfig : rotors) {
62 transformers.push_back(std::make_unique<Rotor>(std::move(rotorConfig)));
64 transformers.push_back(std::make_unique<Reflector>(std::move(reflector)));
74 auto iterator = std::ranges::remove(
observers, observer).begin();
89 for (
const auto& rotorConfig : rotors) {
90 transformers.push_back(std::make_unique<Rotor>(rotorConfig));
92 transformers.emplace_back(std::make_unique<Reflector>(reflector));
98 std::string msg =
"Transformer " + std::to_string(i) +
99 " Type: " + std::to_string(
static_cast<int>(
transformers[i]->getType()));
100 logger->log(LogLevel::Info, msg);
115 AlphabetIndex newPosition = input;
118 newPosition = transformer->transformForward(newPosition);
126 newPosition = transformer->transformReverse(newPosition);
149 std::ranges::transform(
transformers | std::views::take(
rotorCount), atNotch.begin(), [](
const auto& transformer) {
150 const auto* rotor = static_cast<const Rotor*>(transformer.get());
151 return rotor->isNotchPosition(rotor->getPosition()) ? 1 : 0;
158 if (
logger)
logger->log(LogLevel::Debug,
"Rotor 0 stepped.");
161 bool carried = atNotch[i - 1] != 0;
162 bool doubleStep = (i <
rotorCount - 1) && (atNotch[i] != 0);
163 if (carried || doubleStep) {
166 std::string reason = carried ?
"carry" :
"double-step";
167 logger->log(LogLevel::Debug,
"Rotor " + std::to_string(i) +
" stepped due to " + reason +
".");
173 std::ranges::for_each(std::views::iota(0,
rotorCount), [
this](
int index) {
174 const int position =
transformers.at(index)->getPosition();
176 [index, position](
auto* observer) { observer->onRotorStepped(index, position); });
Header file for the Reflector class.
Header file for the RotorBox class.
Defines the Rotor class, a concrete implementation of the Transformer interface.
void updateRotors()
Updates the positions of the rotors.
void initTransformers(const std::vector< RotorConfig > &rotors, const ReflectorConfig &reflector)
Initializes the transformer vector with rotors and a reflector.
RotorBox(ILogger *logger=nullptr)
Constructor for the RotorBox class. Initializes the rotor box with a default number of rotors (3) and...
std::vector< AlphabetIndex > rotorPositions
void registerObserver(IEnigmaObserver *observer)
Registers an observer to receive notifications.
std::vector< IEnigmaObserver * > observers
void printTransformers() const
Prints the types of transformers in the transformer vector. This function iterates through the transf...
std::vector< std::unique_ptr< Transformer > > transformers
AlphabetIndex keyTransform(AlphabetIndex input)
Transforms the input key through the rotor box.
void removeObserver(IEnigmaObserver *observer)
Removes an observer.
void setLogger(ILogger *logger)
Sets the logger for the rotor box.
Global configuration constants for the Enigma machine.
Interface for observing Enigma Machine events. Implement this interface to receive notifications abou...
Configuration structure for a Reflector.