Almost there....

Started by
15 comments, last by GameDev.net 18 years, 10 months ago
Alright, I know I'm getting the hang of C++, but I can't seem to get my Rock, Paper, Scissors to work. I don't know how to make a random command only random between 1 and 3, so it doesn't go below 1 or above 3, but I'll post my source code: //sample game #include <iostream.h> #include <conio> #include <ctime.h> int main () { int a; int b; cout << "Rock(1), Paper(2), or Scissors(3)?" << endl; srand (b); cin >> a; if (a == 1) // begin rock condition { if (b == 1) { cout << "Rock, Draw!" << endl; getch (); return 0; } if (b == 2) { cout << "Paper, You Lose!" << endl; getch (); return 0; } if (b == 3) { cout << "Scissors, You Win!" << endl; } getch (); return 0; } //end rock condition if (a == 2) // begin paper condition { if (b == 1) { cout << "Rock, You Win!" << endl; getch (); return 0; } if (b == 2) { cout << "Paper, Draw!" << endl; getch (); return 0; } if (b == 3) { cout << "Scissors, You Lose!" << endl; getch (); return 0; } } //end paper condition if (a == 3)// begin scissors condition { if (b == 1) cout << "Rock, You lose!" << endl; getch (); return 0; } if (b == 2) { cout << "Paper, You Win!" << endl; getch (); return 0; } if (b == 3) { cout << "Scissors, Draw!" << endl; getch (); return 0; } }//end scissors condition //end of project That's it, its kind of sloppy, but I work that way :), anyway, help on how to fix this up will be greatly appreciated!
Advertisement
srand() is to "seed" the random generator ... so you "can" get different number everytime you run your program.

what you want to use to GET a random number is call the
rand() function

rand() return a random number between 0 and 2^15-1 (0-32767)

so if you want a number between 1 and 3 you can do this :

int randomNumber = rand()%3+1
Woah that was fast, thanks :)
Now, maybe I can finally upgrade and go on to tic tac toe if this works, thanks a million :D


EDIT:
Ok, a couple of problems.... One is that it always goes to 2, as it sais paper everytime, the other problem is that 3 is not working...
My friend had the same problem on his RPS program, so whats going on?

The new code is:

//sample game
#include <iostream.h>
#include <conio>
#include <ctime.h>
int main ()
{
int a;
int b = rand()%3+1;
cout << "Rock(1), Paper(2), or Scissors(3)?" << endl;
cin >> a;
if (a == 1) // begin rock condition
{
if (b == 1)
{
cout << "Rock, Draw!" << endl;
getch ();
return 0;
}
if (b == 2)
{
cout << "Paper, You Lose!" << endl;
getch ();
return 0;
}
if (b == 3)
{
cout << "Scissors, You Win!" << endl;
}
getch ();
return 0;
} //end rock condition
if (a == 2) // begin paper condition
{
if (b == 1)
{
cout << "Rock, You Win!" << endl;
getch ();
return 0;
}
if (b == 2)
{
cout << "Paper, Draw!" << endl;
getch ();
return 0;
}
if (b == 3)
{
cout << "Scissors, You Lose!" << endl;
getch ();
return 0;
}
} //end paper condition
if (a == 3)// begin scissors condition
{
if (b == 1)
cout << "Rock, You lose!" << endl;
getch ();
return 0;
}
if (b == 2)
{
cout << "Paper, You Win!" << endl;
getch ();
return 0;
}
if (b == 3)
{
cout << "Scissors, Draw!" << endl;
getch ();
return 0;
}
}//end scissors condition
//end of project

Now, to me, 1 works, and so does 2, but when I type 3 it does nothing, and when I put in any number, the random number always equals 2, making it paper all the time.
any suggestions?

EDIT:
OK, found out why the (3) wasn't working, forgot an openning and closing bracket, but the number still lands on 2 all the time

[Edited by - doyleman on June 10, 2005 8:19:17 PM]
as I said in my first message, srand(int) is to change the Seed ... to get different random numbers at every execution ...

