how do I compare a character with a string? - c++

#include <iostream>
#include <string>//needed to make string array
#include <fstream>//Needed for redaing in from external file
#include <cstdlib>//needed for rand() function (for random word)
#include <ctime>//needed for time() funtion to seed rand()
using namespace std;
/*
April 25,2020
This program will take read in a random word from an external file and use it for a game of hang man */
void greeting();
void wordPick();
int main()
{
char playAgain;
int tries;
char playerGuess;
string secretWord;
greeting();
ifstream inFile("randwords.txt");
if (inFile.is_open())
{
string wordlist[10];
for(int i = 0; i < 10; ++i)
{
inFile >> wordlist[i];
}
srand(time(0));
string secretword = wordlist[rand() % 10];
cout << secretword << endl;
inFile.close();
}
//wordPick();
//ask user to guess a letter
cout << "Please guess a letter: " << endl;
cin >> playerGuess;
if (playerGuess == secretWord[0])
{
cout << "Thats correct!" << secretWord [0];
}
else if (playerGuess == secretWord[1])
{
cout << "thats correct!" << secretWord[1];
}
else if (playerGuess == secretWord[2])
{
cout << "Thats correct!" << secretWord[2];
}
cout << "Do you want to play again? Y or N: ";
cin >> playAgain;
while (playAgain != 'Y' && playAgain != 'y' && playAgain != 'N' && playAgain != 'n')
{
cout << "Invalid, please enter Y or N: ";
cin >> playAgain;
}
return 0;
}
void wordPick()//reads in external file and puts it in an array for a library of words to randomly choose
{
ifstream inFile("randwords.txt");
if (inFile.is_open())
{
string wordlist[10];
for(int i = 0; i < 10; ++i)
{
inFile >> wordlist[i];
}
srand(time(0));
string secretword = wordlist[rand() % 10];
// cout << secretword << endl;
inFile.close();
}
}
void greeting()//welcomes the player to the game and starts the game
{
string name;
cout << "Hello, Player welcome to Hangman! " << endl;
cout << "What should I call you?" << endl;
cin >> name;
cout << "Hello " << name << ", in this game you will try to guess a random 3 letter word." << endl;
cout << "You will have at least 6 ties to guess the word or else the drawing will complete. Good luck!" << endl;
What I am attempting to do is to check if the char playerGuess is one of the characters in string secretWord, but it isn't outputting the letter even if it is correct. Maybe there is an easier way to compare that I'm just missing?
I thought since this still compares that it should work, but it's just ending the program after guessing the letter.

You assigned the randomly chosen word to secretword (with small w), but the judge is based on secretWord (with large W), to which no word is assigned.
The part
string secretword = wordlist[rand() % 10];
cout << secretword << endl;
should be
secretWord = wordlist[rand() % 10];
cout << secretWord << endl;
Also note that you mustn't declare secretWord in the if block, or the assignment won't be visible to the judge part.

Related

When I made a do/while loop in C++ in order to allow a player to play the game again, the game only loops once, how do I fix this?

char playAgain;
do
{
srand(static_cast<unsigned int>(time(0)));
random_shuffle(words.begin(), words.end());
const string THE_WORD = words[0]; //word to guess
int wrong = 0; //number of incorrect guesses
string soFar(THE_WORD.size(), '-'); //word guessed so far
string used = ""; //letter alrdy guessed
cout << "Welcome to Hangman. Good luck!\n";
while ((wrong < MAX_WRONG) && (soFar != THE_WORD))
{
cout << "\n\nYou have " << (MAX_WRONG - wrong);
cout << " incorrect guesses left.\n";
cout << "\nYou've used the following letters:\n" << used << endl;
cout << "\nSo far, the word is:\n" << soFar << endl;
char guess;
cout << "\n\nEnter you guess: ";
cin >> guess;
guess = toupper(guess); //make uppercase since secret word in uppercase
while (used.find(guess) != string::npos)
{
cout << "You've already guessed " << guess << endl;
cout << "Enter you guess: ";
cin >> guess;
guess = toupper(guess);
}
used += guess;
if (THE_WORD.find(guess) != string::npos)
{
cout << "That's right! " << guess << " is in the word.\n";
//update soFar to include newly guessed letter
for (int i = 0; i < THE_WORD.length(); ++i)
{
if (THE_WORD[i] == guess)
{
soFar[i] = guess;
}
}
}
else
{
cout << "Sorry, " << guess << " isn't in the word.\n";
++wrong;
}
}
//shut down
if (wrong == MAX_WRONG)
{
cout << "\nYou've been hanged!";
}
else
{
cout << "\nYou guessed it!";
}
cout << "\nThe word was " << THE_WORD << endl;
cout << "\nPlay again? < Y , N >\n";
cin >> playAgain;
} while ((playAgain == 'Y') || (playAgain == 'y'));
return 0;
Hello, I have tried to make this game be a game which can be repeatable. I succeeded, but noticed that the game only loops once when the player selects either Y or y. This is obviously because playAgain now retains that value. How do I fix this so that playAgain "forgets" what the user input when the game begins again? Thank you for your help.
The only way I see that the loop won't work is if you have characters in the buffer that you haven't read yet, so clear the line with cin.ignore(). You need to #include <limits> for this to work:
...
cout << "\nPlay again? < Y , N >\n";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
if(!(cin >> playAgain)) break; // if extraction fails, we're probably at EOF
) while(...);

How create a guessing game with letters. For example I need to guess a letter from the word fallout. Which functions are useful

I am creating a guessing game. I need to ask the user to input a letter from a word like fallout. The have that letter they had inputted be correct or incorrect. I am using functions like srand(time(NULL)), rand(), psw.length. once the user inputs a letter and if they are wrong a life is deducted live--.
If they get it right they can move on to the next question with a full 5 lives. I don't know what functions I am missing if I need an array etc.
I have tried applying the rand() && psw.length together in order to at least try to randomize the letter choice so that the user might have a chance to guess the random letter from the word "fallout" but to no avail.
I have made some progress I started with the numerical portion of the code instead of focusing on the whole thing at once. Then now I have to start on the alphabetical portion of the code itself I am organizing my thoughts to simpler terms.
Now onto the alphabetical functions of the code....I now need to randomize letters for the user to answer with the correct letter of the word using functions.
I am trying to make the second answer2 = rand() % word2.length function work could anyone help me here it automatically runs the code giving a positive score to the user....
include <iostream>
#include <string>
#include <time.h>
#include <cstdlib>
using namespace std;
int lives = 3;
int guess;
int guess2;
int answer = 0;
int answer2 = 0;
int i;
int score = 0;
char letter, letter2;
string word = "fallout";
string word2 = "psw";
int main()
{
srand(time(NULL));
cout << "Welcome to the guessing game!" << endl;
cout << "*****************************" << endl;
system("PAUSE");
system("cls");
answer = rand() % 2 + 1;
lives = 3;
do {
cout << "What is a number between 1 and 2? Can you guess it in\n" << endl << lives << endl << "tries?" << endl;
cin >> guess;
if (guess == answer)
{
cout << "You won!!" << endl;
score++;
}
else if (lives == 0)
{
cout << "Your score" << endl << score;
system("PAUSE");
return 0;
}
else
{
cout << "Incorrect try again!" << endl;
lives--;
system("PAUSE");
system("cls");
}
} while (guess != answer);
cout << "You won your score is" << score << endl;
system("PAUSE");
system("cls");
answer = rand() % 3 + 1;
lives = 3;
do {
cout << "What is a number between 1 and 3? Can you guess it in" << endl << lives << "tries?" << endl;
cin >> guess;
if (guess == answer)
{
cout << "You won!!" << endl;
score++;
}
else if (lives == 0)
{
cout << "Your score" << endl << score;
system("PAUSE");
return 0;
}
else
{
cout << "Incorrect try again!" << endl;
lives--;
system("Pause");
system("cls");
}
} while (guess != answer);
cout << "You won your score is" << score << endl;
system("PAUSE");
system("cls");
answer = rand() % 5 + 1;
lives = 3;
do {
cout << "What is a number between 1 and 5? Can you guess it in\n" << endl << lives << "tries?" << endl;
cin >> guess;
if (guess == answer)
{
cout << "You won!!" << endl;
score++;
}
else if (lives == 0)
{
cout << "Your score" << endl << score;
system("PAUSE");
return 0;
}
else
{
cout << "Incorrect try again!" << endl;
lives--;
system("cls");
}
} while (guess != answer);
cout << "You won your score is " << score << endl;
system("PAUSE");
system("cls");
answer = rand() % word.length();
lives = 3;
do
{
cout << "Select the correct letter in the word '" << word << "': ";
cin >> guess;
if (guess == letter)
{
cout << "You Won!" << endl;
score++;
}
else if (lives == 0)
{
cout << "The correct answer is:" << endl;
cout << word[answer];
}
else
{
cout << "Incorrect Try Again" <<
lives--;
}
} while (guess != letter);
cout << "You won your score is " << score << endl;
system("PAUSE");
system("cls");
How can I make this code run well can anybody help me I just need advice on this function here... It keep giving the user a score++ automatically. Is their a simple fix for this. I am a rookie so if there is a basic trick here it would help!
answer2 = rand() % word2.length();
lives = 3;
do
{
cout << "Select the correct letter in the word '" << word2 << "': ";
cin >> guess2;
if (guess2 == letter2)
{
cout << "You Won!" << endl;
score++;
}
else if (lives == 0)
{
cout << "The correct answer is:" << endl;
cout << word2[answer2];
}
else
{
cout << "Incorrect Try Again" <<
lives--;
}
} while (guess2 != letter2);
cout << "You won your score is " << score << endl;
system("PAUSE");
system("CLS");
}
First of all, in C++ you have some different ways to randomize a value. rand() highly not recommended.
From cppreference:
There are no guarantees as to the quality of the random sequence produced. In the past, some implementations of rand() have had serious shortcomings in the randomness, distribution and period of the sequence produced (in one well-known example, the low-order bit simply alternated between 1 and 0 between calls). rand() is not recommended for serious random-number generation needs, like cryptography.
Instead, you can use:
#include <random>
int main() {
/*...*/
// Seed with a real random value, if available
std::random_device r;
// Choose a random mean between 1 and 6
std::default_random_engine e1(r());
std::uniform_int_distribution<int> uniform_dist(1, 7);
answer = uniform_dist(e1);
/*...*/
return 0;
}
Read more about random: https://en.cppreference.com/w/cpp/numeric/random
For loop - Condition problem: for (int i = 0; i < guess; i++) - The condition here seems wrong. Why does this loop runs until i is bigger then the user guess? I think a better way for your target is to use while loop, until the user have no lives:
int lives = 5;
size_t guess_number = 1;
/*...*/
while (lives) {
cout << "Guess" << guess_number++ << endl;
/*...*/
}
Stop the loop: Whenever the user successfully guess the letter (or the letter's place in the word), you might considering random a new letter, a new word, or just stop the game and exit the loop (with break).
The word FALLOUT: Currently, in your code, the word fallout ia a variable name, and not a variable content. start with replacing this name to something like word_to_guess, and put the value fallout into it.
string fallout;
to:
string word_to_guess = "fallout";
Now that you have done it, you can make you code more generic to another words, by choosing a random number between 1 to word_to_guess.size():
std::uniform_int_distribution<int> uniform_dist(1, word_to_guess.size());
Now you want to convert user's guess and computer's guess to letters:
/**
* guess >= 1 - The user have to guess a letter from the beginning of the word (and not before it).
* guess <= word_to_guess.size() - The user can't guess a letter that not exists in the word.
* word_to_guess[guess - 1] == word_to_guess[answer - 1] - Compare the user's letter to the computer's letter
*
* word_to_guess[answer - 1] - You might consider to replace this with word_to_guess[answer], and just random
* a number from 0 to word_to_guess.size() - 1
*/
if (guess >= 1 && guess <= word_to_guess.size() && word_to_guess[guess - 1] == word_to_guess[answer - 1]) {
cout << "You Won" << endl;
break; // Or random new letter/word etc...
}

How to limit character input "cin" to get just one string

I was writing this code for training, and I'm in a problem where if my user write his name followed by a space and something else, the program will mess up my flow. So it's easier if you try the little program and when it ask for name, put like "Robert Red". The problem occurs just when you put something else after the space, if you input just "Robert" all goes good.
This is the code:
// Description: This is a simple replica of the Japanese game Rock, Paper and
// Scissors.
// Author: Ernesto Campese
// Last Update: 11/04/2018
// Version: 0.0.1
#include "std_lib_facilities.h"
int main() {
string username = "";
char userinput;
int rounds = 0;
int wins = 0;
int draws = 0;
int loses = 0;
int user_secret = 0;
vector<string> options = {"Paper", "Scissors", "Rock"};
cout << "Enter your name: ";
cin >> username;
cout << "Welcome " << username << ", this is the game of Rock, Paper and Scissors.\n";
cout << username << " how many rounds you want to do? ";
cin >> rounds;
if (rounds <= 0) {
cout << "You need to play at least one round!\n";
rounds++;
}
cout << "The game is based on " << rounds << " rounds, you versus the CPU.\n";
cout << "Are you ready? (y/n): ";
cin >> userinput;
if (userinput != 'y') {
cout << "\nThank you.\nProgram Terminated by " << username;
return 0;
}
for(int i = 1; i <= rounds; i++) {
// Title of the rounds
if (i == 1) {
cout << "\nLet's start the first round!\n";
} else {
cout << "Round n. " << i << " begins!\n";
}
// USER makes a move
cout << "Which is your move? (r,p,s): ";
cin >> userinput;
cout << '\n' << username << " says... ";
switch (userinput) {
case 'r':
cout << "Rock\n";
user_secret = 2;
break;
case 'p':
cout << "Paper\n";
user_secret = 0;
break;
case 's':
cout << "Scissors\n";
user_secret = 1;
break;
default:
cout << "something weird...\n";
break;
}
// CPU makes a move
int cpu_secret = rand() % 3;
cout << "CPU says... " << options[cpu_secret] << "!\n";
// The program calculates the result.
if (user_secret == cpu_secret) {
draws++;
cout << username << " and the CPU draws!\n\n";
} else if (user_secret == 0 && cpu_secret == 2) {
wins++;
cout << username << " wins!\n\n";
} else if (user_secret == 1 && cpu_secret == 0) {
wins++;
cout << username << " wins!\n\n";
} else if (user_secret == 2 && cpu_secret == 1) {
wins++;
cout << username << " wins!\n\n";
} else {
loses++;
cout << username << " lose!\n\n";
}
}
cout << "\n\nBattle End!\n";
if (wins > loses) {
cout << username << " won the battle!\n";
} else if (loses > wins) {
cout << username << " lost the battle!\n";
} else {
cout << username << " draws the battle!\n";
}
cout << "Thank you " << username << "!\n";
}
You can try it here: Try me
Thank you!
operator>> stops reading input when it finds a whitespace character.
Use std::getline() to read user input with spaces.
Example using your code:
cout << "Enter your name: ";
getline(cin, username);
If you want the user to be able to type in a name that has spaces in it, use std::getline() instead of operator>>:
getline(cin, username);
Otherwise, if you want the user to enter only 1 word for the name, and you want to ignore anything else the user may enter, use std::cin.ignore():
#include <limits>
...
cin >> username;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Alternatively, you can use std::getline() to read a line, and then use std::istringstream with operator>> to extract the 1st word of the line:
#include <sstream>
...
string line;
getline(cin, line);
istringstream(line) >> username;

How would I create a function that determines whether the users input is one the words included in a vector

I have been trying to create a game of hangman using functions. One that gets the users guess and another function that sees if the users guess is in the word that is created in the vector. Any help on how to get the playersGuess and how to create a function to see if that guess is the word would be appreciated. Code is below.
char playersGuess();
int main()
{
//setup
const int MAX_WRONG = 8; //maximum number of incorrect guesses allowed
vector<string> words; //collection of possible words to guess
words.push_back("GUESS");
words.push_back("HANGMAN");
words.push_back("DIFFICULT");
srand(static_cast<unsigned int>(time(0)));
random_shuffle(words.begin(), words.end());
const string THE_WORD = words[0]; //word to guess
int wrong = 0; //number of incorrect guesses
string soFar(THE_WORD.size(), '-'); //words guessed so far
string used = ""; //letters already guessed
cout << "Welcome to Hangman 2. Good Luck!\n";
//main loop
while ((wrong < MAX_WRONG && soFar != THE_WORD))
{
cout << "\n\nYou have " << (MAX_WRONG - wrong);
cout << " incorrect guesses left.\n";
cout << "\nYou've used the follwoing letters:\n" << used << endl;
cout << "\nSo far, the word is:\n" << soFar << endl;
char guess = playersGuess();
while (used.find(guess) != string::npos)
{
cout << "\nYou've already guessed " << guess << endl;
playersGuess();
}
used += guess;
if (THE_WORD.find(guess) != string::npos)
{
cout << "That's right! " << guess << " is in the word.\n";
//update soFra to include newly guessed letter
for (int i = 0; i < THE_WORD.length(); ++i)
{
if (THE_WORD[i] == guess)
{
soFar[i] = guess;
}
}
}
else
{
cout << "Sorry. " << guess << " isn't in the word.\n";
++wrong;
}
}
//shut down
if (wrong == MAX_WRONG)
{
cout << "\nYou've been hanged!";
}
else
{
cout << "\nYou guessed it!";
}
cout << "\nThe Word was " << THE_WORD << endl;
return 0;
}
char playersGuess()
{
char guess;
cout << "\n\nEnter your guess: ";
cin >> guess;
guess = toupper(guess); //make uppercase since secret word in uppercase
return guess;
}
You can use string::find to search a string for a specific char
char guess; // assume this is already set
std::string answer // this too
if (answer.find(guess) != std::string::npos)
{
// Correct letter!
}
else
{
// They were wrong, add a body part
}
The reason your code isn't working is because you never assign their guess to any variable. guess is a local variable that only exists within playersGuess. You'd have to do
char guess = playersGuess();
while (used.find(guess) != string::npos)
{
// ...
You need to do something with the return of playersGuess(). You are inputting a char, but then effectively throwing it away:
char guess = playersGuess();
// ^^^^^
while (used.find(guess) != string::npos)
{
cout << "\nYou've already guessed " << guess << endl;
guess = playersGuess();
// ^^^^^
}

Get blank line after calling Palindrome function

So I have these two functions at the top of my program:
string deletespaces(string sentence){
sentence.erase(std::remove(sentence.begin(), sentence.end(), ' '), sentence.end());
return sentence;
}
and
string checkpalindrome(string sentence){
deletespaces(sentence);
if (sentence == string(sentence.rbegin(), sentence.rend())){
cout << sentence << " is a palindrome." << endl;
}
if(sentence != string(sentence.rbegin(), sentence.rend())){
cout << sentence << " isn't a palindrome." << endl;
}
}
This is my main body of code.
int main(){
int x = 1;
string originalsentence;
while (x == 1) {
int a = 1;
int input;
string sentence;
cout << "Press 1 to reverse a string, 2 to check a palindrome, and anything else to quit: ";
cin >> input;
if(input == 1) {
cout << "Enter a sentence to reverse: ";
cin.ignore();
getline(cin,originalsentence);
originalsentence = sentence;
cout << string(sentence.rbegin(), sentence.rend()) << endl;
}
if(input == 2) {
cout << "Enter a sentence to check: ";
cin.ignore();
getline(cin,originalsentence);
originalsentence = sentence;
checkpalindrome(sentence);
}
cout << "Hit 1 if you want to continue, anything else to quit: ";
cin >> x;
}
}
So here is my problem. I am able to put in my choice about whether to reverse a string or check whether the string is a palindrome. However, when I try to reverse the string, it simply gives a blank line, then asks whether I want to continue. When I ask to check a palindrome, it simply says "is a palindrome" regardless of what I input. Any ideas?