Bulls and Cows

Hi everyone, I was asked to write a Bulls and Cows game for homework and I've done the most. But couldn't get to some points, could you help fill in a few blanks for me? Thanks so much.

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include <bjarne/std_lib_facilities.h>

// if debug is true, then 
//    don't initially seed the random number generator
//    print solution at the start of each game
//    print debug info about the bull/cow calculation
const bool debug = false; 

// for bad input data
class Bad_data{};

// for a bad frequency vector ... this shouldn't ever happen
class Bad_frequency{};

void offer_help(int num_slots, int range_top);
vector<int> generate_solution(int num_slots, int range_top);
void print_vector(string msg, vector<int> v);
bool play_one_game(vector<int> solution, int range_top);
int count_cows(int bulls, vector<int> guess, vector<int> solution, 
               int range_top);
vector<int> compute_frequency(vector<int> data, int range_top);
void print_debug_info(vector<int> solution_frequency, 
                      vector<int> guess_frequency, 
                      vector<int> min_frequency, int total_hits);

int main()
{
   // game parameters
   const int num_slots = 4;     // number of slots
   const int range_top = 10;    // upper bound on slot value

   // pigeonhole-principle check
   if (num_slots >= range_top) {
      cerr << "Error: range_top (" << range_top
	   << ") should be less than num_slots " << num_slots << endl; 
      return 1;
   }

   if (!debug)  // make game truly random if playing "for real"
      srand(time(0));   

   try {
      offer_help(num_slots, range_top);     // ... if needed

      bool playing = true;           // play another round?
      while (playing) {
         // generate solution 
         vector<int> solution = generate_solution(num_slots, range_top);

         // debug...print the solution
         if (debug) 
            print_vector("Actual solution: ", solution);

         // play the game
         bool success = play_one_game(solution, range_top);

         if (success)
            cout << "Congratulations!\n";
         else 
            print_vector("Too bad!  Solution was ", solution);

         // another round?
         cout << "\nPlay again (0/1)? ";
         int play_again;
         if (!(cin >> play_again))
            throw Bad_data();
         playing = play_again != 0;
      }
   }
   catch (Bad_data) {
      cerr << "Bad input data!  I give up!\n";
      return 2;
   }
   catch (Bad_frequency) {
      cerr << "Bad frequency vector.  This can't happen!\n";
      return 3;
   }
}

/*
 * offer help, if needed
 */