so, you got 2 choices :

1- don't exit the program :

while(1) {

All your code goes here

}

2- Seed the random number before calling rand() ...
something like this should be OK :

srand(time(0));
AAhhhhh, i see now, sorry I didn't understand from before, but you have been of really great help!
Thanks a billion :)
Ok, this topic has no more use, but anyhoo....
I beg to differ; the topic has plenty more use, sir. [smile]

First, please learn to use [code][/code] tags for short snippets of code, or [source][/source] for longer ones. The former version sets things in a typewriter font and the latter will put up one of those cute source boxes. This is covered in the FAQ so you don't really have an excuse.

Next, we're going to get rid of the repetition from your code. Repeating stuff in code is *bad*. It gives more possible places to mess up, and just overall increases the size of the thing you have to look at - a real pain when it comes to debugging.

First what we need to do is outline the process:

- Ask the user for a selection.
- Tell the user what the computer's selection was.
- Determine who wins and tell the user.
- Pause and exit.

This guideline keeps us on the right track; for example, we know that we always need to pause and exit at the end, so we'll write the code for that just once - at the end. Similarly, we see that the tasks of identifying the computer's selection and determining the winner are actually separate.

Now we're ready to put that in to code. Follow the comments for more explanation. I'm also going to fix a few style issues that you probably picked up from a really old C++ tutorial. :)

#include <iostream> // new version of this header#include <conio>#include <cctime> // new version of this header// The new libraries put things like cout, endl etc. into the "std namespace";// this protects you in case you want your own variable named cout or endl.// This is especially an issue in game programming, where the standard library// "vector" container is frequently useful and may clash with your own 2d or// 3d vector class ;) Anyway, we don't have such variables of our own, so to// save typing:using namespace std;// That tells the compiler to look in the std namespace for the declaration of// anything that it can't find declared in our code.// I'll define some values so that it's clear how the numbers correspond to// game selections.const int ROCK = 1;const int PAPER = 2;const int SCISSORS = 3;int main () {  srand(time(0));  // In C++, variable declarations don't have to be "at the top of scope".  // Nor should they be; put them right in the place where they're needed.  // I'm going to name the variables more nicely.  int playerChoice;  // First, get the user's selection.  cout << "Rock(1), Paper(2), or Scissors(3)?" << endl;  cin >> a;  // Now that we have the user's selection, we can inform the user what  // the computer selected. Note there is no endl here; the rest of the lines  // will follow.  int computerChoice = rand()%3+1;  if (computerChoice == ROCK) {    cout << "Rock, ";  } else if (computerChoice == PAPER) {    cout << "Paper, ";  } else { // must be SCISSORS    cout << "Scissors, ";  }  // Now follow that up with an indication of who won.  // Note how the brackets are placed, logically grouping each possibility.  // First, let's consider the ways the computer might win.  // Note that && is a logical AND and || is a logical OR, and you may  // read them as such here.  if ((computerChoice == ROCK && playerChoice == SCISSORS) ||      (computerChoice == SCISSORS && playerChoice == PAPER) ||      (computerChoice == PAPER && playerChoice == ROCK)) {    cout << "You Lose!";  // Now the ways the player might win...  } else if ((playerChoice == ROCK && computerChoice == SCISSORS) ||             (playerChoice == SCISSORS && computerChoice == PAPER) ||             (playerChoice == PAPER && computerChoice == ROCK)) {    cout << "You Win!";  } else {    // If neither of those happened, then it was a draw.    cout << "Draw!";  }  // Now we can pause and end.  getch();  return 0;}


Believe it or not, there are still a lot of things that could potentially be cleaned up:

- With a bit more care put in to how the numbers are assigned, it becomes easier to calculate the winner - by doing a bit of arithmetic, instead of big and/or checks.

