Calling a instance value in a different method - c#

I don't know how to access my instance in another method. I have this set of code.
Card rorbcard = new Card();
Deck deck = new Deck();
deck.Shuffle();
rorbcard = deck.TakeCard();
Start0:
Console.Clear();
Console.WriteLine("Allright lets play! Red or black?");
string userValue0 = Console.ReadLine();
switch (userValue0.ToLower())
{
case "red":
{
if (rorbcard.Suit.Equals(Suit.Diamonds))
{
Console.WriteLine("{0},\n Correct give 2 drinks",
rorbcard.ToString());
Thread.Sleep(2000);
}
else if (rorbcard.Suit.Equals(Suit.Hearts))
{
Console.WriteLine("{0},\n Correct give 2 drinks",
rorbcard.ToString());
Thread.Sleep(2000);
}
else
{
Console.WriteLine("{0},\n Wrong sucka take 2 drinks",
rorbcard.ToString());
Thread.Sleep(2000);
}
}
I am trying to use that rorbcard.ToString() in another method, but I cant figure out how to reference it. Here is the other method.
public void HighLow()
{
//highlow part of the game
Deck deck = new Deck();
deck.Shuffle();
Card highLow = new Card();
highLow = deck.TakeCard();
Start1:
Console.Clear();
Console.WriteLine("Your Hand:");
Grid.WriteAt(rorbcard.ToString(), 0, 1);
Console.WriteLine("\n\nDo you think that the next card will higher,lower,\n or
equal to the {0}. Enter high, low, or equal\n", rorbcard);
string uservalue1 = Console.ReadLine();
switch (uservalue1.ToLower())
{
case "high":
if (highLow.CardNumber > rorbcard.CardNumber) <-----Issue
{
Console.WriteLine("{0},\n Correct give 4 drinks",
highLow.ToString());
Thread.Sleep(2000);
}
else
{
Console.WriteLine("{0},\n Wrong drink 4\n", highLow.ToString());
Thread.Sleep(2000);
}
Thanks for your time in looking into this. I am stuck and have been for a bit.

You can do either
a. Pass as parameter to HighLow() like
public void HighLow(string rorbcard)
b. Create a class level variable. Assign value to it and use that value in HighLow() like
class MyClass
{
private string rorbCardClassLevel;
private void MyrorbCardMethod
{
//Other code lines.
//Inside case statement
rorbCardClassLevel = rorbcard.ToString();
}
private void HighLow()
{
//Use rorbCardClassLevel here.
}
}

All I needed to do was place my instances outside the methods and inside my class. Duh

Related

This do while loop is is going on forever and I can’t get it to stop

I’m trying to make a game where you have to choose a random number, and the computer will tell you if you’re right or not. But in the code I have, the loop will just keep executing what is in the if command. If I try to break it’ll just do what’s in the while part of it. I want to be able to enter a number, tell you if it’s right or not, and then let you guess again. Thanks for the help! Also, ignore how part of the code isn’t counting as code. I couldn’t get it to go into the code part, and I didn’t try very hard either. Also sorry about the abnormal variable names.
using System;
using System.Threading;
namespace newProject
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("useless intro");
int shortOut;
Random rnd = new Random();
int daNumber = rnd.Next(9);
string userNumber = Console.ReadLine();
bool isParsable = Int32.TryParse(userNumber, out shortOut);
if (isParsable)
{
do
{
if (shortOut != daNumber)
{
Console.WriteLine("no");
}
} while (shortOut != daNumber);
Console.WriteLine("that's it yeah");
}
}
}
}
Your code is asking for the user input only once. It then checks if it is an int and, if it is, it then starts the loop that never changes the variables. It's going to loop forever.
You need to ask for the user's input repeatedly until they guess correctly. Asking for the input needs to be in the loop. And you should only break out of the loop when they get it right.
Here's how I would do it:
Random rnd = new Random();
//choose a number between 0 and 8 inclusive
int daNumber = rnd.Next(9);
// start with a value that the user would never enter
int daGuess = int.MinValue;
//loop if the two numbers are not the same
while (daGuess != daNumber)
{
Console.WriteLine("Enter your guess:");
if (int.TryParse(Console.ReadLine(), out daGuess))
{
if (daGuess != daNumber)
{
Console.WriteLine("no");
}
else
{
Console.WriteLine("that's it yeah");
}
}
}
You don't need to check the guess match twice. What you want is an infinite loop that breaks when the condition is true.
int daNumber = new Random().Next(9);
while(true)
{
if (Int32.TryParse(Console.ReadLine(), out int shortOut))
{
if (shortOut == daNumber)
{
Console.WriteLine("that's it yeah");
break;
}
Console.WriteLine("no ");
}
else
{
Console.WriteLine("cannot be parsed as int");
}
}
}

