Skip to content

Instantly share code, notes, and snippets.

@Zorgatone
Created February 23, 2017 16:24
Show Gist options
  • Select an option

  • Save Zorgatone/76eaf8ed65d019195df58c91b45983b9 to your computer and use it in GitHub Desktop.

Select an option

Save Zorgatone/76eaf8ed65d019195df58c91b45983b9 to your computer and use it in GitHub Desktop.
Bulls and Cows game in C++
#include <iostream>
#include <vector>
#include <stdexcept>
#include <ctime>
#include <cstdlib>
#include <cctype>
using namespace std;
constexpr short int number_of_digits{ 4 };
constexpr short int upper_limit{ 10 };
void init_digits(vector<char>& digits);
void get_chars(vector<char>& chars);
void check_input(vector<char>& digits, vector<char>& chars, short int& bulls, short int& cows);
int main() {
vector<char> digits(number_of_digits);
vector<char> chars(number_of_digits);
char answer;
do {
short int bulls{ 0 }, cows{ 0 };
unsigned int tries{ 1 };
init_digits(digits);
/*
// <DEBUG>
cout << "-- Secret chars: ";
for (short int i{ 0 }; i < number_of_digits; i++) {
cout << digits[i];
}
cout << " --" << endl;
// </DEBUG>
*/
while(true) {
cout << "Try to guess the 4 chars (0-9): ";
try {
get_chars(chars);
} catch(runtime_error& e) {
cerr << e.what() << endl;
continue;
}
check_input(digits, chars, bulls, cows);
if (bulls == 4) {
cout << "You win with " << tries << " tries!" << endl;
break;
}
cout << bulls << " bulls and " << cows << " cows." << endl;
tries++;
}
cout << endl << "Do you want to play again [y/N]? ";
cin >> answer;
} while(tolower(answer) == 'y');
return 0;
}
void init_digits(vector<char>& digits) {
srand(unsigned(time(NULL)));
vector<bool> checks(10, false);
for (short int i{ 0 }; i < number_of_digits; i++) {
short int d = (rand() % upper_limit);
if (checks[d]) {
i--;
continue; // Skip duplicated digit
}
digits[i] = '0' + d;
checks[d] = true;
}
}
void get_chars(vector<char>& chars) {
vector<bool> checks(10, false);
for (short int i{ 0 }; i < number_of_digits; i++) {
char c;
cin >> c;
if (!isnumber(c)) {
string s{c};
s = "Error: invalid char \"" + s + "\"!";
throw runtime_error(s);
}
unsigned short d = c - '0';
if (checks[d]) {
string s{c};
s = "Error: digit \"" + s + "\" is duplicated!";
throw runtime_error(s);
}
chars[i] = c;
checks[d] = true;
}
}
void check_input(vector<char>& digits, vector<char>& chars, short int& bulls, short int& cows) {
bulls = cows = 0; // Double-checking initial value.
for (short int i{ 0 }; i < number_of_digits; i++) {
for (short int j{ 0 }; j < number_of_digits; j++) {
if (digits[i] == chars[j]) {
if (i == j) {
bulls++;
break;
} else {
cows++;
}
}
}
}
}
@VishavjeetBawa
Copy link

VishavjeetBawa commented Mar 21, 2025

Will it not count multiple cows(useless addition) ?
I tried to make for and I had to track the indicies of bulls and skip them. at first I used the same logic as yours.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment