0

I am working on a little text based adventure game, the first project I've ever worked on for my own enjoyment, and have ran into a problem. I have got it to ask if you want to play, what your name will be and then the problem starts when you try to choose a race. It works just fine when the user types the first character but when they type the string it will skip past the gender, and class cin. Do I have to clear the cin? Or is my code just wrong?? Thanks for any help you can provide.

#include "pch.h"
#include <iostream>
#include <string>
#include <cctype>
#include <map>
using namespace std;

enum races { Human, Orc, Elf, Dwarf};
enum classes { Warrior, Mage, Archer, Assassin};
const std::map< char, string > race_map =
{ {'H', "human"}, {'O', "orc"}, {'E', "elf"}, {'D', "dwarf"} };
const std::map< char, string > class_map =
{ {'W', "warrior"}, {'M', "mage"}, {'Ar', "archer"}, {'A', "assassin"} 
};

void gameIntro();
void gameStart();
void raceFunc(char race);
void playerClassFunc(char playerClass);


void gameIntro()
{
string playerName;
char race;
char sex;
char playerClass;

cout << "Enter your name: \n";
cin >> playerName;
cout << "\n";


cout << "Select a race (Human, Orc, Elf, Dwarf): \n";
cin >> race;
cout << "\n";
raceFunc(race);


cout << "Select Gender (M or F): \n";
cin >> sex;
cout << "\n";


cout << "Select a class (Warrior, Mage, Archer, Assassin): \n";
cin >> playerClass;
cout << "\n";
playerClassFunc(playerClass);

gameStart();
}

void raceFunc(char race)
{
race = toupper(race);
switch (race)
{
case 'H':
    cout << "You chose Human!\n\n";
break;
case 'O':
    cout << "You chose Orc!\n\n";
break;
case 'E':
    cout << "You chose Elf!\n\n";
break;
case 'D':
    cout << "You chose Dwarf!\n\n";
break;

default:
    cout << "Please choose from the following. Program closing.\n";
    system("pause");
    exit(0);
}
}

void playerClassFunc(char playerClass)
{
playerClass = toupper(playerClass);
switch (playerClass)
{
case 'W':
    cout << "You chose Warrior!\n";
break;
case 'M':
    cout << "You chose Mage!\n";
break;
case 'Ar':
    cout << "You chose Archer!\n";
break;
case 'A':
    cout << "You chose Assassin!\n";
break;

default:
    cout << "Please choose from the following. Program closing.\n";
    system("pause");
    exit(0);
}
}

void gameStart()
{

}

int main()
{
char answer;

cout << "Welcome to Dark Horse\n\n";
cout << "This is my fisrt ever actual program I made out of my own free 
will lol.\n";
cout << "It is a Text-Based Adventure game. In this game you will make a 
character,\n";
cout << "and explore the land of Spelet, battling enemies, leveling up, 
getting loot,\n";
cout << "and learning skills! You do not need to capitalize anything but 
your character\n";
cout << "name. If a question has (something like this) if you don't 
enter whats inside\n";
cout << "the program will CLOSE, so please pay attention! Thank you for 
trying it out!\n";
cout << "I really hope y'all enjoy it!\n\n";
do
{
    cout << "Would you like to play?\n";
    cin >> answer;
    if (answer == 'Y')
    {
        gameIntro();
    }
    else if (answer == 'N')
    {

        system("pause");
        return 0;
    }
    else if (answer != 'N' || 'Y' || 'exit')
    {
        cout << "Come on dog it's Y or N...yes or no...\n\n";
    }

} while (answer == 'N' || 'Y');

system("pause");
return 0;
}

Problem when entering string

Working when entering character

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Hoeins
  • 49
  • 4
  • 1
    After you type a character into console and submit it with enter, cin actually contains the newline characters. So next time you read single character from cin, you get those of the newline. So you are calling gender and class with (probably) '\r' and '\n' respectively. You have to `ignore()` the newlines after each cin read. – Jan Hošek Mar 17 '20 at 09:31
  • 1
    This is actually a well-written question. I expect it was down-voted because it is a frequent issue and could have been found by searching. Don't get discouraged. – stark Mar 17 '20 at 13:53

1 Answers1

1

"cin, of class istream, is the standard input channel used for user input. This steam corresponds to C's stdin. Normally, this stream is connected to the keyboard by the operating system." (Josuttis, 2012, p. 745)

Josuttis, N. (2016). The C++ Standard Library: A Tutorial and Reference 2nd Edition: Addison-Wesley

The types are important.

char race;
std::cout << "Please enter your race:" << std::endl;
std::cin >> race;

If the user enters "Human", the standard input stream contains Human and the race variable now has the value H (of type char). The standard input stream now contains uman.

char gender;
std::cout << "Please enter your gender:" << std::endl;
std::cin >> gender;

Calling >> with std::cin gets another character from the standard input stream (in this case u) and stores it in gender. The standard input stream now contains man.

While it appears that the gender question was skipped, you can now see that this is not the case. The input stream still contains characters. If you look at your first screenshot you can see that "Mage" was selected. This is because the value of playerClass is m, the same m from when you entered human.

One way to remedy this is to use std::string instead of char to store the input. That way you have more flexibility in parsing what the user enters (e.g. you can allow for H or Human).

Community
  • 1
  • 1
Ryan H.
  • 2,543
  • 1
  • 15
  • 24
  • When I store it in as a string my switch/case seems to mess up. I'm sorry if this is a fairly easy fix, I am still learning but thought i had learned enough to attempt this lol. here is the problem. https://imgur.com/a/fzmi0p0 – Hoeins Mar 18 '20 at 03:27
  • @Hoeins, You are using "switch". The expression must be of an integral type or of a class type for which there is an unambiguous conversion to integral type. I suggest you could refer to the link: https://stackoverflow.com/questions/650162/why-the-switch-statement-cannot-be-applied-on-strings – Jeaninez - MSFT Mar 18 '20 at 06:25
  • So what would be the correct way to go about this then? – Hoeins Mar 19 '20 at 01:30
  • @Hoeins, There are different ways you can approach this. One way is using an if-statement *instead* of the switch-statement. Additionally, the following might be helpful: https://stackoverflow.com/questions/4165131/c-c-switch-for-non-integers – Ryan H. Mar 19 '20 at 11:28