- The "magic numbers" involved in picking the computer's selection are a possible bug source - it's unlikely we'll have to worry about this, but imagine if we wanted to add more options to the game than just rock, scissors or paper. We'd have to remember to change this, too, and that's bad. Besides, in future games we're likely to be using this random-number technique a lot, so it would be a good idea to wrap it up into a function - let it take in a minimum and maximum value, for example. (There are also better ways to go about it than the way you're being shown here, which is usually shown because it's easy to understand :/ This works, but other options are "better" as in "more random/unpredictable" - although *real* randomness from a computer is basically impossible without special hardware.)

- We can put the "symbol" names (rock, scissors, paper) into a table of strings, which makes it easier to make sure that the user's "menu" is consistent with the code's understanding of what number means which symbol. Doing this with the other text items would be a good idea as well; it then becomes easier to translate the game. Later, it would be possible to read all those little bits of text in from a file with some special formatting, and then it's much nicer for our translators - they shouldn't have to know how to compile code, let alone program. (You think I'm kidding because this is just rock/paper/scissors, but may as well learn the good ideas now :) )

- And a big one: You may find that the program behaves rather unexpectedly if the user decides to be stupid (or malicious) and types in something that isn't one of those numbers (1, 2 or 3). It would be a good idea to add some error checking, especially if we later want to expand the game to play multiple times per session. (Note: it's easy to check if a number is in bounds, but checking if something *is a number* is a bit trickier - plus there is extra work to be done if it isn't, in order to let the user try again. see here.
"First, please learn to use [*code][/*code] tags for short snippets of code, or [*source lang="cpp"]
[/*source] for longer ones. The former version sets things in a typewriter font and the latter will put up one of those cute source boxes. This is covered in the FAQ so you don't really have an excuse."

Dont mean to sound rude or anything, but I do know of the tags, just don't like them. Please don't ask why, just trust me that I don't like them, however, if it helps others understand, I'll gladly do it, Also, I know I could clean the code up, but you didn't have to say I picked up the code from a really old tutorial, as I didn't. I actually learned quite a bit by a person who told me I should get into C++.
I did this code completely without any reference what so ever except when I needed to know how to set a limit to randomization and ask for the code to make it randomize, which was srand or of the sort, so I would really appreciate it if you did not assume anything, although when teaching, I guess you should, but what you were assuming were irrelevant and did not need to be 'assumed', namely, the

"I'm also going to fix a few style issues that you probably picked up from a really old C++ tutorial. :)".

Ok, once again, I apologize if I sounded rude, but I just need to point out that I made a major leap from a simple name askinig program to Rock Paper Scissors in around 2 days. I will try doing the code you posted, and see if I can make it better, formal, whatever.

Sorry bout the ranting;
doyle
Quote:Original post by doyleman
Also, I know I could clean the code up, but you didn't have to say I picked up the code from a really old tutorial, as I didn't. I actually learned quite a bit by a person who told me I should get into C++.

I did this code completely without any reference what so ever except when I needed to know how to set a limit to randomization and ask for the code to make it randomize, which was srand or of the sort, so I would really appreciate it if you did not assume anything, although when teaching, I guess you should, but what you were assuming were irrelevant and did not need to be 'assumed' ...

Ok, once again, I apologize if I sounded rude, but I just need to point out that I made a major leap from a simple name askinig program to Rock Paper Scissors in around 2 days. I will try doing the code you posted, and see if I can make it better, formal, whatever.


Hey dude, no one is trying to insult your intelligence here, only trying to be helpful. First, <iostream.h> is an antiquated header file - it's old, it's outdated. If you try to compile you will get a warning like this - "#warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard." It's simply a matter of form.

Actually what Zahlman was assuming was a fair assumption, one that I would have made myself. Most people you ask who have learned C++ in the last few years will tell you that you should use <iostream> instead of <iostream.h>. Pretty much the only place that you'll find <iostream.h> used is in older, outdated tutorials.

If you don't want to accept good advice, that's up to you. Again, no one is looking down on you or being condescending...simply trying to be helpful. I mean, you did ask for help... "anyway, help on how to fix this up will be greatly appreciated!" ... No need to get defensive.
haha, I put in I didn't mean to sound rude and all, I know he was helping :)
What I was saying was that basically I was new and that I made a big jump in terms of programming. Didn't mean to sound defensive, but you know, on the internet its kind of hard to show expression, even with smilies and stuff.
Sorry bout if what I said was harsh, but <iostream.h> is sooo much easier for me, plus my compiler works with it just fine, so I didn't see any problems *how else would I know what the problem with my code was lol*

Im not a fan of assuming, so that's why I went into that topic, as if you know the saying (it makes an ass of 'u m e', get ite, put it together, you get assume, lol), but yeah, don't like it....
anyway, I apologize for any bashing, flaming, etc that I may have signalled out or whatever, so sorry ;).
thanks for helping and all, and I am working on the whole revision thing on R/P/S right now :)

doyle
Original post by Zahlman
I beg to differ; the topic has plenty more use, sir. [smile]

First, please learn to use
tags for short snippets of code, or
for longer ones. The former version sets things in a typewriter font and the latter will put up one of those cute source boxes. This is covered in the FAQ so you don't really have an excuse.

Next, we're going to get rid of the repetition from your code. Repeating stuff in code is *bad*. It gives more possible places to mess up, and just overall increases the size of the thing you have to look at - a real pain when it comes to debugging.

First what we need to do is outline the process:

- Ask the user for a selection.
- Tell the user what the computer's selection was.
- Determine who wins and tell the user.
- Pause and exit.

This guideline keeps us on the right track; for example, we know that we always need to pause and exit at the end, so we'll write the code for that just once - at the end. Similarly, we see that the tasks of identifying the computer's selection and determining the winner are actually separate.

Now we're ready to put that in to code. Follow the comments for more explanation. I'm also going to fix a few style issues that you probably picked up from a really old C++ tutorial. :)

*** Source Snippet Removed ***

Believe it or not, there are still a lot of things that could potentially be cleaned up:

- With a bit more care put in to how the numbers are assigned, it becomes easier to calculate the winner - by doing a bit of arithmetic, instead of big and/or checks.

- The "magic numbers" involved in picking the computer's selection are a possible bug source - it's unlikely we'll have to worry about this, but imagine if we wanted to add more options to the game than just rock, scissors or paper. We'd have to remember to change this, too, and that's bad. Besides, in future games we're likely to be using this random-number technique a lot, so it would be a good idea to wrap it up into a function - let it take in a minimum and maximum value, for example. (There are also better ways to go about it than the way you're being shown here, which is usually shown because it's easy to understand :/ This works, but other options are "better" as in "more random/unpredictable" - although *real* randomness from a computer is basically impossible without special hardware.)

- We can put the "symbol" names (rock, scissors, paper) into a table of strings, which makes it easier to make sure that the user's "menu" is consistent with the code's understanding of what number means which symbol. Doing this with the other text items would be a good idea as well; it then becomes easier to translate the game. Later, it would be possible to read all those little bits of text in from a file with some special formatting, and then it's much nicer for our translators - they shouldn't have to know how to compile code, let alone program. (You think I'm kidding because this is just rock/paper/scissors, but may as well learn the good ideas now :) )

- And a big one: You may find that the program behaves rather unexpectedly if the user decides to be stupid (or malicious) and types in something that isn't one of those numbers (1, 2 or 3). It would be a good idea to add some error checking, especially if we later want to expand the game to play multiple times per session. (Note: it's easy to check if a number is in bounds, but checking if something *is a number* is a bit trickier - plus there is extra work to be done if it isn't, in order to let the user try again. see here.

Well, the source was removed, but that is the first time I have ever really seen use of the logical operators. Cool! I understand the code completely... well most of it anyways. Why is the modulus used?'%'
My friend wants to learn to program in C++. If he forgets BASIC right away, well, I am worried.

This topic is closed to new replies.

Advertisement