I have implemented the bulls and cows game in C++.
The code:
#include <cstdio>
#include <cstdlib>
#include <ctime>
struct DigitMatches {
int matches_in_right_positions;
int matches_in_wrong_positions;
};
void CountNumberDigits(int (&counts)[10], int n) {
while (n > 0) {
counts[n % 10]++;
n /= 10;
}
}
class DigitsMatchChecker {
public:
DigitMatches CheckMatchedDigits(int generated_number, int guess_number) {
CountNumberDigits(this->generated_number_left_digits_, generated_number);
CountNumberDigits(this->guess_number_left_digits_, guess_number);
DigitMatches matches;
matches.matches_in_right_positions = this->CountMatchesInRightPositions(generated_number, guess_number);
matches.matches_in_wrong_positions = this->CountMatchesInWrongPositions(guess_number);
return matches;
}
private:
int CountMatchesInRightPositions(int generated_number, int guess_number) {
int matches = 0;
while (generated_number > 0 && guess_number > 0) {
const int generated_number_digit = generated_number % 10;
const int guess_number_digit = guess_number % 10;
if (generated_number_digit == guess_number_digit) {
matches++;
this->guess_number_left_digits_[generated_number_digit]--;
this->generated_number_left_digits_[generated_number_digit]--;
}
generated_number /= 10;
guess_number /= 10;
}
return matches;
}
int CountMatchesInWrongPositions(int guess_number) {
int matches = 0;
while (guess_number > 0) {
const int guess_number_digit = guess_number % 10;
int &generated_number_left_digits = this->generated_number_left_digits_[guess_number_digit];
int &guess_number_left_digits = this->guess_number_left_digits_[guess_number_digit];
if (generated_number_left_digits > 0 && guess_number_left_digits > 0) {
matches++;
generated_number_left_digits--;
guess_number_left_digits--;
}
guess_number /= 10;
}
return matches;
}
private:
int generated_number_left_digits_[10] = {};
int guess_number_left_digits_[10] = {};
};
void InitializeRandomNumberGenerator() {
srand(time(nullptr));
}
int GenerateNumber(int min, int max) {
return min + (rand() % (max - min + 1));
}
int InputNumber() {
int n;
scanf("%d", &n);
return n;
}
int main() {
InitializeRandomNumberGenerator();
const int kTotalNumberOfDigits = 4;
const int generated_number = GenerateNumber(1000, 9999);
int attempts = 0;
while (true) {
const int guess_number = InputNumber();
if (guess_number < 1000 || guess_number > 9999) {
printf("Invalid number. Must be between 1000 and 9999.\n");
continue;
}
const DigitMatches matches = DigitsMatchChecker().CheckMatchedDigits(generated_number, guess_number);
printf("%d cows, %d bulls\n", matches.matches_in_right_positions, matches.matches_in_wrong_positions);
attempts++;
if (matches.matches_in_right_positions == kTotalNumberOfDigits)
break;
}
printf("You won! Attempts: %d\n", attempts);
return 0;
}
I would like to hear objective criticism and comments on my code.