Hi everyone!
I have no previous programming experience and am currently teaching myself C++ through the Stroustrup beginners book, and hit a bit of a snag.
One of the exercises in chapter 5 describes a game called Bulls & Cows: for those who haven't heard of it, the computer creates a vector of 4 random numbers between 0 and 9, and the user tries to guess the correct numbers in the correct sequence. A "bull" is a guess that's correct and in the right position in sequence, a "cow" is the correct number in the wrong position.
So I came up with something straightforward. Here's the original checking mechanism:
1 2 3 4 5 6 7
|
for (int i = 0; i < answer.size(); i++) {
for (int j = 0; j < guess.size(); j++) {
if (guess[i] == answer [j] && j == i) //correct num in right position
bulls++;
if (guess[i] == answer [j] && j != i) //correct num in wrong position
cows++;
|
I compiled it, ran it and it seemed absolutely fine after a few tries. I left it for a few days, but then I thought to myself: this chapter is all about errors and how to deal with it. I reread it, and the author suggests an attitude of "come on, let's break this code!" So I went back and had another look at it. I quickly found I had no provision for bad input or integers out of the range of 0-9, but that was quickly fixed. I was pretty satisfied with myself.
Then (the bane of my life!) against a test vector of 1 2 3 4 I tried 1 1 1 1. "You have 1 bull(s) and 3 cow(s)!". Oh, this can't be right, I thought. To cut a long story short, as I got more into the problem I divided the program into functions, so I could more easily focus on the area. I tried for days checking for the number of "bulls" within the loop, but finally realized it's better to do from without. So, my current version is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
void check_guess (const std::vector<int>& guess,
const std::vector<int>& answer, int& bulls, int& cows)
{
std::vector<int> bull_check;
for (int i = 0; i < answer.size(); i++) { //initial loop to fill
for (int j = 0; j < 4; j++) //a third vector checking
if (guess[i] == answer [j] && i == j) //number of correct bulls
bull_check.push_back (answer[i]);
}
for (int i = 0; i < answer.size(); i++) { //number of bulls and cows
for (int j = 0; j < guess.size(); j++) {
if (guess[i] == answer [j] && j == i) //correct num in right position
bulls++;
if (guess[i] == answer [j] && j != i){
if (bull_check.size() == 0) cows++; //no bulls, it's a cow!
else for (int k = 0; k < bull_check.size(); ++k){//right num, wrong position.
if (guess [i] == bull_check [k]) break;
cows++;
}
}
}
}
}
|
This gives better, but still in certain conditions problematic output (e.g., input of 9 8 9 8 on 0 9 8 7 gives 2 bulls, 2 cows). I guess my questions would be: is there a simple solution I'm completely missing? The nub of the problem seems to be lines 18-22 and I have a bad feeling I'm horrendously over-complicating things!