Thursday, 29 September 2016

Chapter 6 // Exercise 8 - Principles & Practice Using C++

In all these exercises I am using Visual Studio Community 2015 and the header file "std_lib_facilities.h" which can be found here:


http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h


My version is spelt differently so adjust the code accordingly if copying and pasting.


Chapter 6 // Exercise 8

Redo the "Bulls & Cows" game from exercise 12 in Chapter 5 to use four letters rather than four digits.



#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;

void getSeed();
void printRules();
void startGame();
void getLetters();
void compareLetters();
char assignLoop();
vector<char> fourLetters{ 0,0,0,0 };
vector<char> guess{ 0,0,0,0 };

int main()
try
{
char loop = 'y';

while (loop == 'y')
{
//get number for seed  & assign letters to fourLetters
getSeed();

//print rules of game
printRules();

//begin the game and keep going till user decides to quit
startGame();

//ask if you want to play again
loop = assignLoop();
}

keep_window_open();

return 0;
}


catch (exception& e)
{
cerr << "Error: " << e.what() << '\n';
keep_window_open();
return 1;
}

//produces random number which corralates to ASCII lower case alphabet
char getRandLetter()
{
char randNum = (rand()%(122 - 97 + 1)) + 97; // produces random number between 97 and 122
return randNum;
}

//get seed for rand num and assign letters to comp's four letters
void getSeed()
{
cout << "Please enter a number(any number):\n";
int n;
cin >> n;

srand(n);
for (int i = 0; i < fourLetters.size(); ++i)
{
fourLetters[i] = getRandLetter();
}

sort(fourLetters); //to compare if any are the same

for (int i = 1; i < fourLetters.size(); ++i)
{
while (fourLetters[i] == fourLetters[i - 1])
{
fourLetters[i] = getRandLetter();
}
}

}



void printRules()
{
cout << "//RULES//";
cout << "\nLets Play Bulls & Cows.\n";
cout << "Guess the 4 letters.\n";
cout << "If a letter is right in the right position you will get a bull.\n";
cout << "If the letter is right in the wrong position you will get a cow.\n";
cout << "\nGuess a letter a-z. Each letter must be different and lower case. \n\n";
}

void startGame()
{
while (guess != fourLetters)
{
//get user letters
getLetters();
//compare user and random letters for bulls & cows
compareLetters();
}
}

void getLetters()
{

vector<string>n = { "1st Letter: ", "2nd Letter: ", "3rd Letter: ", "4th Letter: " };

for (int i = 0; i < 4; ++i)
{
cout << n[i];
char letter;
cin >> letter;

if (letter < 'a' || letter > 'z')
error("You can only use lower case.\n");

guess[i] = letter;
}

cout << "Your guess: ";

for (int i = 0; i < 4; ++i)
{
cout << guess[i] << " ";
}

cout << '\n';
}

void compareLetters()
{
for (int i = 0; i < 4; ++i)
{
for (int n = 0; n < 4; ++n)
{
if (guess[i] == fourLetters[n])
{
if (i == n)
cout << "1 Bull(" << guess[i] << ")";
else
cout << "1 Cow(" << guess[i] << ")";
}
}
}
}

char assignLoop()
{
cout << "\n\nCongratz! You did it!\n";
cout << "Would you like to play again? y / n:\n";
char l;
cin >> l;
while (l != 'y' && l != 'n')
{
cout << "Invalid answer, try again. y / n:\n";
cin >> l;
}

return l;
}



This one took a while as I figured out how to perfect a few things. The original exercise had you guess a number 1 - 9, this one a letter a -z. Since int and char are interchangeable I simply changed most of the code to char however when it came to randomizing what letters you would get I had to find a new function.


The one I've got accepts a max and a min value, for us we want between 97 and 122 as these are the numbers for the characters a - z. I then just assigned one of the generated numbers to the guess vector. When looking to see if any of them were the same I realised my prior function wasn't exactly perfect and would sometimes allow the same numbers. I've corrected it on this one by sorting them first. This does give the letters some predictability by putting them in order however not all the time as if some are the same they will be changed to another generated number.