How to return a user input value to another class? c#

I'm new to c# and object orientated programming so please excuse me if it's a nooby question but i'm not too familiar with everything yet.
I want to ask the user for input in a method in the first class, and then return this value to a method in the second class, to work out the final cost. I understand how to pass a set value via constructors but thats as far as i know, this would be fine however i need an input value to be passed not a set value. (this code is just a bit from my main program)
class TableOrder
{
string inputtablenumber;
int tablenumber;
public int TableNumber()
{
Console.Write("please enter the table number:");
inputtablenumber = Console.ReadLine();
tablenumber = int.Parse(inputtablenumber);
return tablenumber;
}
}
class TableBill
{
public void CalculateBill()
{
TableOrder TO = new TableOrder();
TO.AddDrink();
if (tablenumber >= 6 & tablenumber < 10)
{
Console.Write("You are due a 10% discount");
}
if (tablenumber > 10)
{
Console.Write("you are due a 15% discount");
}
}
}
class Program
{
static void Main(string[] args)
{
TableBill TB = new TableBill();
TB.CalculateBill();
}
}
so i want to use the number that comes from the TableNumber method in my CalculateBill class, instead of passing over an already set value. I tried with the TO.AddDrink(); but i didn't get anywhere. This is only a small snippet of my overall code so whats happening may not make too much sence but i just want to access this tablenumber value in another class.
Thank You in advance!
Change int tablenumber; to public int tablenumber;, then in CalculateBill call TO.TableNumber and replace tablenumber with TO.tablenumber.
Alternatively:
public void CalculateBill()
{
TableOrder TO = new TableOrder();
var tablenumber = TO.TableNumber();
TO.AddDrink();
if (tablenumber >= 6 & tablenumber < 10)
{
Console.Write("You are due a 10% discount");
}
if (tablenumber > 10)
{
Console.Write("you are due a 15% discount");
}
}
}

C# random image in picturebox and assign value

