In: Computer Science
(LANGUAGE C++)
This time, you will finish the program so that the user gets to solve the puzzle. You will also use header files and introduce classes into your program. We will follow the draft start to how to incorporate classes.
Here are the requirements:
·In the file quotes.h, define the Quotes class:
o Quotes(string filename) // a constructor to load quotes from the named file into a vector
o The vector should be a field of the class so it will be saved for calls to getQuote() below
o string getQuote() // return random string from vector
o because the vector saves all quotes, you do not need to reload the quotes from the file
·translator.h defines the Translator class:
o As noted in class, we can use this class to both encrypt the quote as well as maintain the user’s current guesses as to how to decrypt the puzzle
o For the user’s current guess, we start with mapping every letter to itself
o To make this easier, define a default constructor (no parameters) which creates this mapping
§ The mapping should be stored as a field of the Translator class
o Implement a function randomize() that does not return anything and randomizes the mapping of letters (creates the code – only use this once per puzzle to create it)
§ This is pretty much going to be the code from genCode(), but the Translator class stores the array (or whatever you want to use for the mapping), so:
·don’t create a new array
·don’t return the array
o string translate(string txt) – this replaces encrypt() from hw4. As for randomize(), the main difference is that you are not passing in the code since Translator already has it
§ call this each time the user changes the mapping for a letter
o Support a function to change the translator for one letter
§ This is a new function to allow the user to update the current guess
·Your hw5.cpp now just has #include’s for the above header files and main()
o main() should display an opening message and prompt for a file name for the file of quotes
o The main loop should keep going until the user wants to quit
§ Each iteration gets a new random quote, then lets the user try to solve it
§ Solving involves changing the user’s guess at the code one letter at a time and showing the user the effect of the change
§ It’s not required, but you can use a special non-letter character to quit before solving the puzzle – you can use exit(0) (defined in <cstdlib>) to quit the program, or the break statement to continue with a new puzzle
§ If the user solves the puzzle (matches the quote successfully), congratulate them, ask if they want to continue, and if so, generate a new puzzle to solve
·A sample run is attached
SAMPLE RUN
Cryptoquote solving game Please enter name of file with quotes: quotes1.txt Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Enter a letter to substitute: b Enter the letter to replace b: i Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I awcl wyewio ewjplr pn ul onhlunri, ufp I oll jne I oanfyr awcl ullj hngl oklmivim. Yiyi Pnhyij Enter a letter to substitute: l Enter the letter to replace l: e Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I awce wyewio ewjper pn ue onheunri, ufp I oee jne I oanfyr awce ueej hnge okemivim. Yiyi Pnhyij Enter a letter to substitute: o Enter the letter to replace o: s Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I awce wyewis ewjper pn ue snheunri, ufp I see jne I sanfyr awce ueej hnge skemivim. Yiyi Pnhyij Enter a letter to substitute: j Enter the letter to replace j: n Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I awce wyewis ewnper pn ue snheunri, ufp I see nne I sanfyr awce ueen hnge skemivim. Yiyi Pnhyin Enter a letter to substitute: n Enter the letter to replace n: o Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I awce wyewis ewnper po ue soheuori, ufp I see noe I saofyr awce ueen hoge skemivim. Yiyi Pohyin Enter a letter to substitute: e Enter the letter to replace e: w Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I awce wywwis wwnper po ue soheuori, ufp I see now I saofyr awce ueen hoge skemivim. Yiyi Pohyin Enter a letter to substitute: a Enter the letter to replace a: h Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I hwce wywwis wwnper po ue soheuori, ufp I see now I shofyr hwce ueen hoge skemivim. Yiyi Pohyin Enter a letter to substitute: f Enter the letter to replace f: u Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I hwce wywwis wwnper po ue soheuori, uup I see now I shouyr hwce ueen hoge skemivim. Yiyi Pohyin Enter a letter to substitute: y Enter the letter to replace y: l Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I hwce wlwwis wwnper po ue soheuori, uup I see now I shoulr hwce ueen hoge skemivim. Lili Pohlin Enter a letter to substitute: r Enter the letter to replace r: d Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I hwce wlwwis wwnped po ue soheuodi, uup I see now I should hwce ueen hoge skemivim. Lili Pohlin Enter a letter to substitute: w Enter the letter to replace w: a Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I hace alwais wanped po ue soheuodi, uup I see now I should hace ueen hoge skemivim. Lili Pohlin Enter a letter to substitute: c Enter the letter to replace c: v Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have alwais wanped po ue soheuodi, uup I see now I should have ueen hoge skemivim. Lili Pohlin Enter a letter to substitute: u Enter the letter to replace u: v Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have alwais wanped po ve sohevodi, vup I see now I should have veen hoge skemivim. Lili Pohlin Enter a letter to substitute: u Enter the letter to replace u: b Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have alwais wanped po be sohebodi, bup I see now I should have been hoge skemivim. Lili Pohlin Enter a letter to substitute: h Enter the letter to replace h: m Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have alwais wanped po be somebodi, bup I see now I should have been moge skemivim. Lili Pomlin Enter a letter to substitute: g Enter the letter to replace g: r Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have alwais wanped po be somebodi, bup I see now I should have been more skemivim. Lili Pomlin Enter a letter to substitute: k Enter the letter to replace k: p Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have alwais wanped po be somebodi, bup I see now I should have been more spemivim. Lili Pomlin Enter a letter to substitute: i Enter the letter to replace i: y Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have always wanped po be somebody, bup I see now I should have been more spemivim. Lily Pomlin Enter a letter to substitute: p Enter the letter to replace p: t Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have always wanted to be somebody, but I see now I should have been more spemivim. Lily Tomlin Enter a letter to substitute: m Enter the letter to replace m: c Puzzle: B awcl wyewio ewjplr pn ul onhlunri, ufp B oll jne B oanfyr awcl ullj hngl oklmbvbm. Ybyi Pnhybj Current: I have always wanted to be somebody, but I see now I should have been more specivic. Lily Tomlin Enter a letter to substitute: v Enter the letter to replace v: f You solved it! Congratulations! Do you want to continue? (y/n) n
PROVIDED CODE
#include <iostream> #include <fstream> #include <cstdlib> #include <vector> #include <string> using namespace std; // Covers the printable characters, // and makes working with the code table easier const int NUM_CHAR_VALUES = 128; const int NUM_LETTERS = 26; /** Read lines from the chosen file into the vector */ void readQuotes(string filename, vector<string> & quotes) { ifstream quoteFile(filename); string nextLine; // Note that this loop assumes there are no empty lines, // even at the end while (getline(quoteFile, nextLine)) { quotes.push_back(nextLine); } } /** Return random quote from vector */ string getQuote(vector<string> & quotes) { return quotes[rand() % quotes.size()]; } /** Return random code array */ char * genCode() { char * code = new char[NUM_CHAR_VALUES]; bool used[NUM_CHAR_VALUES]; for (int i = 0; i < NUM_CHAR_VALUES; ++i) used[i] = false; for (char ch = 'a'; ch <= 'z'; ++ch) { char code_char; do { code_char = rand() % NUM_LETTERS + 'a'; } while (used[static_cast<int>(code_char)]); code[static_cast<int>(ch)] = code_char; code[static_cast<int>(toupper(ch))] = toupper(code_char); used[static_cast<int>(code_char)] = true; } return code; } /** Return encrypted form of txt param using code array to translate Code array is defined for upper and lower-case ASCII values, but other elements are not initialized */ string encrypt(string txt, char code[]) { string result = txt; for (unsigned int ch = 0; ch < txt.size(); ++ch) if (isalpha(txt[ch])) result[ch] = code[static_cast<int>(txt[ch])]; return result; } // Display translations for letters // assumes 128 char table in code parameter // code is assumed to be for ASCII void codeLetters(char code[]) { cout << "Letters are encoded as follows: " << endl; for (char ch = 'a'; ch <= 'z'; ch++) { cout << ch << " -> " << code[static_cast<int>(ch)] << endl; } } int main() { string filename; vector<string> quotes; const char YES = 'y'; char repeat; cout << "Driver to test encryption code, version 2" << endl << endl; cout << "Please enter name of file with quotes: "; cin >> filename; readQuotes(filename, quotes); srand(3); // could use time(0) as param to get random results each time, but // fixed seed should make it easier to debug our code do { char * code = genCode(); codeLetters(code); string txt = getQuote(quotes); string puzzle = encrypt(txt, code); cout << "Original : " << txt << endl; cout << "Encrypted: " << puzzle << endl; cout << "Do you want to continue? (y/n) "; cin >> repeat; } while (YES == repeat); return 0; }
solution:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
#include <cstring>
using namespace std;
// Covers the printable characters,
// and makes working with the code table easier
const int NUM_CHAR_VALUES = 128;
const int NUM_LETTERS = 26;
/** Read lines from the chosen file into the vector
*/
void readQuotes(string filename, vector<string> & quotes) {
ifstream quoteFile(filename);
string nextLine;
// Note that this loop assumes there are no empty lines,
// even at the end
while(getline(quoteFile, nextLine)) {
quotes.push_back(nextLine);
}
}
/**
Return random quote from vector
*/
string getQuote(vector<string> & quotes) {
return quotes[rand() % quotes.size()];
}
/** Return random code array
*/
char * genCode() {
char * code = new char[NUM_CHAR_VALUES];
bool used[NUM_CHAR_VALUES];
for (int i = 0; i < NUM_CHAR_VALUES; ++i)
used[i] = false;
for (char ch = 'a'; ch <= 'z'; ++ch) {
char code_char;
do {
code_char = rand() % NUM_LETTERS + 'a';
} while (used[static_cast<int>(code_char)]);
code[static_cast<int>(ch)] = code_char;
code[static_cast<int>(toupper(ch))] = toupper(code_char);
used[static_cast<int>(code_char)] = true;
}
return code;
}
/** Return encrypted form of txt param using
code array to translate
Code array is defined for upper and lower-case
ASCII values, but other elements are not initialized
*/
string encrypt(string txt, char code[]) {
string result = txt;
for (unsigned int ch = 0; ch < txt.size(); ++ch)
if (isalpha(txt[ch]))
result[ch] = code[static_cast<int>(txt[ch])];
return result;
}
// Display translations for letters
// assumes 128 char table in code parameter
// code is assumed to be for ASCII
void codeLetters(char code[]) {
cout << "Letters are encoded as follows: " << endl;
for (char ch = 'a'; ch <= 'z'; ch++) {
cout << ch << " -> " << code[static_cast<int>(ch)] << endl;
}
}
int main()
{
string filename;
vector<string> quotes;
char letter[4],rep[4],upp[4];
string puzzle1;
cout << "Cryptoquote solving game" << endl << endl;
cout << "Please enter name of file with quotes: ";
cin >> filename;
readQuotes(filename, quotes);
srand(3);
char * code = genCode();
codeLetters(code);
string txt = getQuote(quotes);
string puzzle = encrypt(txt, code);
cout << "Puzzle: " << puzzle << endl;
puzzle1 = puzzle;
cout << "Current : " << puzzle1 << endl;
do{
cout<<"Enter a letter to substitute: ";
cin>>letter;
cout<<"Enter the letter to replace"<<letter<<": ";
cin>>rep;
for(int j=0;puzzle1[j]!='\0';j++){
if((puzzle1[j]>='A') && (puzzle1[j]<='Z'))
{
if(puzzle1[j]==letter[0])
{
puzzle1[j]=toupper(rep[0]);
}
}
else if(puzzle1[j] >='a' && puzzle1[j] <='z')
{
if(puzzle1[j]==letter[0]){
puzzle1[j]=rep[0];
}
}
}
cout << "Puzzle: " << puzzle << endl;
cout << "Current : " << puzzle1 << endl;
}while(strcmp (txt.c_str(), puzzle1.c_str()));
return 0;
}