So I'm trying to write an easy basic game here with basic C++, and when I try to execute this
// global variabless
const char UP = 'w', LEFT = 'a', DOWN = 's', RIGHT = 'd'; // player movement choices
char playerMove; // goes with askPlayer
void askPlayer()
{
char choice;
cout << "Use the WASD keys to move: ";
cin >> choice;
int worked;
do{
if (choice == 'w' || choice == 'W')
{
playerMove = UP;
worked = 1;
}
else if (choice == 'a' || choice == 'A')
{
playerMove = LEFT;
worked = 1;
}
else if (playerMove == 's' || playerMove == 'S')
{
playerMove = DOWN;
worked = 1;
}
else if (playerMove == 'd' || playerMove == 'D')
{
playerMove = RIGHT;
worked = 1;
}
else
{
cout << "Invalid entry." << endl;
worked = 0;
}
} while (worked != 1);
return;
}
It works up to the user entering a letter. Xcode says (lldb) then the page fills up with numbers, and after you stop the run, it says "Program ended with exit code: 9". It does this even if you enter one of the valid values
You never prompt for another value after the user enters the first one:
cin >> choice; // <==
int worked;
do {
// ..
} while (worked != 1);
Just move the input into the loop:
int worked;
do {
cin >> choice; // possibly with cout prompt too
// rest as before
} while (worked != 1);
Your input is outside the loop, your variable worked is uninitialized ( though it is not a error in your code but is cleaner to initialize your variables) and it should have bool type. Whole code can be simplified by the switch statement:
void askPlayer()
{
do {
char choice;
cout << "Use the WASD keys to move: ";
cin >> choice;
switch( choice ) {
case 'w' : case 'W' :
playerMove = UP;
break;
case 'a' : case 'A' :
playerMove = LEFT;
break;
case 's' : case 'S' :
playerMove = DOWN;
break;
case 'd' : case 'D' :
playerMove = RIGHT;
break;
default:
cout << "Invalid entry." << endl;
continue;
}
} while( false );
return;
}
Related
I am working on a project right now and when I try to run what I have below it gives me an error that says "uninitialized local variable 'userOption' used" on line 22, while (isValidOption(userOption) == true) {.
How do I fix that error? Thank you.
#include<iostream>
#include <string>
using namespace std;
char toupper(char ch) {
if (ch >= 'A'&&ch <= 'Z')
return(ch);
else
return(ch - 32);
}
bool isValidOption(char ch) {
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X')
return(true);
else
return(false);
}
char getMainOption() {
string UserInput;
char userOption;
while (isValidOption(userOption) == true) {
cout << "Choose One of the following options\n";
cout << "I--List Our Inventory\n";
cout << "O--Make an Order\n";
cout << "L--List all Orders made\n";
cout << "X--Exit\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
if (!isValidOption(userOption)) {
cout << "Invalid String\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
}
if (userOption == 'I')
cout << "Listing Our Inventory\n";
else if (userOption == 'O')
cout << "Make an order\n";
else if (userOption == 'L')
cout << "Listing all orders\n";
}
return userOption;
}
int main() {
char choice;
choice = getMainOption();
system("pause");
return 0;
}
What the error is saying that you're trying to read from userOption before you've ever written to it. If a variable is uninitialized, its memory contents will be full of junk left behind by other functions and it can easily cause bugs. In your case, you'll want to read input from the user into userOption before you do any logic on it. This can be done with a do-while loop:
char userOption; // not yet initialized
do {
...
cin >> userOption; // userOption gets initialized here on first loop run
} while (isValidOption(userOption)); // no need for == true, that's a tautology :-)
// NOTE: perhaps you want to loop while the input is INvalid, as in
// while (!isValidOption(userOption)); ?
A couply code-review comments I would additionally give are:
std::toupper already exists in <cctype>. Docs are here
return is not a function call and it's better to write return ch; than return(ch);
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X'){ return true; } else { return false; } is completely equivalent to the shorter return ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X';
Also take a look at system(“pause”); - Why is it wrong?
Happy coding! Let me know if questions remain
I'm very new to coding and have hit a confusing spot...I have made a very basic ticTacToe game and when I am trying to check the value of the array to see if there are 3 in a row it is not grabbing the values (or maybe it is but im out of scope??).
Just wondering how I would go about checking the value of my multi array?
Here is the code.
user.cpp // check win function
void User::checkForWin()
{
board board;//construct board
if ((board.ticTacToeBoard[0][0] == getUser1Char()) && (board.ticTacToeBoard[0][1] == getUser1Char()) &&
(board.ticTacToeBoard[0][2] == getUser1Char()))//Check array values to see if they win. PROBLEM AREA
{
std::cout << getUserName(_user1Char) << "You Are The Winner!" << std::endl;
exit(0);
}
User.cpp // Game loop
void User::userGo(char userGo)
{
board board; //Construct board
board.initBoard(); //Initilize board
int quitGame = 1; //sets value of quit game loop...This isnt working either but a minor issue for now as im just using exit(); until i figure it out
while (quitGame == 1) //game loop
{
while (userGo == 'G') //loop to swap user goes
{
invalid1: //goto return point if user1 enters an invalid character.
cout << getUserName('A') << " Please enter a letter between A and I or Q for quit" << endl;
char player1Input; //
cin >> player1Input;
if ((player1Input == 'Q') || (player1Input == 'A') || (player1Input == 'B') || // If player input equals
(player1Input == 'C') || (player1Input == 'D') || (player1Input == 'E') || // any of these values
(player1Input == 'F') || (player1Input == 'G') || (player1Input == 'H') || // then run for loop
(player1Input == 'I'))
{
for (int iii = 0; iii < 3; iii++) // Looping through tictactoe board values
{ // values are set to A through I
for (int jjj = 0; jjj < 3; jjj++) // as there are 9 places in the array
{
switch (player1Input) // Checking user input against and placing into array in relevant spot.
{ // *Find More elegant way to right this maybe with a loop.
case 'Q':
cout << "Thanks for Playing! " << endl;
quitGame = 2;
exit(0);
case 'A':
board.ticTacToeBoard[0][0] = 'X';
break;
case 'B':
board.ticTacToeBoard[0][1] = 'X';
break;
case 'C':
board.ticTacToeBoard[0][2] = 'X';
break;
case 'D':
board.ticTacToeBoard[1][0] = 'X';
break;
case 'E':
board.ticTacToeBoard[1][1] = 'X';
break;
case 'F':
board.ticTacToeBoard[1][2] = 'X';
break;
case 'G':
board.ticTacToeBoard[2][0] = 'X';
break;
case 'H':
board.ticTacToeBoard[2][1] = 'X';
break;
case 'I':
board.ticTacToeBoard[2][2] = 'X';
break;
default:
break;
}
}
}
}
else
{
cout << "Sorry ";
getUserName('A'); // If none of the values are correct print out wrong value statement
cout << " This is not a valid move." << endl; // and send the user back to the invalid1 Marker.
goto invalid1;
}
checkForWin(); // Check for win - PROBLEM AREA
board.printBoard(); // Print board for user2 visual
userGo = 'F'; // swap to User2's Go.
}
while (userGo == 'F') //loop to swap user goes
{
invalid2: //goto return point if user2 enters an invalid character.
cout << getUserName('B') << " Please enter a letter between A and I or press Q to quit." << endl;
char player2Input;
cin >> player2Input;
if ((player2Input == 'Q') || (player2Input == 'A') || (player2Input == 'B') || // If player input equals
(player2Input == 'C') || (player2Input == 'D') || (player2Input == 'E') || // any of these values
(player2Input == 'F') || (player2Input == 'G') || (player2Input == 'H') || // then run for loop
(player2Input == 'I'))
{
for (int iii = 0; iii < 3; iii++) // Looping through tictactoe board values
{ // values are set to A through I
for (int jjj = 0; jjj < 3; jjj++) // as there are 9 places in the array
{
switch (player2Input) // Checking user input against and placing into array in relevant spot.
{ // *Find More elegant way to right this maybe with a loop.
case 'Q':
cout << "Thanks for Playing" << endl;
quitGame = 2;
exit(0);
break;
case 'A':
board.ticTacToeBoard[0][0] = 'O';
break;
case 'B':
board.ticTacToeBoard[0][1] = 'O';
break;
case 'C':
board.ticTacToeBoard[0][2] = 'O';
break;
case 'D':
board.ticTacToeBoard[1][0] = 'O';
break;
case 'E':
board.ticTacToeBoard[1][1] = 'O';
break;
case 'F':
board.ticTacToeBoard[1][2] = 'O';
break;
case 'G':
board.ticTacToeBoard[2][0] = 'O';
break;
case 'H':
board.ticTacToeBoard[2][1] = 'O';
break;
case 'I':
board.ticTacToeBoard[2][2] = 'O';
break;
default:
break;
}
}
}
}
else
{
cout << "Sorry " << _name2;
getUserName('B'); // If none of the values are correct print out wrong value statement
cout << " This is not a valid move." << endl; // and send the user back to the invalid2 Marker.
goto invalid2;
}
}
checkForWin(); // Check for win - PROBLEM AREA
board.printBoard(); // Print board for user1 visual
userGo = 'G'; // swap to User1's Go.
}
}
I know I have used a load of magic numbers/characters and my code isn't going to be the most elegant as I am just learning, please any advice is much appreciated and also and mainly the reason I posted.
Why won't checkForWin() do what its told?
You need to either add a member variable to User which represents the board, a global variable that can be seen by everything, or you need to make checkForWin take a board as a parameter.
checkForWin(Board& board)
{
//Board board; // << remove this line
You would then pass the local board to checkForWin each time:
checkForWin(board);
A better design, though, would be to make checkForWin a member function of Board rather than User so that you would call:
board.checkForWin();
There are other design critiques and code changes I could recommend but that goes well beyond the scope of answering your question, better to let you absorb all of this and continue your studies at an appropriate pace :)
In the checkForWin function, the variable board is a local variable. It exists only for that function and is default constructed.
If you have a User::board member variable, or a global board variable, your local definition shadows and overrides the member/global variable.
Same in the userGo function.
I have been having an issue getting the if else statement to properly work in the code.
I have everything else where I need it, just we are supposed to have multiple entries input and it just automatically uses the responses and the else statements do not work.
int main ()
{
string dep = "Deposit";
string with = "Withdrawl";
string bal = "Balance";
char choice;
cout << "PLease enter options A, B, C, or Q to quit.\n";
cin >> choice;
switch (choice) //to make them all the same, same as using toUpper
{
case 'a':
case 'A':
cout << "";
break;
case 'b':
case 'B':
cout << "";
break;
case 'q':
case 'Q':
cout << "";
break;
}
int count = 1;
while (count <= 4)
{
if (choice == 'a' || 'A' )
cout << dep << endl;
else if (choice == 'b' || 'B' )
cout << with << endl;
else if(choice == 'c' || 'C' )
cout << bal << endl;
else
(choice !='a' && choice !='b' && choice !='c');
cout << "that is invalid, PLease enter options A, B, C, or Q to quit.\n";
++count ;
}
system ("PAUSE");
return 0;
}
You need to fix the conditional statements like this:
if (choice == 'a' || choice == 'A' )
What you have will always result in the first conditional being met because 'A' is equal to decimal 65.
if(choice == 'a'||'A'),the computers will run the 'a'||'A' first,and it's return 1 (in bool) ,and then run the
choice == 1,according to your codes, there are no choice == 1,so the codes in if will not be run.
I want to loop a question and make it say "press Y to continue or N to quit" but I don't quite know how. I tried to do a while loop but they haven't worked well. Here's the code:
cout << "press Y to play again or anything else to close: ";
cin >> val;
if (val != "Y" && val != "y")
{
spelaIgen = false;
}
}
Best for you to use cases to make your selections of "Y or N". The attempt you were making would have made it so any character other than Y would quit.
bool correctVal = false;
char val;
while (!correctVal)
{
cout << "press Y to play again or N to close: ";
cin >> val;
switch(val)
{
case 'y':
case 'Y':
spelaIgen = false;
correctVal = true;
break;
case 'n':
case 'N':
spelaIgen = true;
correctVal = true;
break;
default:
cout << "\nInvalid entry!" << endl;
}
}
You could do something like this. Initialize your input variable, then use that variable as your while condition. Continue iterating your while loop until they enter something other than 'y' or 'Y'.
char val = 'Y';
while (val == 'Y' || val == 'y')
{
// Do stuff
cout << "press Y to play again or anything else to close: ";
cin >> val;
}
I am assuming you are using the standard namespace in C++ here. Try the following:
string val = "Y";
while (val == "Y")
{
cout << "press Y to play again or anything else to close: ";
cin >> val;
if (val != "J" && val != "j")
{
spelaIgen = false;
}
}
I'm working on something along the lines of a console based Tamagotchi (I can't draw, so I'm working with what I've got). For my menu functions, I'm trying to present a menu > take in user input as a char > convert the char to an int > perform selection.
#include <iostream>
//Functions
void menuShow();
int menuChoice();
void menuAction();
int main()
{
menuAction();
}
//Menu display
void menuShow()
{
std::cout << "\nPlease choose from the following:" << std::endl;
std::cout << "(S)tatus of your pet." << std::endl;
std::cout << "(F)eed your pet." << std::endl;
std::cout << "(Q)uit." << std::endl;
}
//Convert input from char to int
int menuChoice()
{
char userChoice;
int convertChoice = 0;
do
{
menuShow();
std::cout << "Choice: ";
std::cin >> userChoice;
if ((userChoice = 'S') || (userChoice = 's'))
{
convertChoice = 1;
}
else if ((userChoice = 'F') || (userChoice = 'f'))
{
convertChoice = 2;
}
else if ((userChoice = 'Q') || (userChoice = 'q'))
{
convertChoice = 3;
}
} while ((userChoice != 'S') || (userChoice != 's') || (userChoice != 'F') || (userChoice != 'f') || (userChoice != 'Q') || (userChoice != 'q')); //Repeat if incorrect selection is made
return convertChoice; //return converted int
}
//Get converted choice and perform related action
void menuAction()
{
int choice;
do
{
choice = menuChoice(); //initialize using returned convertChoice
switch (choice)
{
case 1:
std::cout << "You look at your pets' stats" << std::endl;
break;
case 2:
std::cout << "You feed your pet" << std::endl;
break;
default:
std::cout << "You have quit!" << std::endl;
break;
}
} while (choice != 3);
}
As of right now it doesn't accept an input and perform the action, it just spits out the menu over and over. So my questions are: 1) Am I on the right track for this conversion to work or am I not even close? 2) If I'm way off, can you push me in the right direction (given that this is possible)?
Also, I know this could be taken care of by using int's for the user selections and passed to the switch. However, I wanted to see if I could do this for future reference, as well as try to think "outside the box" in terms of the repetitive "option 1:", option 2:", etc.