I'm creating a card game using C#. I want to assign a value to my card example: Ace(image) = 1; and I want to random it. Here's my code:
private void button1_Click(object sender, EventArgs e)
{
Random cards = new Random();
card = cards.Next(0, 9);
switch (card)
{
case 0:
pictureBox1.Image = Properties.Resources.king_d;
pictureBox2.Image = Properties.Resources.jack_s;
break;
case 1:
pictureBox1.Image = Properties.Resources.ace_c;
pictureBox2.Image = Properties.Resources.ten_d;
break;
}
}
}
new the random out of the method. you can take it from a singleton class (read this) or for simplicity if you are in windows app make it static like this:
static Random cards = new Random();
private void button1_Click(object sender, EventArgs e)
{
card = cards.Next(0, 9);
switch (card)
{
case 0:
pictureBox1.Image = Properties.Resources.king_d;
pictureBox2.Image = Properties.Resources.jack_s;
break;
case 1:
pictureBox1.Image = Properties.Resources.ace_c;
pictureBox2.Image = Properties.Resources.ten_d;
break;
}
}
}
Update
The best way to have a card that contains a value, picture, etc. is to have a new class for that. Since PictureBox already has most properties and behaviors that you need, I recommend using it.
The code has to be something like this:
Public Class MyCard:PictureBox
{
public int GamePoint {get;set;}
}
Then instead of using PictureBox in your code, use this.
To be honest I like to encapsulate the code a bit more so I prefer this:
Public Class MyCard:PictureBox
{
public CardType CardType {set;get;}
public int GamePoint {get{ return (int)this.CardType; }}
public MyCard(CardType _cardType)
{
CardType = _cardType;
}
}
enum CardType
{ Ace=1,
King=2,
...
}
Although I don't see an actual question in your question, I think you want to do this in a simpler way.
Well first of all, don't create a Random every time the method is called, make it a class-level variable and initialize it:
private static Random cards = new Random();
Currently, you're using a switch to decide what to show in the two picture boxes. If the random number is 0, put these two cards, if the number is 1, put those two cards... This means that each number from 0 to 9 corresponds to two Bitmaps.
You can use a dictionary to map 0 to 9 to Tuple<Bitmap, Bitmap>, but I think it's better to use an array.
What you basically need to do is to declare an array that stores those Tuple<Bitmap, Bitmap>. Let's call it CardCombinations. I recommend you to put this array in a utility class called CardUtility or something. Then, you can just do:
card = cards.Next(0, 9);
pictureBox1.Image = CardUtility.CardCombinations[card].Item1;
pictureBox2.Image = CardUtility.CardCombinations[card].Item2;
As you can see, this greatly reduced the code in the button1_Click method. Now we can declare the array that I was talking about.
It's pretty simple:
public static Tuple<Bitmap, Bitmap>[] CardCombinations => new[] {
new Tuple<Bitmap, Bitmap>(Properties.Resources.king_d, Properties.Resources.jack_s),
...
};
"But that's still verbose!" you cried. Protip: you can use the using static directive to shorten the bitmap names to king_d and jack_s!
using static SomeNamespace.Properties.Resources;

Get next enum based on the order they are rather than name or value?

Let's say I have an enum like such:
public enum Something
{
This = 10,
That = 5,
It = 11
}
I would like to know if its possible to get the next enum based on the order they are and not their value or name.
Unhappily I have no control over the numbers, I can only change the names.
For example, if I have That the next is It and not This.
Pseudo code:
var current = Something.That;
Console.WriteLine(current);
// prints That
current = GetNextEnum(Something.That);
// prints It
Console.WriteLine(current);
current = GetNextEnum(Something.It);
// prints This
Console.WriteLine(current);
// And so the cycle continues...
Is there any way to achieve this?
UPDATE:
I can't execute more than one state per pulse, so I need to know which state I have ran to know which state to run next, for example:
private Something _state = Something.That;
private void Pulse()
{
// this will run every pulse the application does
foreach (var item in (Something)Enum.GetValues(typeof(Something)))
{
if (_state == item)
{
// Do some stuff here
}
_state = next item;
return;
}
}
Am also trying to avoid to make a block for each state and rather have the states being executed dynamically as they can be added or removed.
So my real question is how can I know what comes next and where I am.
public Something GetNextEnum(Something e)
{
switch(e)
{
case This:
return That;
case That:
return It;
case It:
return This;
default:
throw new IndexOutOfRangeException();
}
}
Or make it an extension:
public static class MySomethingExtensions {
public static Something GetNextEnum(this Something e)
{
switch(e)
{
case This:
return That;
case That:
return It;
case It:
return This;
default:
throw new IndexOutOfRangeException();
}
}
}
and you can use it like this:
_status=_status.GetNextEnum();

Display string value real time

