× Go Back Go Back to Programming Section Menu Go Back to Home Page
class_Mastermind.h
/**************************************************************************************************/
/*               File Name: class_Mastermind.h               Written by: Koral Eren               */
/**************************************************************************************************/
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <string>

using namespace std;

class Mastermind{
    private:
        string code; //4 digit code will be stored in this string
        string User_guess; //4 digit user guess will be stored in this string
    public:
        static int guess_count; //Counter to hold how many guesses were made.

        Mastermind() // Constructor that initializes the code with first possible value: 1023
        {            // This constructor also prints the welcome message every time an
                     // object from Mastermind class is created.
          code = "1023";
          print_welcome_message();
        }

        ~Mastermind()
        {
            // Destructor. Useful if a menu is implemented for multiple games of Mastermind
        }

        void holdNumber() //Holds a valid code
        {
           srand(time(NULL)); // Seeding time each time code is run so that the serie of numbers
                              // generated by rand() becomes different.
           while (true)
           {

                int temp = ((rand()%9)*1000+(rand()%9)*100+(rand()%9)*10+(rand()%9))%8854+1023;
                //Rand returns an integer between 0 to 32767(RAND_MAX). When % used for larger
                //numbers close to 32767, it reduces randomness. So I decided to get a random
                //number for each digit for better randomness.
                //(a number between 0 and 9999)%8854+1023 generates a random number between
                //1023 and 9876.

                for (int i = 0; i<4; i++) //putting generated integer into string
                {
                    code[3-i] = (char)(temp%10+48);//48 is the ascii value for 0 as char
                                                  //1583 % 10 = 3, put 3 into code[3]
                    temp /= 10; // Throws out a digit. Integer division rounds the decimal.
                                // 1583 / 10 = 158.3 but 158 since its type is int.
                }

                if (code[0] == code [1]) //These if statements check whether the code generated consists of
                    continue;            //unique numbers or not. If similarity found, it will go to the beginning of
                                         //the while loop and will get another random number. This will continue until
                if (code[0] == code [2]) //all unique code found.
                    continue;

                if (code[0] == code [3])
                    continue;

                if (code[1] == code [2])
                    continue;

                if (code[1] == code [3])
                    continue;

                if (code[2] == code [3])
                    continue;


                break;//If all the conditions above resulted as false, then I found a valid code
                      //I can get out of the infinite while loop.
           }
        }

        void check(string User_guess)
        {
            while (true)
            {
                 /*
                    These if statements check whether the code generated consists of
                    unique numbers or not. If similarity found, they will output an error
                    message and they return by calling check (itsself) again. Check will call
                    get_code_from_user. The code will be then returned to check as input.

                    The string User_guess here is a different string from User_guess declared above.
                    All operations here are done on this local User_guess string. Only get_code_from_user
                    modifies string User_guess that was declared as private.

                    I didn't use pass by reference following the input style used in the PDF.
                 */


                if (User_guess[0] == User_guess[1])
                {
                    cout << "Please Enter a valid guess\n"; //If similarity found, prints message
                    return check(get_code_from_user());     //function calls itsself by asking user
                }                                           //another code and checks it with comp. guess
                if (User_guess[0] == User_guess[2])
                {
                    cout << "Please Enter a valid guess\n";
                    return check(get_code_from_user());
                }

                if (User_guess[0] == User_guess[3])
                {
                    cout << "Please Enter a valid guess\n";
                    return check(get_code_from_user());
                }

                if (User_guess[1] == User_guess[2])
                {
                    cout << "Please Enter a valid guess\n";
                    return check(get_code_from_user());
                }

                if (User_guess[1] == User_guess[3])
                {
                    cout << "Please Enter a valid guess\n";
                    return check(get_code_from_user());
                }

                if (User_guess[2] == User_guess[3])
                {
                    cout << "Please Enter a valid guess\n";
                    return check(get_code_from_user());
                }

                break;
            }

            //If User_guess made till here, then it is a valid guess. Same guess might be done before
            //but its users responsibility to not make the same guess twice or more.

            if (User_guess == code)//Check whether two strings are same using operator overloading.
            {
                cout << "You solved it!" << endl; //If code equals users guess then User found the code.

                cout << "\nPress [enter] to exit game...";
                getchar();

                exit(EXIT_SUCCESS);//End program exit(0), game finished. Exit terminates program
                //in any code block.
            }

            if(User_guess[0] == code[0]) //The first 4 if below checks for right number, right place
                cout << "+";

            if(User_guess[1] == code[1])
                cout << "+";

            if(User_guess[2] == code[2])
                cout << "+";

            if(User_guess[3] == code[3])
                cout << "+";

            //The last 4 if checks for right number, wrong place
            //find returns npos (-1) if it can't find the location.
            //These conditions also check if index returned by find isn't right location

            if(code.find(User_guess[0])!= string::npos && code.find(User_guess[0]) != 0)
                cout << "-";

            if(code.find(User_guess[1])!= string::npos && code.find(User_guess[1]) != 1)
                cout << "-";

            if(code.find(User_guess[2])!= string::npos && code.find(User_guess[2]) != 2)
                cout << "-";

            if(code.find(User_guess[3])!= string::npos && code.find(User_guess[3]) != 3)
                cout << "-";

            cout << endl;
        }