void offer_help(int num_slots, int range_top)
{
   cout << "Need help (0/1)? ";
   int need_help;
   if (!(cin >> need_help)) 
      throw Bad_data();

   if (need_help != 0) {
       cout << "I will generate a pattern of 4 distinct numbers,each in the range 0 through 9.\n";
       cout << "You will give a series of guesses of this pattern.\n";
       cout << "Each guess that you enter will be a line containg 4 intergers,seperated by spaces, such as\n";
       cout << "     2 4 3 1\n";
       cout << "I will respond with the number of bulls and cows.\n";
       cout << "For example, if the actual solution was 2 3 6 1, I'll respond\n";
       cout << "     Bulls: 2, cows: 1\n";
       cout << "Since two guesses (2 and 1) were in the correct position and one guess (3) was in a n incorrect position.\n";
       cout << "See how many guesses it takes you to get the solution!\n";
       cout << "\n";
       cout << "If you want to give up, type a negative number for one of your guesses, and we'll tell you what the pattern was.\n";
   }

/*
 * generate solution for a game of Bulls and Cows
 *
 * precondition: num_slots > 0, range_top > 0
 * return value: vector of size num_slots, with distinct entries, each
 * in the range [0..range_top)
 */

vector<int> generate_solution(int num_slots, int range_top)
{
   // tracks which numbers have been used
   vector<bool> is_used(range_top);
   vector<int> solution;
   for (int i = 0; i < num_slots; i++) {
      int trial = randint(range_top);
      while (is_used.at(trial)) 
         trial = randint(range_top);         
      solution.push_back(trial);
      is_used.at(trial) = true;
   }
   return solution;
}

/*
 * print a vector, with an initial decoration, all on one line
 * 
 * the only precondition (not easily enforceable) is that it all fits
 * on line
 */
void print_vector(string msg, vector<int> v)
{
   cout << msg;
   for (int i = 0; i < v.size(); i++)
      cout << v[i] << " ";
   cout << endl;
}

/*
 * NEED HELP HERE
 * 
 * preconditon:  something
 * return value: something else
 */
bool play_one_game(vector<int> solution, int range_top)
{
   return true;                         // we won!
}

/*
 *  NEED HELP HERE
 */
int count_cows(int bulls, vector<int> guess, vector<int> solution, 
               int range_top)
{
   // next two lines should be
   //    vector<int> solution_frequency = ... ;
   //    vector<int> guess_frequency = ... ;
   // where you need to figure out how to fill in the right-hand side
   // of these initializations
   vector<int> solution_frequency;
   vector<int> guess_frequency;
   vector<int> min_frequency;
   int total_hits = 0;
   if (debug)
      print_debug_info(solution_frequency, guess_frequency, 
                       min_frequency, total_hits);
   return 42;
}

/* NEED HELP HERE
 * determine how many 0's, 1's, ... in a given vector
 *
 * precondition: something 
 * return value: yet another thing
 */
vector<int> compute_frequency(vector<int> data, int range_top)
{
   vector<int> temp(range_top);
   // a simple, yet elegant, for-loop will do the job here
   return temp;
}

/*
 * prints useful debugging information, as per the project handout
 */
void print_debug_info(vector<int> solution_frequency, 
                      vector<int> guess_frequency, 
                      vector<int> min_frequency, int total_hits)
{
   cout << "index:             ";
   for (int i = 0; i < solution_frequency.size(); i++)
      cout << " " << i;
   cout << "                   ";
   cout << endl;
   cout << "                   ";
   for (int i = 0; i < solution_frequency.size(); i++)
      cout << "--";
   cout << endl;      
   cout << "solution frequency:";
   for (int i = 0; i < solution_frequency.size(); i++)
      cout << " " << solution_frequency[i];
   cout << endl;
   cout << "guess frequency:   ";
   for (int i = 0; i < guess_frequency.size(); i++)
      cout << " " << guess_frequency[i];
   cout << endl;
   cout << "minimum:           ";
   for (int i = 0; i < guess_frequency.size(); i++)
      cout << " " << min_frequency[i];
   cout << endl;
   cout << "sum minimum:        " << total_hits << endl;
}
Sorry for not making it clear, the input should be 4 different integers from 0-9.
The output should be like this:
Need help (0/1)? 0
Actual solution: 3 6 7 5
Guess #1? 3 3 2 1
index: 0 1 2 3 4 5 6 7 8 9
--------------------
soln frequency: 0 0 0 1 0 1 1 1 0 0
guess frequency: 0 1 1 2 0 0 0 0 0 0
minimum: 0 0 0 1 0 0 0 0 0 0
sum minimum: 1
Bulls: 1, cows: 0
Guess #2? 2 3 1 4
index 0 1 2 3 4 5 6 7 8 9
--------------------
soln frequency: 0 0 0 1 0 1 1 1 0 0
guess frequency: 0 1 1 1 1 0 0 0 0 0
minimum: 0 0 0 1 0 0 0 0 0 0
sum minimum: 1
Bulls: 0, cows: 1
Guess #3? 3 6 7 5
index: 0 1 2 3 4 5 6 7 8 9
--------------------
soln frequency: 0 0 0 1 0 1 1 1 0 0
guess frequency: 0 0 0 1 0 1 1 1 0 0
minimum: 0 0 0 1 0 1 1 1 0 0
sum minimum: 4
Bulls: 4, cows: 0
Congratulations!
Play again (0/1)? 0
This is my code for this exercise but using letters
This was more complicated but at least i was getting right number of cows in this code (compared to my digit version)

Probably this is a bit hard to read but hope it helps a little

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Redo the Bulls and Cows game from exercise 12 in chapter 5 
//to use four letters rather than four digits

#include <string>
#include <vector>
#include <iostream>
#include <ctime>
using namespace std;

int main(){
	try{
		vector<char> vec_input, vec_kompis, vec_cows;
		srand(time(0));    // 97 - 122               starpiba 25
		int i, cows, bulls;
		for (int i = 0; i < 4; i++)
			vec_kompis.push_back((rand() % 26 + 97));       // 0 - 24          97 - 121
		char input;
		//cout << "Kompja vektors = ";
		//for (int i = 0; i < 4; i++){
		//	cout << vec_kompis[i] << " ";
		//}
		//cout << endl;
		cout << "enter the letters   ";
		bool done = false, cow_repeats = false;
		while (!done){
			i = 0;
			cows = 0;
			bulls = 0;
			cow_repeats = false;
			vec_input.clear();
			while (cin >> input && i < 4){
				vec_input.push_back(input);
				i++;
			}
			cin.clear();
			cin.ignore(numeric_limits<streamsize>::max(), '\n');
			for (int i = 0; i < vec_input.size(); i++){
				if (vec_input.at(i) == vec_kompis.at(i)){   // get bulls
					bulls++;
					cout << "Bulls is " << vec_input.at(i) << endl;
				}
				//ierakstisim vektora kads simbols jau ir saskaitits
				cow_repeats = false;
				for (int z = 0; z < i; z++){
					if (vec_input.at(i) == vec_input.at(z)) { 
						cow_repeats = true; 
					}
				}
				for (int j = 0; j < vec_input.size(); j++){          //tagad skaitisim cows
					if (j!=i && vec_kompis.at(i) == vec_input.at(j) && !cow_repeats){
						cows++;
						//cout << "cow ir " << vec_kompis.at(i) << endl;
					}
				}// for j = 0 loop beigas
			}// for i = 0 loop beigas

			cout << "bulls = " << bulls << endl
				<< "cows  = " << cows << endl;
			if (bulls == 4){
				cout << "Computers vector was  ";
				for (int i = 0; i < vec_kompis.size(); i++)
					cout << vec_kompis.at(i) << " ";
				done = true;
			}

		}// while(!done) beigas
		cin.get();
	}
	catch (exception& e){
		cerr << "error was " << e.what() << endl;
		system("pause");
	}

}
Last edited on
Topic archived. No new replies allowed.