// Author: Chan Tsz Ming // U. No.: 3035692462 // COMP2113 Course Project // Description: Bulls and Cows // this is the main file for running the game #include <iostream> #include <cstdlib> #include <string> #include <cctype> #include <ctime> using namespace std; // A "Guess" contains parameters A and B, representing... // ...the no. of bulls and cows respectively of a guess number // It stores the guess number ("gnum") in a dynamic char array as well struct Guess { int A; int B; char * gnum; }; // this function gets a number from user input // if the input is valid, it returns True and stores the input number in a dynamic char array num[] // int leng is the required no. of digits in the number // it returns False if the input is invalid // NOTE: num is a char array, not int or int array bool getnum_in(char * &num, int leng) { string num_in; cin >> num_in; if (num_in.length() != leng) { return 0; } else { int i; for (i = 0; i < num_in.length(); i++) { if (!isdigit(num_in[i])) { return 0; break; } else num[i] = num_in[i]; } num[i] = '\0'; return 1; } } // this function returns the number of bulls // sec: secret number guess: guess number by player leng: no. of digits of the number int n_bulls(char * &sec , char * &guess, int leng) { int b = 0; for (int i = 0 ; i < leng ; i++) { if (sec[i] == guess[i]) {b++ ;} } return b; } // this function returns the number of COWS AND BULLS TOGETHER // by comparing all possible combinations (pairs) between... // ... the digits of secret number and guess number int n_cowsNbulls(char * &sec , char * &guess, int leng) { // these two bool arrays are to record whether the digit... // ... has already been matched, to avoid double counting... // ... when there are repeated digits in sec or in guess bool * sec_matched = new bool[leng]; bool * guess_matched = new bool[leng]; for (int a = 0 ; a < leng ; a++) { // initialize all entries to be false sec_matched[a] = 0; guess_matched[a] = 0; } int c = 0; for (int i = 0 ; i < leng ; i++) { for (int j = 0; j < leng ; j++) { if (guess_matched[i] || sec_matched[j]) { continue; } else if (sec[j] == guess[i]) { c++; sec_matched[j] = 1; guess_matched[i] = 1; } } } delete [] sec_matched; delete [] guess_matched; return c; } // this function increases the size of the dynamic array guesses[] // guesses: the dynamic array guesses[] // size: the current size of guesses // increase: how much do you want the size of guesses[] to increase by void grow_guesses(Guess * &guesses, int &size, int increase) { if (guesses == NULL) return; int new_size = size + increase; Guess * tmp = new Guess [new_size]; for (int i = 0 ; i < size ; i++) { tmp[i] = guesses[i]; } delete [] guesses; guesses = tmp; size = new_size; } // main function int main() { srand(time(NULL)); // welcome message and introduction cout << "--------------------Welcome to Bulls and Cows!!--------------------" << endl; // choosing game mode cout << "Please indicate your preferred game mode:\n 1 Play with computer 2 Play with another person\n" << "Type \'1\' \'or \'2\': "; string mode; getline(cin, mode); while (mode!="1" && mode!="2") { cout << "Invalid mode. Please indicate the game mode by typing the number \'1\' or \'2\': "; getline(cin, mode); } if (mode == "1") cout << "\nYou may choose the no. of digits (1 to 20) of the secret number according to your desired difficulty.\n"; else if (mode == "2") cout << "\nPlayer 1 please get ready! Now, please think of a secret number and its no. of digits.\n"; // get the no. of digits of the secret number from user int leng; bool valid = 0; cout << "How many digits does the secret number contain? (1-20): "; while (!valid) { cin.clear(); cin >> leng; if (cin.fail()) { cout << "Invalid input. The no. of digits should lie between 1 and 20. Please enter again: "; } else if (leng < 1 || leng > 20) { cout << "Invalid input. The no. of digits should lie between 1 and 20. Please enter again: "; } else valid = 1; } char * secnum = new char[leng+1]; if (mode == "1") { for (int s = 0 ; s < leng ; s++) { secnum[s] = rand() % 10 + 48; } secnum[leng] = '\0'; cout << "DEBUGGING S random gen: " << secnum << "DBE" << endl; cout << "Secret number generated!" << endl; } else if (mode == "2") { // For Player 1, who sets the secret number // get the secret number from user cout << "Please enter your secret number for Player 2 to guess: "; while (!getnum_in(secnum, leng)) { cout << "\nInvalid input. Your secret number should consists of exactly " << leng << " digits.\n" << "Please enter your secret number again: "; } // For Player 2, who guesses the secret number cout << ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\nPlayer 2, are you ready to guess? Let\'s start!\n" << "-----A kind reminder: don't scroll to the above to peep the secret number!!!-----\n"; } // "guesses" stores the series of guess numbers by the player // the entry [0] is not used and the first trial is stored at index [1] int guesses_size = 21; // original size of guesses: stores at most 20 trials Guess * guesses = new Guess[guesses_size]; bool won = 0; int trial = 0; // while the secret number is not guessed, ask the player to enter guess numbers repeatedly // IMPORTANT: guesses[0] is NOT used!! The information of the first trial is stored in guesses[1] while (!won) { // if the no. of trials of player exceeds the size where guesses[] can hold if (trial == guesses_size - 1) { cout << "\nYou have tried " << trial << " times already. Do you want to continue? [Y/N]: "; string choice; getline(cin, choice); while (choice!="Y" && choice!="N") { cout << "Invalid choice. Please state whether you want to continue. (Y for yes and N for No): "; getline(cin, choice); } if (choice == "N") { cout << "-----Sorry. You didn\'t get it. The secret number is " << secnum << ".-----" << "\n-----Add oil next time!-----" << endl; break; } else if (choice == "Y") { grow_guesses(guesses, guesses_size, 10); cout << "OK. You are granted 10 more trials. Keep it up!!" << endl; } } trial++; guesses[trial].gnum = new char[leng+1]; cout << "\nPlease enter your guess: "; while (!getnum_in(guesses[trial].gnum, leng)) { cout << "Invalid guess. Your guess number should consists of exactly " << leng << " digits.\n" << "Please enter your guess number again: "; } guesses[trial].A = n_bulls(secnum, guesses[trial].gnum, leng); guesses[trial].B = n_cowsNbulls(secnum, guesses[trial].gnum, leng) - guesses[trial].A; // for determing to use "st" in 1st, 21st, etc.; "rd" in 3rd, 33rd, etc. or "th" in 5th, 6th, 11th, 12th, etc. string nth; switch (trial % 10) { case 1: if (trial % 100 == 11) nth = "th"; else nth = "st"; break; case 2: if (trial % 100 == 12) nth = "th"; else nth = "nd"; break; case 3: if (trial % 100 == 13) nth = "th"; else nth = "rd"; break; default: nth = "th"; } cout << "Your " << trial << nth << " trial is" << ": " << guesses[trial].gnum << " Result: " << guesses[trial].A << 'A' << guesses[trial].B << 'B' << endl; if (guesses[trial].A == 4) { cout << "-----Congratulations! You\'ve guessed it! The secret number is " << secnum << ".-----" << "\n-----You took " << trial << " trials to guess the correct number.-----" << endl; won = 1; } } cout << "See you again. Byebye!" << endl; for (int t = 1 ; t <= trial ; t++) { delete [] guesses[t].gnum; } delete [] secnum; return 0; }
Write, Run & Share C++ code online using OneCompiler's C++ online compiler for free. It's one of the robust, feature-rich online compilers for C++ language, running on the latest version 17. Getting started with the OneCompiler's C++ compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as C++
and start coding!
OneCompiler's C++ online compiler supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample program which takes name as input and print your name with hello.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name;
cout << "Enter name:";
getline (cin, name);
cout << "Hello " << name;
return 0;
}
C++ is a widely used middle-level programming language.
When ever you want to perform a set of operations based on a condition If-Else is used.
if(conditional-expression) {
//code
}
else {
//code
}
You can also use if-else for nested Ifs and If-Else-If ladder when multiple conditions are to be performed on a single variable.
Switch is an alternative to If-Else-If ladder.
switch(conditional-expression){
case value1:
// code
break; // optional
case value2:
// code
break; // optional
......
default:
code to be executed when all the above cases are not matched;
}
For loop is used to iterate a set of statements based on a condition.
for(Initialization; Condition; Increment/decrement){
//code
}
While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.
while (condition) {
// code
}
Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.
do {
// code
} while (condition);
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Function gets run only when it is called.
return_type function_name(parameters);
function_name (parameters)
return_type function_name(parameters) {
// code
}