6 comments:

  1. My code:

    #include "../../std_lib_facilities.h"

    int main()
    try
    /*Redo the “Bulls and Cows” game from exercise 12 in Chapter 5 to use four letters rather than four digits.*/

    {
    vector fourLetters = { 'a','b','c','d' };
    vector guess = { 'a','a','a','a' };

    cout << "Lets Play Bulls & Cows.\n";
    cout << "Guess the 4 letters. If a digit is right in the right position you will get a bull.\n";
    cout << "If the digit is right in the wrong position you will get a cow.\n"
    << "Example Guess: a g d b (Each number is seperated by space! Press enter after entering all 4 numbers.)";

    cout << "\n\nGuess a letter a to z. Each letter must be different: \n";

    // Getting random letters
    srand(time(NULL));
    char pc1 = rand() % (122-97+1) + 97; // random letters between 97 to 122 aka a to z
    char pc2 = rand() % (122 - 97 + 1) + 97;
    char pc3 = rand() % (122 - 97 + 1) + 97;
    char pc4 = rand() % (122 - 97 + 1) + 97;


    while (guess != fourLetters)
    {

    fourLetters[0] = pc1;
    fourLetters[1] = pc2;
    fourLetters[2] = pc3;
    fourLetters[3] = pc4;

    sort(fourLetters);

    // deleting repeated letters
    for (int i = 1; i < fourLetters.size(); ++i)
    {
    while (fourLetters[i] == fourLetters[i - 1])
    {
    fourLetters[i] = randint(9);
    }
    }

    for (int i = 0; i < fourLetters.size(); ++i)
    {

    char digit;
    cin >> digit;

    if (digit >= 'a' && digit <= 'z')


    guess[i] = digit;

    else error("You can only use a to z.\n");
    }

    for (int i = 0; i < guess.size(); ++i)
    {
    for (int n = 0; n < guess.size(); ++n)
    {
    if (guess[i] == fourLetters[n])
    {
    if (i == n)
    cout << "1 Bull \n";
    else
    cout << "1 Cow \n";
    }
    }
    }
    }

    cout << "\nCongratz! You did it!\n";


    keep_window_open("~");
    }

    catch (exception& e)
    {
    cerr << "error: " << e.what() << '\n';
    keep_window_open();
    return 1;
    }
    catch (...) {
    cerr << "Oops: unknown exception!\n";
    keep_window_open();
    return 2;
    }

    ReplyDelete
  2. Yep this works! You have missed out what type the vectors are at the top though so this code won't compile but that's an easy fix.

    I will say though it's just a little confusing to play as you get no feedback after the four letters have been inputted. For example if you don't get a bull or a cow nothing happens and it looks like the game has broken lol. I know it's early days but if there's one thing my lecturers convey the most it's user functionality. The user will always find a way to do something that you didn't expect.

    But other than that, good job!

    ReplyDelete
  3. Well, I did not miss the vector type. The problem is with these blogspot comment boxes. They erase anything which comes between these brackets "<" and ">".

    "I will say though it's just a little confusing to play as you get no feedback after the four letters have been inputted. For example if you don't get a bull or a cow nothing happens and it looks like the game has broken lol. I know it's early days but if there's one thing my lecturers convey the most it's user functionality. The user will always find a way to do something that you didn't expect."

    I don't have teachers. I am learning how to program on my own. and Yeah, this is true... I will try to pop out some words when the user doesn't get a bull or a cow. Thanks...!!

    ReplyDelete
  4. ummm... I don't see any solutions after exercise 6 of chapter 8. I know the university is eating up all your time but I would be very happy if you could post the solutions of other chapters too..

    I love to read your codes. They always help me when I don't find a way to proceed.

    Parry, you are a great programmer!

    ReplyDelete
  5. Replies
    1. Thank you, I'm trying my best, and before September I had no teachers either I had no teachers until around chapter 7 but even then they have other things to do than help me with this book lol.

      As for time, I really struggle, I just handed in 2 assignments that were due before Christmas, and I've now got 2 exams (maths and programming) a week after I go back in January, along with another assignment to hand in that week. Along with work as well, I'm finding it hard to balance my time but I would like to return to the chapter exercises at some point as this book has really helped my learning.

      Delete