I have made a "computer". My conctructor looks like this:
PC::PC()
{
cout << "Would you like to turn the pc on? type y for yes." << endl;
a = getchar();
while (a != 'y')
{
cout << "If you dont turn it on, then nothing will happen. Loser." << endl;
a = getchar();
}
}
Then if you press y you will be sent to the next step which is the function PC::pcOn which looks like this:
void PC::pcOn()
{
for (auto i = 0; i < 3; i++)
{
cout << "----------------------------------------" << endl;
}
cout << "--------- What is your name? -----------" << endl;
changeName();
for (auto i = 0; i < 3; i++)
{
cout << "----------------------------------------" << endl;
}
for (auto i = 0; i < 5; i++)
{
cout << "**" << endl;
Sleep(100);
}
cout << "Welcome " << name << " to the future of computing." << endl << endl;
cout << "This computer program can do a lot of things for you" << endl << "it is a good calculator, try to type \"calculater\"" << endl;
}
However when i have the while loop in the contructor to get the y to go on, the changeName(); wont work, but if i remove that, the changeName function works just fine, and it takes my input just fine.
The code for the changeName() looks like this:
void PC::changeName()
{
string _name;
getline(cin, _name);
name = _name;
}
I have tried using the Visual Studio's debugger to see why i wont call it correctly, but alas to no hope.
The weird thing is, that the function works fine if the while loop in the constructor is not there.
It is because in getline(cin, _name), it always inputs the "/n" character as it is feeded when you type enter.
To correct it, put a getchar();
void PC::changeName()
{
string _name;
getchar();
getline(cin, _name);
name = _name;
}
You need to flush cin before calling changeName(), this can be done using
int c;
while ((c = getchar()) != '\n' && c != EOF);
What I want is for it to let the user guess the number as many times as it takes to guess it, then tell him the number of times it took him to guess it, that´s why im making the condition for the for loop g!=r, however, I have no idea if C++ allows this.
Also, the errors I get when trying to compile this are
expression must have a constant value
expression did not evaluate to a constant" and "case expression not constant
Here´s the code:
int main()
{
int r = rand() % 101;
int g = 0;
int t = 10;
std::cout << "Guess a number, human (From 1 to 100)." << std::endl;
std::cin >> g;
for (int t = 0; g != r; t++)
{
switch (g) {
case (g == r):
std::cout << "You won, now get lost!" << std::endl;
break;
case (g < r):
std::cout << "Too low, piece of turd." << std::endl;
break;
case (g > r):
std::cout << "Too high, dubai." << std::endl;
break;
default :
std::cout << "How could you possibly have gotten it wrong, you stupid ape." << std::endl;
}
}
std::cout << "Finally!, it took you " << t << " freaking times!" << std::endl;
return 0;
}
The switch case checks must be constant expressions that are compared for equality against the original value.
In your case, you can rewrite that switch using if commands.
Use the code below, and it will compile.
if (g == r)
{
std::cout << "You won, now get lost!" << std::endl;
}
else if (g < r)
{
std::cout << "Too low, piece of turd." << std::endl;
}
else if (g > r)
{
std::cout << "Too high, dubai." << std::endl;
}
else
{
// will not get here, as previous if already cover all cases
std::cout << "How could you possibly have gotten it wrong, you stupid ape." << std::endl;
}
C++ switch
http://en.cppreference.com/w/cpp/language/switch
C++ if
http://en.cppreference.com/w/cpp/language/if
If you're required to use a switch, you might try using a while loop with a flag and some checks before the switch:
bool flag = true;
int t = 0;
int x = 0;
while( flag )
{
t++;
std::cout << "Guess a number, human (From 1 to 100)." << std::endl;
std::cin >> g;
if( g == r )
{
x = 1;
flag = false;
}
else if( g < r )
x = 2;
else
x = 3;
switch (x) {
case (1):
std::cout << "You won, now get lost!" << std::endl;
break;
case (2):
std::cout << "Too low, piece of turd." << std::endl;
break;
case (3):
std::cout << "Too high, dubai." << std::endl;
break;
default :
std::cout << "How could you possibly have gotten it wrong, you stupid ape." << std::endl;
}
}
I changed it to an if statement, and now after the first guess, the user isn´t able to guess again.
ok, the new code here:
int main()
{
int r = rand() % 101;
int g = 0;
int t = 0;
std::cout << "Guess a number, human (From 1 to 100)." << std::endl;
std::cin >> g;
for (int t = 0; g = r; t++)
{
if (g < r)
{
std::cout << "Too low." << std::endl;
std::cin >> g;
}
else if (g > r)
std::cout << "Too high." << std::endl;
std::cin >> g;
}
std::cout << "Finally!, it took you " << t << " freaking times!" << std::endl;
return 0;
}
I want to make a simple game of 3 players, each player moves in a block depending of the random function from 1 to 6 blocks each time, when first player has been moved the second player start and then then the third player. To do that I increase the index of an array rach time a player finish its move.
My problem is that the indexer seems no to been increased, and it stacks in the player 1 even if I increase it. I have exactly the same code in C# and it works well!
Here is the code in C++.
int main ()
{
string namesofplayers[] = {"one","two","three"};
int movementofplayers[] = {0,0,0}; // start position of players is
int gamesize = 32; //32 blocks-steps of game
int random;
int y = 0;
a:
y++;
if (y >= 3)
{
y = 0;
}
cout << "it's" << namesofplayers[y] << "turn to play";
int R = (rand() % 6 + 1);
cout << "player " << namesofplayers[y] << " moves to block" << R << endl;
movementofplayers[y] += random;
cout << movementofplayers[y];
if (movementofplayers[y] < gamesize)
{
goto a;
}
else
{
cout << "Player " << namesofplayers[y] << " wins the game" << endl;
}
}
On the off chance of doing your work, I took the liberty to write up an alternative implementation which fixes some of the problems your former code had and also produces more readable output. I also threw out the one-liners because they drive me crazy, but that's personal preference. Also, I tend to explicitly qualify symbols from the standard library using the appropriate scope.
Get rid of goto. You can browse SO and the web for multiple reasons why not to use an explicit jump like that. Just use a loop
Fix the missing initial seed for the pseudo-random number generator. If you set a varying seed, i.e. by invoking it with some variable value (e.g. time(nullptr) ), you'll always get the same succession of "random" values - with each program invocation.
Fix the use of the variable random. You tried to add some garbage-initialized value random to movementofplayers[y]. Interestingly, g++-4.7 seems to ensure that the variable is set to 1 before being used in the arithmetic op. However, the correct variable you need is R.
Return a well defined value from main().
I hope the code still does what you intended it to do:
#include <string>
#include <iostream>
int main ()
{
srand(time(NULL));
std::string namesofplayers[] = {"one","two","three"};
int movementofplayers[] = {0,0,0}; // start position of players is
int gamesize = 32; //32 blocks-steps of game
int y = 1;
while(movementofplayers[y] < gamesize)
{
if (y >= 3)
{
y = 0;
}
std::cout << "it's " << namesofplayers[y] << " turn to play" << std::endl;
int R = (rand() % 6 + 1);
std::cout << "player " << namesofplayers[y] << " moves to block " << R << std::endl;
movementofplayers[y] += R;
std::cout << "movements of player " << namesofplayers[y] <<": " << movementofplayers[y] << std::endl;
y++;
}
std::cout << "Player " << namesofplayers[y] << " wins the game" << std::endl;
return 0;
}
Here is how I would do it.
Added seeding the random number generator so you don't get the same game every time.
Added a constant for number of players to get rid of the magic number and also make it easier to expand the number of players if desired.
Got rid of the goto. Although it is possible to use goto in a reasonable way it is prone to accidental misuse, makes the code harder to follow, and makes people angry. :)
I tweaked the output and names a bit just to make it a little easier for me to test. In doing so I corrected an issue where it said the player moved to block R which was their roll for that turn, not their actual position in the game.
#include <string>
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
std::srand(static_cast<unsigned int>(std::time(0)));
const int gamesize = 32;
const int num_players = 3;
const std::string namesofplayers[num_players] = {"1", "2", "3"};
int movementofplayers[num_players] = {0, 0, 0};
int current_player = 0;
for(;;) //Loop forever, the game logic will exit the loop when a winner is found
{
const int roll = rand() % 6 + 1;
movementofplayers[current_player] += roll;
std::cout << "Player " << namesofplayers[current_player] << " rolls a " << roll << " and moves to block " << movementofplayers[current_player] << std::endl;
//Check if they won and if so, end the game
if(movementofplayers[current_player] >= gamesize)
{
std::cout << "Player " << namesofplayers[current_player] << " wins the game!" << std::endl;
break;
}
current_player = (current_player + 1) % num_players;
}
return 0;
}
I am currently in the process of writing a C++ Monty Hall Problem Simulation and have run into some trouble. The error I keep getting is:
source.cpp(23): error C4700: uninitialized local variable 'doorReveal' used
source.cpp(25): error C4700: uninitialized local variable 'doorSwitch' used
source.cpp(52): error C4700: uninitialized local variable 'stayWin' used
source.cpp(56): error C4700: uninitialized local variable 'switchWin' used
I can't seem to figure out what is wrong. The project is supposed to simulate the wins by first staying with the original door choice on the first 100 tries and then switching when door is revealed on the next 100 tries. Thank you all for your help in advance.
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
int doorChoice;
int prizeDoor;
int doorReveal;
int doorSwitch;
int count;
int switchWin;
int stayWin;
srand((unsigned int) time(0));
for (count = 0; count <= 200; count++)
{
prizeDoor = (rand() % 3) + 1;
doorChoice = (rand() % 3) + 1;
cout << "The prize door is door number " << prizeDoor << " ." << endl;
cout << "The door the contestant chose was door " << doorChoice << endl;
doorReveal != prizeDoor || doorChoice;
cout << "The host revealed door number " << doorReveal << " ." << endl;
doorSwitch != doorChoice || doorReveal;
while (count < 101)
{
if (doorChoice == prizeDoor)
{
cout << "Great Job! You won!" << endl;
}
else {
cout << "Not this time!" << endl;
}
}
while (count < 201)
{
if (doorSwitch == prizeDoor)
{
cout << "You switched and won!" << endl;
}
else {
cout << "You switched and lost!" << endl;
}
}
if (doorChoice == prizeDoor)
{
stayWin++;
}
if (doorSwitch == prizeDoor)
{
switchWin++;
}
count++;
}
cout << "Your win percentage when staying was " << stayWin << "%!" << endl;
cout << "Your win percentage when switching was " << switchWin << "%!" << endl;
return 0;
}
Problem 1: operator!=
operator != doesn't do what you think it does.
Did you mean
doorReveal = !(prizeDoor || doorChoice);
cout << "The host revealed door number " << doorReveal << " ." << endl;
doorSwitch = (doorChoice || doorReveal);
I sense another logic issue in determining the doorReveal. I'll have to think about that later.Edit: see problem 5
Problem 2: while
There's also a problem with the while loops:
while(count < 101)
// ...
while(count < 201)
They're infinite loops, because count isn't increased during the loop. I think you meant if there, instead of while.
Problem 3: Initiliazing switchWin and stayWin
These variables are only being incremented. Like #KonradRudolph suggested,
declare your variables where they are first needed
initialize them
while you're at it, mark them const as appropriate
Problem 4: rand()%3 is biased
You should probably use a uniform distribution.
See
http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx
I'll leave using std::uniform_int_distribution as an exercise for the reader here, as it is likely beyond the scope of your course. Remember to use it though, in any real life code.
Problem 5: Fix your door 'derivation'
Booleans aren't sets. Even if they were, you'd be stuck to binary sets. I propose the following model:
enum doors { door1 = 1, door2 = 2, door3 = 4, any = door1|door2|door3 };
so you can say:
doors const doorReveal = doors(~(prizeDoor | doorChoice) & any);
doors const doorSwitch = doors(~(doorChoice | doorReveal) & any);
Fixing that results in a program that appears to work:
#include <iostream>
#include <time.h>
using namespace std;
enum doors { door1 = 1, door2 = 2, door3 = 4, any = door1|door2|door3 };
static inline std::ostream& operator<<(std::ostream& os, doors val) {
switch(val) {
case door1: return os << "door #1";
case door2: return os << "door #2";
case door3: return os << "door #3";
case any: return os << "any door";
}
return os << "OOPS";
}
int main()
{
unsigned switchWin = 0;
unsigned stayWin = 0;
srand((unsigned int) time(0));
for(int count = 0; count <= 200; count++)
{
doors const prizeDoor = doors(1 << rand() / ( RAND_MAX / 3 ));
doors const doorChoice = doors(1 << rand() / ( RAND_MAX / 3 ));
cout << "The prize door is door number " << prizeDoor << " ." << endl;
cout << "The door the contestant chose was door " << doorChoice << endl;
doors const doorReveal = doors(~(prizeDoor | doorChoice) & any);
doors const doorSwitch = doors(~(doorChoice | doorReveal) & any);
cout << "The host revealed door number " << doorReveal << " ." << endl;
if(count < 101)
{
if(doorChoice == prizeDoor)
{
cout << "Great Job! You won!" << endl;
}
else
{
cout << "Not this time!" << endl;
}
};
if(count < 201)
{
if(doorSwitch == prizeDoor)
{
cout << "You switched and won!" << endl;
}
else
{
cout << "You switched and lost!" << endl;
}
};
if(doorChoice == prizeDoor)
{
stayWin++;
}
if(doorSwitch == prizeDoor)
{
switchWin++;
};
count++;
}
cout << "Your win percentage when staying was " << stayWin << "%!" << endl;
cout << "Your win percentage when switching was " << switchWin << "%!" << endl;
return 0;
}
I have never experienced anything like this. I was using a cout statement to help me debug a small program, and once I was satisfied with my code I commented out the cout. Now, the code no longer works. Below is the code with the cout commented out.
The intent of this program is to test the two hard coded boolean two dimensional arrays for having an odd number of true statements on each row. Thus, the first array should return true and the second array should return false. With the cout statement commented out both instead return false.
#include <iostream>
using namespace std;
template <size_t size_y>
bool findEvenDegrees(bool mapArray[][size_y])
{
bool returnValue;
for (int x=0; x<size_y; x++)
{
int result = 0;
for (int y=0; y<size_y; y++)
{
result = result + mapArray[x][y];
//the line below causes the problem
cout << mapArray[x][y] << "\t" << result << "\t" << x << endl;
}
if (result%2 == 1)
{
returnValue = false;
break;
}
}
if (returnValue== false)
{
return returnValue;
}
else
{
return true;
}
}
int main()
{
bool array1[][6] =
{
{false,true,true,false,false,false},
{true,false,false,true,false,false},
{true,false,false,true,false,false},
{false,true,true,false,true,true},
{false,false,false,true,false,true},
{false,false,false,true,true,false}
};
bool array2[][8] =
{
{false,true,true,false,false,false,false,false},
{true,false,false,true,false,false,false,false},
{true,false,false,true,false,false,false,false},
{false,true,true,false,true,false,false,false},
{false,false,false,true,false,true,true,false},
{false,false,false,false,false,true,false,true},
{false,false,false,false,true,false,false,true},
{false,false,false,false,false,true,true,false}
};
bool answer1 = findEvenDegrees(array1);
bool answer2 = findEvenDegrees(array2);
if (answer1 == true)
{
cout << "Array 1 has a even degree for every switch." << endl;
}
else
{
cout << "Array 1 has a odd degree for at least one switch." << endl;
}
if (answer2 == true)
{
cout << "Array 2 has a even degree for every switch.";
}
else
{
cout << "Array 2 has a odd degree for at least one switch.";
}
return 0;
}
You never initialize returnValue. If it happens to start out as false it will stay that way and the function will return false.
First, I cleaned up your code a little, and arrived at:
#include <iostream>
template <size_t S>
bool findEvenDegrees(bool (&themap)[S][S]) {
for( bool(&row)[S]: themap ) {
bool is_degree_odd = false;
for( auto col: row )
is_degree_odd ^= col;
if( is_degree_odd )
return false;
}
return true;
}
int main()
{
using std::cout;
using std::endl;
bool array1[6][6] = {
{false,true,true,false,false,false},
{true,false,false,true,false,false},
{true,false,false,true,false,false},
{false,true,true,false,true,true},
{false,false,false,true,false,true},
{false,false,false,true,true,false}
};
cout << "Array 1 has an "
<< (findEvenDegrees(array1) ? "even degree for every" : "odd degree for at least one")
<< " switch." << endl;
bool array2[8][8]= {
{false,true,true,false,false,false,false,false},
{true,false,false,true,false,false,false,false},
{true,false,false,true,false,false,false,false},
{false,true,true,false,true,false,false,false},
{false,false,false,true,false,true,true,false},
{false,false,false,false,false,true,false,true},
{false,false,false,false,true,false,false,true},
{false,false,false,false,false,true,true,false}
};
cout << "Array 2 has an "
<< (findEvenDegrees(array2) ? "even degree for every" : "odd degree for at least one")
<< " switch." << endl;
return 0;
}
In the process of cleaning it up, I eliminated the if(result%2 == 1) { resultValue = true; break; }, by effectively returning when I found the first odd-degree row. As I eliminated the resultValue variable, I also killed the "unitialized" bug mentioned by #sth.