I'm writing a console program, and my code looks like this:
Configuration.cs
public static class Configuration
{
public static string Message = "";
}
Menu.cs
class Menu
{
public static void showMenu()
{
Console.Clear();
Console.WriteLine("1: SOMETHING");
Console.WriteLine("2: SOMETHING");
Console.WriteLine("3: SOMETHING");
Console.WriteLine("SYSTEM MSG: " + Configuration.Message);
Console.Write("INPUT: ");
}
}
Program.cs
...
static void Main(string[] args)
{
...
int choice;
while(true)
{
Menu.showMenu();
choice = Convert.ToInt32(Console.ReadLine());
switch(choice)
{
case 1:
Configuration.Message = "HELLO!";
break;
case 2:
Configuration.Message = "HI!";
break;
case 3:
Configuration.Message = "WHAT?!";
break;
}
}
}
...
For now, when I change Configuration.Message, it will display on the menu because the showMenu method clears the console and show the string again.
But what I want to make is without Clear method, I want to show Configuration.Message for real time. I was thinking that using Timer and refresh the menu every second, but it is not efficient (feels like cheating). How can I do this?
When you write to the Console, the write operation begins at the current cursor position. So...
Look at the properties and methods of the System.Console class, in particular:
CursorLeft gets or sets the column position of the cursor
CursorTop gets or sets the row position of the cursor
SetCursorPosition( int left , int top ) sets both row and column position.
As each character is written, the cursor moves one position to the right, wrapping to the next row when the cursor would move past the BufferWidth column (e.g. if you're console's buffer is 80 columns wide, writing the 80th column would advance the column outside the buffer (column 81), so the cursor would move to column 1 of the next row.
For what you want to do, you could also look at P/Invoking the native Win32 cursor methods, or use something like one of the .Net derivations of *nix's curses(3) and Gnu's ncurses(3):
Mono-Curses: http://www.mono-project.com/MonoCurses
Curses Sharp: http://curses-sharp.sourceforge.net/
Curses X: http://www.csharpcity.com/2013/consolecurses-library-for-c/
I would suggest that if functionality like this is necessary it would be better to look at a UI technology like WPF. But, that being said, maybe this would do what you wanted. Showing the menu each time you set the Message. I do not think when using the console there is a way to bind a variable to some message on the console.
public static class Configuration
{
private static string _message;
public static string Message
{
get
{
return _message;
}
set
{
_message = value;
Menu.showMenu();
}
}
}
Edit: to implement this using a property changed event you could do something like this. Note, I am not implementing INotifyPropertyChanged as to keep the static class.
class Program
{
static void Main(string[] args)
{
Configuration.PropertyChanged += (sender, e) =>
{
Menu.showMenu();
};
int choice;
while (true)
{
Menu.showMenu();
choice = Convert.ToInt32(Console.ReadLine());
switch (choice)
{
case 1:
Configuration.Message = "HELLO!";
break;
case 2:
Configuration.Message = "HI!";
break;
case 3:
Configuration.Message = "WHAT?!";
break;
}
}
}
}
class Menu
{
public static void showMenu()
{
Console.Clear();
Console.WriteLine("1: SOMETHING");
Console.WriteLine("2: SOMETHING");
Console.WriteLine("3: SOMETHING");
Console.WriteLine("SYSTEM MSG: " + Configuration.Message);
Console.Write("INPUT: ");
}
}
public static class Configuration
{
public static event PropertyChangedEventHandler PropertyChanged;
private static string _message;
public static string Message
{
get
{
return _message;
}
set
{
if (value != _message)
{
_message = value;
NotifyPropertyChanged(property: _message);
}
}
}
private static void NotifyPropertyChanged(object property, String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(property, new PropertyChangedEventArgs(propertyName));
}
}
}
Make the menu appear when the user hits enter.
It is not a good idea to write to the console except in response to input from the user. The reason for this is that you might write to the console in the middle of them typing out the line they want. Then their text and backspace keys will become out of synch, and it will become difficult for the user to understand what's going on.
My recommendation would be to add another option so the user can just hit ENTER without a choice and it will re-display the menu without the clear. This will allow the user to decide when they want to refresh in realtime by just hitting ENTER and not selecting an option.
If you truly want a more realtime approach, and want to mix it with user input, I would suggest that the console is not a good way to deliver this solution.

Categories