        void writeNumber() //Displays number to the user
        {
            cout << "The guess of the computer was: " << code << endl;
        }

        void print_welcome_message() //prints welcome message shown in the PDF.
        {
            cout << "Welcome to Mastermind!" << endl;
            cout << "I'm thinking of a 4 digit code, with numbers between 0 and 9" << endl;
            cout << "Dublicate values are not allowed." << endl;
            cout << "Can you break the code in just 10 guesses?" << endl;
        }

        const string get_code_from_user() //Gets input from user to the string and parses it.
        {

            while (true)
            {
                cout << "Guess " << guess_count << ": ";
                getline(cin, User_guess); //Similar to cin but doesn't stop at whitespace
                //All the junk user enters will be saved in the User_guess string.

                if (User_guess.length() != 4) // Checking for the number of chars
                {
                    cout << "Please Enter a valid guess\n";
                    continue;
                }

                else
                {
                    unsigned int i;

                    for(i = 0; i < User_guess.length(); i++)
                    {
                        //Checks for nums between 0 and 9 or 1 and 9 for 1st digit
                        if (i == 0)
                        {
                            if(User_guess[i] < '1' || User_guess[i] > '9')
                            {
                            cout << "Please Enter a valid guess\n";
                            break;
                            }
                        }
                        else if(User_guess[i] < '0' || User_guess[i] > '9')
                        {
                            cout << "Please Enter a valid guess\n";
                            break;
                        }
                    }

                    if (i!= 4) // i != 4 means there was a problem above: start all over
                        continue;
                }

                break;
            }

            return User_guess; //returns the User_guess declared in line 14 with its updated value
        }
};

main.cpp
/****************************************************************************************/
/*               File Name: main.cpp               Written by: Koral Eren               */
/****************************************************************************************/
#include <iostream>

#include "class_Mastermind.h"

using namespace std;

int Mastermind::guess_count = 1; //Initializes the static integer counter

int main()
{
    Mastermind mas; //Creates a new game (a new object from class Mastermind):

    mas.holdNumber(); //Computer holds a number

    while (Mastermind::guess_count <= 10) //User has 10 guesses. While less than 10 guesses are made do:
    {
        mas.check(mas.get_code_from_user()); //Gets a code from user and compares with code holded.
        Mastermind::guess_count ++; //Increments guess counter
    }

    cout << "\n-----GAME OVER-----\nYou ran out of guesses" << endl;

    mas.writeNumber(); //Guesses are over so time to print the number computer holded.

    cout << "\nPress [enter] to exit game...";
    getchar();

    return 0;
}