Join 109,157 C# Programmers for FREE! Ask your question and get quick answers from experts. There are 1,024 online right now! We've got more than 500 tutorials and 2,000 snippets. Join and find out why Dream.In.Code is the #1 programming help community on the internet! Registration is fast and FREE... Join Now!
Here's my game that I made just for fun and to help me learn. There is a lot of similar or repeating code that I would like to use methods for, as I have done for some of it.
Yes, this is pretty sloppy. I probably should have used flags for some (or all?) of the error checking.
And some of the while loops probably could have been for loops, when I used a counter...except that you'd need to break out of the for loop when the user gets the correct answer and I don't know how to do that. How do you do that?
Also, is there a way to keep from having to create different variable names (example: for the user's answer or for their guess)?
So here's my sloppy code:
csharp
using System; using System.Collections.Generic; using System.Text;
namespace ConsoleApplication1 { class Program { private static void greeting() { //Depending on the current time, print either "Good morning," "Good afternoon," or "Good evening" DateTime time = new DateTime();
//get the current time time = DateTime.Now;
//if it is past midnight but before noon, print "Good morning." if (time.Hour >=0 && time.Hour < 12 ) { Console.WriteLine("Good morning."); } //if it is past noon but before 6PM, print "Good afternoon." else if (time.Hour >= 12 && time.Hour < 18) { Console.WriteLine("Good afternoon."); } //if it is past 6PM, print "Good evening." else if (time.Hour >= 18) { Console.WriteLine("Good evening."); }
}
//method to get answer from user, when asked if they want to know my name public static void GetAns() { string ans = Console.ReadLine(); ans = ans.ToUpper(); if (ans == "Y") { Console.WriteLine("Okay. You asked. My name is Tammy."); greeting();
} else //if they enter anything other than Y or y, allow them to exit { Console.WriteLine("Okay. I will not tell you my name."); greeting();
} } //method called when the user doesn't enter a valid number public static void GuessError() { Console.WriteLine("You must enter a whole number greater than zero."); }
static void Main(string[] args)
{ //initialize a new instance of the Random class Random RandomClass = new Random(); //print greeting based on user's current time greeting();
Console.WriteLine("Welcome to the game.\n"); Console.WriteLine("What shall I call you?");
//assign whatever they type to a property called name, which we will use throughout the game string name = Console.ReadLine(); Console.WriteLine("Hello {0}!", name);
Console.WriteLine("Would you like to play a game? Type Y for yes or N for no."); string answer = Console.ReadLine(); answer = answer.ToUpper();
if (answer == "Y") { Console.WriteLine("What do you want to play, {0}? Pick one: 1. Harder guessing game 2. Math game 3. Easy guessing game", name);
int game; //if they didn't enter a number, return 0 int.TryParse(Console.ReadLine(), out game); //show error if they did not enter a number between 1 and 3 while (game <= 0 || game > 3) { Console.WriteLine("You must enter either 1, 2, or 3."); int.TryParse(Console.ReadLine(), out game); } switch (game) { case 1: Console.WriteLine("Okay, let's start the harder guessing game!"); Console.WriteLine("I am thinking of a number between one and one hundred."); Console.WriteLine("Try to guess my number, {0}! Type your first guess now.", name);
//get a random number between one and 100 int myNum = RandomClass.Next(1, 100);
//create property for guesses int guess; int.TryParse(Console.ReadLine(), out guess); //make sure the user entered a valid number while (guess <=0 || guess >= 101) { GuessError(); int.TryParse(Console.ReadLine(), out guess); } int countr = 0; //let them keep guessing until they guess the right number or for 10? tries while (guess != myNum && countr<9) { //give a hint if they are within one number if (guess == (myNum + 1)|| guess == myNum -1) { //put a couple methods in here for repeating code Console.WriteLine("That's pretty close, {0}, but not right. Guess again!", name); int.TryParse(Console.ReadLine(), out guess); }
//if they guess too high, tell them to guess lower else if (guess > myNum) { Console.WriteLine("Lower!"); int.TryParse(Console.ReadLine(), out guess); } //if they guess too low, tell them to guess higher else if (guess < myNum) { Console.WriteLine("Higher!"); int.TryParse(Console.ReadLine(), out guess); } countr++; //make sure the user entered a valid number while (guess <= 0 || guess >= 101) { GuessError(); int.TryParse(Console.ReadLine(), out guess); } } if (countr >= 9) { Console.WriteLine("Sorry, {0}, the correct answer was " + myNum.ToString(), name);
}
if (guess == myNum) { Console.WriteLine("Good guess, {0}! That's my number!", name); }
Console.WriteLine("Would you like to play again?"); string again = Console.ReadLine(); again = again.ToUpper();
//if they want to play again, repeat the game if (again == "Y") { goto case 1; }
else//if they enter anything other than Y or y, end the game Console.WriteLine("Okay. No more games. Shall I tell you my name, {0}?", name); //call method to get the user's answer GetAns();
break;
case 2: Console.WriteLine("Let's play a math game. Pick one: 1. addition or 2. subtraction."); int pick; //if they didn't enter a number, return 0 int.TryParse(Console.ReadLine(), out pick); //if they didn't enter either 1 or 2, show error while (pick <= 0 || pick > 2) { Console.WriteLine("You must enter either 1 or 2."); int.TryParse(Console.ReadLine(), out pick); } if (pick == 1) { Console.WriteLine("Let's start adding!"); int add1 = RandomClass.Next(1, 100); int add2 = RandomClass.Next(1, 100); Console.WriteLine("Add " + add1.ToString() + " and " + add2.ToString() + "."); Console.WriteLine("Type your answer now."); int sumGuess; int.TryParse(Console.ReadLine(), out sumGuess); //make sure they entered a number while (sumGuess == 0) { GuessError(); int.TryParse(Console.ReadLine(), out sumGuess); }
int sum = add1 + add2; int tries = 0; //let them keep trying until they get it or for 10 tries while (sumGuess != sum && tries < 9) { //if their answer is within one number, give a hint if (sumGuess == sum + 1 || sumGuess == (sum - 1)) { Console.WriteLine("That's pretty close, {0}, but not right. Keep guessing!", name); } else { Console.WriteLine("Keep trying!"); } //update counter tries++; int.TryParse(Console.ReadLine(), out sumGuess); //show error if they don't enter number or leave blank while (sumGuess == 0) { GuessError(); int.TryParse(Console.ReadLine(), out sumGuess); }
} if (tries >= 9) { //if they don't get it within 10 tries, tell them the answer Console.WriteLine("Sorry, {0}, the correct answer is " + sum + ".", name); }
if (sumGuess == sum) { Console.WriteLine("Congratulations! That is the correct answer."); }
Console.WriteLine("Would you like to play again? Type Y or N."); string addAgain = Console.ReadLine(); if (addAgain == "Y" || addAgain == "y") { goto case 2; } else { Console.WriteLine("Ok, so you don't want to add any more. Do you want to know my name?"); //call method to get the user's answer GetAns(); } } else if (pick == 2) { Console.WriteLine("Let's start subtracting!"); int sub1 = RandomClass.Next(1, 100); int sub2 = RandomClass.Next(1, 100); int trys = 0; //make sure the first number is more than the second one, to avoid negative numbers //and make sure the two numbers are not equal, so the answer will never be zero while (sub1 <= sub2) { sub1 = RandomClass.Next(1, 100); sub2 = RandomClass.Next(1, 100); } int diff = sub1 - sub2; Console.WriteLine("Subtract " + sub1 + " minus " + sub2 + "."); Console.WriteLine("Type your answer now."); int diffGuess; int.TryParse(Console.ReadLine(), out diffGuess);
//show error if they didn't enter a number while (diffGuess == 0) { GuessError(); int.TryParse(Console.ReadLine(), out diffGuess); } //let them keep trying until they get it or for 10 tries while (diffGuess != diff && trys < 9) { //if their answer is within one number, give a hint if (diffGuess == diff + 1 || diffGuess == diff - 1) { Console.WriteLine("That's pretty close, {0}, but not right. Try again.",name); } else { Console.WriteLine("Keep trying!"); } //update counter trys++; int.TryParse(Console.ReadLine(), out diffGuess); //show error if they don't enter number or leave blank //this code is repeated, can I avoid this? while (diffGuess == 0) { GuessError(); int.TryParse(Console.ReadLine(), out diffGuess); }
} if (trys >= 9) { Console.WriteLine("Sorry, {0}, the correct answer is " + diff + ".", name); }
if (diffGuess == diff) { Console.WriteLine("Congratulations! That is the correct answer."); } Console.WriteLine("Would you like to play again? Type Y or N."); string subAgain = Console.ReadLine(); if (subAgain == "Y" || subAgain == "y") { goto case 2; } else { Console.WriteLine("Ok, so you don't want to subtract any more. Do you want to know my name?"); //call method to get the user's answer GetAns(); } }
break;
case 3: Console.WriteLine("Let's start the easy guessing game!"); Console.WriteLine("I am thinking of a number between one and ten."); Console.WriteLine("Try to guess my number, {0}! Type your first guess now.", name);
//get a random number between one and ten myNum = RandomClass.Next(1, 10);
int.TryParse(Console.ReadLine(), out guess); //make sure the user enters a valid number (1-10) while(guess <=0||guess>=11) { GuessError(); int.TryParse(Console.ReadLine(), out guess); } //let them keep guessing until they guess the right number or for 5 tries int count = 0; while (guess != myNum && count<4)//count starts at 0, so when it gets to 4, they will have used 5 tries {
//give a hint if they guess within one number if (guess == (myNum + 1) || guess == myNum - 1) { Console.WriteLine("That's pretty close, {0}, but not right. Guess again!", name); count++; int.TryParse(Console.ReadLine(), out guess);
} else { Console.WriteLine("Keep guessing!");
count++;
int.TryParse(Console.ReadLine(), out guess); } //make sure the user enters a valid number (1-10) while (guess <= 0 || guess >= 11) { GuessError(); int.TryParse(Console.ReadLine(), out guess); } } //if they use up all their tries, tell them the answer if (count >= 4) { Console.WriteLine("Sorry, {0}, my number was " + myNum + ".", name); } //if they get the right answer, let them know if (guess == myNum) { Console.WriteLine("Good guess, {0}! That's my number!", name); } //give the user a choice whether to play again Console.WriteLine("Would you like to play again?"); again = Console.ReadLine(); again = again.ToUpper();
//if they want to play again, repeat the game if (again == "Y") { goto case 3; } else//if they enter anything other than Y or y, end the game Console.WriteLine("Okay. No more games, {0}. Shall I tell you my name?", name);
//call method to get the user's answer GetAns(); break; } }
else //if they enter anything other than Y or y when asked if they want to play a game { Console.WriteLine("Okay. No games. Shall I tell you my name, {0}?", name); //call method to get the user's answer GetAns();
Don't be afraid of methods, they're good for you. Each distinct section that you have in your massive if case thing can be placed in it's very own method.
Also, a goto is a sign of failure and any instructor is likely to let you know it.
Here's some code to get you going. I didn't write it all, but it should give you an idea.
csharp
using System; using System.Collections.Generic; using System.Text;
namespace ConsoleApplication1 { class Program { private String userName = null; private Random RandomClass = new Random();
private void Welcome() { Console.WriteLine("Welcome to the game.\n"); Console.WriteLine("What shall I call you?"); this.userName = Console.ReadLine(); Console.WriteLine("Hello {0}!", userName); }
// helper function private bool GetYN(string prompt) { if (prompt != null) { Console.WriteLine(prompt); } string ans = Console.ReadLine(); return (ans.Trim().ToUpper() == "Y"); }
private bool GetYN() { return GetYN(null); }
//method to get answer from user, when asked if they want to know my name private void GetAns() { if (GetYN()) { Console.WriteLine("Okay. You asked. My name is Tammy."); } else { Console.WriteLine("Okay. I will not tell you my name."); } greeting(); }
// return true if they want to play again private bool EasyGame() { Console.WriteLine("Let's start the easy guessing game!"); Console.WriteLine("I am thinking of a number between one and ten."); Console.WriteLine("Try to guess my number, {0}! Type your first guess now.", this.userName);
int guess = 0; int count = 0; bool done = false; int myNum = RandomClass.Next(1, 10);
while (!done) { int.TryParse(Console.ReadLine(), out guess); if (guess<1 || guess>=11) { Console.WriteLine("You must enter a whole number greater than zero."); } else { count++; if (guess == myNum) { Console.WriteLine("Good guess, {0}! That's my number!", this.userName); done = true; } else if (count > 5) { Console.WriteLine("Sorry, {0}, my number was " + myNum + ".", this.userName); done = true; } else { if (guess == (myNum + 1) || guess == myNum - 1) { Console.WriteLine("That's pretty close, {0}, but not right. Guess again!", this.userName); } else { Console.WriteLine("Keep guessing!"); } } } }
return (GetYN("Would you like to play again?")); }
private bool HarderGame() { // your code return false; }
private bool MathGame() { // your code return false; }
private int GetGameSelection() { int game; Console.WriteLine("What do you want to play, {0}? Pick one: 1. Harder guessing game 2. Math game 3. Easy guessing game", name); //if they didn't enter a number, return 0 int.TryParse(Console.ReadLine(), out game); //show error if they did not enter a number between 1 and 3 while (game < 1 || game > 3) { Console.WriteLine("You must enter either 1, 2, or 3."); int.TryParse(Console.ReadLine(), out game); } return game; }
private void GameSelect() { switch (GetGameSelection()) { case 1: while (HarderGame()); break;
case 2: while (MathGame()); break;
case 3: // loop on one game until they're done while (EasyGame()); break; } }
public void Play() { Welcome(); if (GetYN("Would you like to play a game? Type Y for yes or N for no.")) { GameSelect() } else { Console.WriteLine("Okay. No games. Shall I tell you my name, {0}?", this.userName); } // give them the name GetAns(); }
static void Main(string[] args) { Program pgm = new Program(); pgm.Play(); } } }
Thank you. Since this is not for a class, I consider you (and other DIC'ers) my instructor at the moment.
So... should I get rid of the case statement completely? Or just don't use goto. I see why you said it is a sign of failure, since I could not get it to work any other way.
It does make sense that every chunk of code should go into a method, especially if it repeats.
If code repeats, then a method is often the most efficient way to eliminate the duplication.
I'm not a big fan of case statements. They don't do anything that an if then else construct can't do, and are far more limited. They can make some code look cleaner, but only in specific instances and usually providing that code doesn't grow. Some folks love them, but not I.
Some cleanups will be purely cosmetic, by their nature. Just choose a coding style that appeals to you and be consistent.
This is a flag, is that right? I haven't used them much yet.
csharp
// helper function private bool GetYN(string prompt) { if (prompt != null) { Console.WriteLine(prompt); } string ans = Console.ReadLine(); return (ans.Trim().ToUpper() == "Y"); }
private bool GetYN() { return GetYN(null); }
and if I understand it correctly, since it is boolean, it must return either true or false. This line: return (ans.Trim().ToUpper() == "Y"); will cause GetYN to return true if they enter a y or Y and false otherwise. Is that right?
There are really two different methods here, both named GetYN, but since their parameters differ, you can do that. When you call GetYN(), it causes GetYN(string prompt) to run, and returns either true or false to GetYN().
This happens first:
CODE
return (GetYN("Would you like to play again?"));
and it causes "Would you like to play again?" to be displayed, and then it gets their answer using the two methods above.
This:
CODE
while (HarderGame());
causes the game to continue as long as they want to play, because HarderGame is boolean, and the code will run as long as HarderGame() returns true.
What I put in here:
CODE
private bool HarderGame() { // your code return false; }
in place of //your code, would be code that causes the game to start, that I already have written. At the end of the game code, I would ask if they want to play again, using your boolean
CODE
return (GetYN("Would you like to play again?"));
and it works because if they enter Y or y, as stated above, it will return true, otherwise it returns false.
The boolean done, here, just lets them quit playing that game (not the entire program) when they guess the right number or use up all their tries. Otherwise, it lets them keep trying.
CODE
bool done = false; int myNum = RandomClass.Next(1, 10);
while (!done) { int.TryParse(Console.ReadLine(), out guess); if (guess<1 || guess>=11) { Console.WriteLine("You must enter a whole number greater than
zero."); } else { count++; if (guess == myNum) { Console.WriteLine("Good guess, {0}! That's my number!",
this.userName); done = true;
This game is the most involved thing I've ever done in programming, so far. We never did anything like this in class. (edit--with a couple exeptions in VB)
I really want to be good at this, so thanks again for helping me. I want to make sure I understand why things are done, not just "what" to do. Please tell me if I have not understood any part of this correctly.
This post has been edited by OliveOyl3471: 10 Jun, 2008 - 10:30 PM
The program runs and for the most part it works as is, but it doesn't ask them if they want to know my name whenever they are done playing the games. It just displays a blank line and if you press enter it will display "Okay. I will not tell you my name." lol.
I would also like to change it so that instead of automatically repeating the same game they can go back to the game choices when asked if they want to play again. You would call GetGameSelection() at that point, wouldn't you? Where would you call it?
I did change it so that they have a choice of adding or subtracting when they want to play again, for the math game.
Here's part of the 'new improved' game (still working on it):
csharp
//Show error message if they don't enter a number private static void GuessError() { Console.WriteLine("That is not a valid number. Please try again."); }
// return true if they want to play again private bool EasyGame() { //baavgai's improved version of my code here }
private bool HarderGame() {
Console.WriteLine("Okay, let's start the harder guessing game!"); Console.WriteLine("I am thinking of a number between one and one hundred."); Console.WriteLine("Try to guess my number, {0}! Type your first guess now.", this.userName);
int count = 0; bool done = false; int myNum = RandomClass.Next(1, 100); int guess=0; while (!done) { int.TryParse(Console.ReadLine(), out guess); //make sure the user entered a valid number while (guess <= 0 || guess >= 101) { GuessError(); int.TryParse(Console.ReadLine(), out guess); }
//let them keep guessing until they guess the right number or for 10? tries while (guess != myNum && count < 9) { //give a hint if they are within one number if (guess == (myNum + 1) || guess == myNum - 1) {
Console.WriteLine("That's pretty close, {0}, but not right. Guess again!", this.userName); int.TryParse(Console.ReadLine(), out guess); }
//if they guess too high, tell them to guess lower else if (guess > myNum) { Console.WriteLine("Lower!"); int.TryParse(Console.ReadLine(), out guess); } //if they guess too low, tell them to guess higher else if (guess < myNum) { Console.WriteLine("Higher!"); int.TryParse(Console.ReadLine(), out guess); } count++; //make sure the user entered a valid number while (guess <= 0 || guess >= 101) { GuessError(); int.TryParse(Console.ReadLine(), out guess); } } if (count >= 9) { Console.WriteLine("Sorry, {0}, the correct answer was " + myNum.ToString(), this.userName); done = true; }
if (guess == myNum) { Console.WriteLine("Good guess, {0}! That's my number!", this.userName); done = true; } } //if they want to play again, repeat the game return (GetYN("Would you like to play again?")); //how do you get this to do something else when they enter N? }
private bool MathGame() { //my math game code goes here
return (GetYN("Would you like to play again?"));//lets them play another math game }
private int GetGameSelection() { int game; Console.WriteLine("What do you want to play, {0}? Pick one: 1. Harder guessing game 2. Math game 3. Easy guessing game", this.userName); //if they didn't enter an int, return 0 int.TryParse(Console.ReadLine(), out game); //show error if they did not enter a number between 1 and 3 while (game < 1 || game > 3) { Console.WriteLine("You must enter either 1, 2, or 3."); int.TryParse(Console.ReadLine(), out game); } return game; }
private void GameSelect() { switch (GetGameSelection()) { case 1: while (HarderGame()) ; break;
case 2: while (MathGame()) ; break;
case 3: // loop on one game until they're done while (EasyGame()) ; break; } }
And some of the while loops probably could have been for loops, when I used a counter...except that you'd need to break out of the for loop when the user gets the correct answer and I don't know how to do that. How do you do that?
CODE
private void button9_Click(object sender, EventArgs e) { string iStr = ""; for (int i = 0; i < 10; i++) if (i == 5) { iStr = i.ToString(); break; // This is how you break out of a for loop } MessageBox.Show(iStr); }
Hope this helps,
This post has been edited by djkitt: 30 Jun, 2008 - 06:52 AM