Using another classes function in c# - c#

im trying to be able to call the function from the dieclass and use the roll number in the matchplay class... is this possible?
public class DieClass
{
public void DiceRoll(int min, int max)
{
Random random = new Random();
int roll1 = random.Next(0, 6);
int roll2 = random.Next(0, 6);
int roll3 = random.Next(0, 6);
}
}
public class MatchPlay
{
public void Match()
{
DieClass.DiceRoll();
Console.WriteLine("Starting Match Play...");
Console.WriteLine();
Console.WriteLine("Round One");
Console.WriteLine("Your first dice is [0]", roll1);
Console.WriteLine("Your second dice is [0]", roll2);
Console.WriteLine("Your third dice is [0]", roll3);
}
}
}

There are a few things that need fixin':
Your DiceRoll method is an instance method, so you'd need to create an instance of the DiceClass class in order to use it.
The roll1, roll2, and roll3 variables are local to the method, so you won't be able to use them once the method completes. Instead, you might make them public properties of the class.
You don't need to instantiate a new Random every time the method is called (in fact this can lead to problems because Random is seeded with a value based on the system clock, so if your method is called very rapidly, it will produce the same numbers over and over). You can just make it static and instantiate it once.
Since you're taking in min and max arguments to the Roll method, shouldn't we use them? You currently have 0 and 6 hard-coded.
To use a format string, you need to use the curley braces ({}) instead of square brackets ([]).
Finally, from a naming convention point of view, you don't need the word Class as part of your class name, and you don't need Dice as part of the method name. This will simplify the amount of typing, and will still be very understandable.
What you might consider doing is creating a class that represents a single Die object, and give it a Roll() method and a Value property. Then the user can create as many as they like and keep them in a List:
public class Die
{
public int Value { get; set; }
// Make this static and instantiate it only once to avoid re-seeding issues
private static readonly Random rnd = new Random();
public Die()
{
Value = 1;
}
public void Roll()
{
// This method uses values 1-6 as a standard die
Roll(1, 6);
}
public void Roll(int minValue, int maxValue)
{
Value = rnd.Next(minValue, maxValue + 1);
}
}
Now, you can use the Die class as follows:
public class MatchPlay
{
public void Match()
{
// Add three Die objects to our list of dice
List<Die> dice = new List<Die>
{
new Die(), new Die(), new Die()
};
Console.WriteLine("Starting Match Play...");
Console.WriteLine();
Console.WriteLine("Round One");
// Roll all dice
dice.ForEach(d => d.Roll());
Console.WriteLine("Your first dice is {0}", dice[0].Value);
Console.WriteLine("Your second dice is {0}", dice[1].Value);
Console.WriteLine("Your third dice is {0}", dice[2].Value);
}
}
Finally, we can kick off a match in our Main method:
private static void Main()
{
MatchPlay game = new MatchPlay();
game.Match();
Console.WriteLine("\nDone!\nPress any key to exit...");
Console.ReadKey();
}

Either you need to make DiceRoll a static method, or create an instance of DieClass and call your method through that.
For example, you may declare your method as
public static void DiceRoll(int min, int max)
Or you can instantiate an object like:
DieClass dice = new DieClass();
dice.DiceRoll(0, 6);
That being said, you have other problems with your DieClass class, the most obvious of which is you need a means of communicating the result back to the caller. The easiest approach would be to have DiceRoll() generate a single result and return that. Also, you've hardcoded 0 and 6 as your params to random.Next() despite the method expecting a pair of parameters min and max.

Related

How to write a function that takes an integer as a parameter and calculates and returns the squared value

Ahoy! I have just started methods but I am a tad confused when it comes to methods with math. First post so be nice :) I'm aware I out in NumberToSquare way too many times!
Write a program that asks the user to enter a number. In your program write a function called SquareValue that takes an integer parameter and calculates the square of integer parameter and returns this squared value. Your program should take this returned square value and display it. An example of the output is:
Please enter a number to square: 8
/ 8 squared is: 64
What I have so far is not so comprehensible. I thought along a few different avenues and was unsure as to what to delete. Help please.
namespace SquareValue
{
class Program
{
static void Main(string[] args)
{
int number=NumberToSquare();
SquareValue(NumberToSquare * NumberToSquare);
string output;
Console.ReadKey();
}
public int SquareValue(NumberToSquare, NumberToSquare);
{
int result = NumberToSquare * NumberToSquare;
return result;
Console.WriteLine("{0} squared is "+result");
}
public int NumberToSquare()
{
Console.WriteLine("Please enter a number to square: ");
int NumberToSquare = Console.ReadLine();
return NumberToSquare;
}
}
I see no reason to over complicate this:
public int Square(int x)
{
return (x * x);
}
or
public int Square(int x)
{
return Math.Pow(x,2);
}
Or just use Math.Pow as it exists with 2 as the Power Of number.
You seem very green on programming and I'm not sure SO is a place to go to learn the basics, but I'll run through what you've done and explain what's going wrong.
Your original program concept is fine but there are many issues with basic syntax. I understand you mightn't be familiar with reading compiler errors so I'll explain the errors that I see just reading through the code...
You put a ; at the end of the SquareValue(..., ...) method which teeminates the declaration so the body in braces isn't part of the method, then things go haywire later on.
You're not passing in the value captured from the NumberToSquare method...
int number=NumberToSquare();
SquareValue(NumberToSquare * NumberToSquare);
NumberToSquare isn't a defined variable so NumberToSquare * NumberToSquare can't calculate, what you'd want is number * number where `number is the value entered by the user.
Your definition of int SquareValue(NumberToSquare, NumberToSquare) expects two parameters although you haven't speified the type. It should be
int SquareValue(int NumberToSquare, int NumberToSquare)
but you have the same variable declared twice which is another error and then you aren't passing two parameters anyway. You want to multiply a number by itself therefore you only have a single source number so why declared two parameters? You need a single parameter method
int SquareValue(int NumberToSquare)
and call like this
int number=NumberToSquare();
SquareValue(number);
Now the SquareValue() method returns an int but you never capture it in the calling code and display the result in the method. Follow the idea in this app that the Main method will do all the orchestration and display, but the SquareValue() method should ONLY do a calculation and not any I/O. I'd also rename the NumberToSquare() method a as what is actually happening ... GetNumberToSquareFromUser().
And there's also a stray " before the closing bracket.
Console.WriteLine("{0} squared is " + result");
And you defined a string output variable which is never used.
And your methods need to be static because main(..) is a static method, not instance. If you declare a Squaring class and instantiated it then you could call non static methods from that.
Also ReadLine() returns a string which can't be assigned to an int.
And finally the result line is implicitly using String.Format behind the scenes but you haven't specified the original number for the {0} token. You could also use interpolation. You could do either of these
Console.WriteLine("{0} squared is " + result, number);
Console.WriteLine($"{number} squared is " + result);
So here's your program revised
class Program
{
static void Main(string[] args)
{
int number = GetNumberToSquareFromUser();
int result = SquareValue(number);
Console.WriteLine("{0} squared is " + result, number);
Console.ReadKey();
}
public static int SquareValue(int numberToSquare)
{
return numberToSquare * numberToSquare;
}
public static int GetNumberToSquareFromUser()
{
Console.WriteLine("Please enter a number to square: ");
int NumberToSquare = int.Parse(Console.ReadLine());
return NumberToSquare;
}
}
I hope this help, I know it's alot to take in, but I hope you take the time to read and really understand rather than just blindly submit the revised version.
When writing your methods, make them reusable. When you start using a method to output to the console in addition to its primary purpose (i.e. to square a number), its re-usability becomes minimal. It is much better to keep specific code in your main method, and put sub tasks into separate methods, such as squaring a number. Now, whenever you need to square a number, you already have a perfectly good method for that.
I didn't handle the case for users entering bad input, but that can be done in the else of the TryParse if block.
static void Main(string[] args)
{
int squredNum = 0;
int NumberToSquare = 0;
Console.WriteLine("Please enter a number to square: ");
if(int.TryParse(Console.ReadLine(), out NumberToSquare))
{
squredNum = SquareValue(NumberToSquare);
Console.WriteLine("{0} squared is {1}", NumberToSquare, squredNum);
}
Console.ReadKey();
}
static int SquareValue(int numberToSquare)
{
return numberToSquare * numberToSquare;
}
p.s. I would not recommend using Math.Pow() to square a number. No need to kill a fly with a bazooka!
Here is an example of such program with robust handling:
using System;
namespace ConsoleApp1
{
internal static class Program
{
private static void Main(string[] args)
{
while (true)
{
Console.WriteLine("Enter value to square or X to exit");
var line = Console.ReadLine();
if (line == null)
continue;
if (line.Trim().Equals("X", StringComparison.InvariantCultureIgnoreCase))
{
Console.WriteLine("Exitting ...");
break;
}
int result;
if (!int.TryParse(line, out result))
continue;
Console.WriteLine(result * result);
}
}
}
}
See the docs online, understand each statement, write your very own program then as your teacher will likely figure out you didn't pull that solely by yourself :)

random number in constructor c#

I am a student taking an introductory programming course in line with game development. One of my assignments calls for me to define a players attack damage inside of the constructor. I want the damage to be random, but no matter what I do I get back the same number. This is a test I made to see how I can get this number to be random.
class MainChar
{
public static Random random = new Random();
public int Atk;
public MainChar()
{
this.Atk = random.Next(11);
}
public void h()
{
while (Atk != 10)
{
Console.WriteLine(Atk);
}
}
}
I'm creating a new instance of MainChar in my main program, and running h(). I get a repeating list of the same number instead of random numbers between 1 and 10. Any ideas?
P.S. This thread was useful, but could not answer my question.
In the method h(), the while forms an infinite loop if the atk!=10. so you need to specify an exit condition there to break the loop; you can use like this:
public void h()
{
while (Atk != 10)
{
this.Atk = random.Next(11);
}
Console.WriteLine(Atk);
}
Now you will get a random number between 0 and 11 and is not 10 in the console
if you want to continue with a random number until it generate a breaking condition or number, you can modify the h() func as:
public int Atk;
public static int max = 100;
public void h()
{
while (Atk != 10)
{
this. Atk = random.Next(max);
Console.WriteLine(Atk);
}
}

Having an integer inside a method that increases by 1 everytime the method was called to a specific object of a lass

I have a 'Movie' class in my C# code that has an int[] ratings = new int[10]; as a field. I would like to place numbers in this empty array from my main program.
For that, I would need a method, that could point to the actual free index of the array to put the integer there, but the other integer that would point to the free index would be reset to 0 everytime the method is called. Thus, my question is, that how can I place an integer in my method that is increased everytime the method was called.
This is the method in the class:
public void Rate(int rating)
{
int x = 0;
ratings[x] = rating;
}
This is how I call it in the main program
Movie asd = new Movie(blabla...);
Rate.asd(1);
Rate.asd(1);
Rate.asd(1);
So I called it 3 times, and I would want the 'x' integer in the class's method to increase.
Thanks in advance.
First of all, you have an error in the code you have posted.
As I suppose rather than:
Movie asd = new Movie(blabla...);
Rate.asd(1);
Rate.asd(1);
Rate.asd(1);
you want to paste here:
Movie asd = new Movie(blabla...);
asd.Rate(1);
asd.Rate(1);
asd.Rate(1);
As C# does not allow to use static method variables (like i.e. C++ does) you have two options:
first, make x value (from Rate method) a Movie's class variable, so Rate method will "remember" the next index,
second (and better) rather than intiger array - if possible use any kind of list or queue (which can manage indexing for you).
The problem is that local variables are discarded when exiting a method.
class SomeClass
{
private int x = 42;
public void DoSometing(int y)
{
int a = y + 5;
x += a * a;
// a stops to exist here
}
}
Solution is to store the variable in the containing class as well
class SomeOtherClass
{
private int x = 42;
private int a = 0;
public void DoSomething(int y)
{
a = y + 5;
x += a * a;
}
}
Now SomeOtherClass remembers the value of a. That's basically the point of member variables a.k.a. fields - to store the state of the object.
More appropriate for your problem:
class ClassWithAnArrayAndCount
{
private int[] values = new int[10];
private int taken = 0;
public void Add(int value)
{
if (taken == 10)
throw new ArgumentOutOfRangeException(); // sorry, no more space
values[taken++] = value;
}
public int Taken { get { return taken; } }
}

Randomly Picking Up An Object In The Array List

Can i use the random class to retrieve an object randomly from an array list and i know i can't store this randomly retrieved object in variable
using System;
using System.Threading;
using System.Collections;
namespace ThreadSample
{
class FunWithVehicles
{
public void VehicleThread1()
{
Console.WriteLine("Type Of Vehicle Is Car\nRegisteration Number Is: TN0098 1234\nLicense Number Is APK32456\nVehicle Number Is 1");
}
public void VehicleThread2()
{
Console.WriteLine("Type Of Vehicle Is Van\nRegisteration Number Is: TN0012 2385\nLicense Number Is UKL37899\nVehicle Number Is 2");
}
public void VehicleThread3()
{
Console.WriteLine("Type Of Vehicle Is Truck\nRegisteration Number Is: TN1798 8907\nLicense Number Is MNT59863\nVehicle Number Is 3");
}
public void VehicleThread4()
{
Console.WriteLine("Type Of Vehicle Is Tanker\nRegisteration Number Is: TN3987 5357\nLicense Number Is RTJ23498\nVehicle Number Is 4");
}
public void VehicleThread5()
{
Console.WriteLine("Type Of Vehicle Is Bus\nRegisteration Number Is: TN9768 3212\nLicense Number Is RTJ98734\nVehicle Number Is 5");
}
}
class TollGate
{
\\ retrieving the randomly stored object happens here and it will check a parameter
\\ The Parameter Function is to check whether the sent object was already sent and to see whether the previous number is remaining since all the threads have to be sent sequentially
}
class Simulate
{
public static void Main()
{
Simulate s = new Simulate();
Simulate n = new Simulate();
FunWithVehicles f = new FunWithVehicles();
ThreadStart Ref1 = new ThreadStart(f.VehicleThread1);
ThreadStart Ref2 = new ThreadStart(f.VehicleThread2);
ThreadStart Ref3 = new ThreadStart(f.VehicleThread3);
ThreadStart Ref4 = new ThreadStart(f.VehicleThread4);
ThreadStart Ref5 = new ThreadStart(f.VehicleThread5);
Thread Th1 = new Thread(Ref1);
Thread Th2 = new Thread(Ref2);
Thread Th3 = new Thread(Ref3);
Thread Th4 = new Thread(Ref4);
Thread Th5 = new Thread(Ref5);
ArrayList items = new ArrayList();
items.Add(Th1);
items.Add(Th2);
items.Add(Th3);
items.Add(Th4);
items.Add(Th5);
Random rnd = new Random();
int r = rnd.Next(items.Count);
// storing will happen here and it will be sent to the TollGate class to check the parameter
// If there are no previous numbers and if is not sent, it will be processed and displayed in the TollGate class and decremented from the array list right here in the simulate class, so the next time only 4 objects will be remaining and once all the threads are processed the application stops
}
}
I want to randomly pick an object and store it so that it can be sent to another class. I don't know what exactly to put in the The Parameter Function to make it work and how to make the decrements part of it work.
Any help would be appreciated.For the display i got Thread.Start(); but how to fuse it in the existing code to make it work. How to Number the threads or function so that it knows about processing the threads sequentially.
Why not.
Use Random class Next(int minvalue, int maxvalue) method to give value less than the length of the array list.
Then use that random value as index to get value from array list.
This way
ArrayList ar = new ArrayList();
//Fill Array List
Random r = new Random();
int rand = r.Next(0, ar.Count);
var value = ar[rand];
You can use the Random you already have, and do this.
object picked = items[rnd.Next(0,items.Count)];

Random not working

To clarify, multiple students objects and all of them are getting the same value.
I know this question has been asked before, but I have had no luck with the other posts about his topic. I have a random number generator ranging from 1-3. I then us %2 to make a bool value true or false. Every time I run the program I either get all true or all false. Here is my code. I know that random is not really random. What can I do to get more random numbers.
Random random = new Random();
public Student()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
public bool readingLevel()//this always returns one value for the entire program.
{
return level;
}
You are only assigning a random value to 'level' once during the constructor, so it will always have the initial value.
Try:
public bool readingLevel()
{
return (random.Next(1,3) % 2 == 0);
}
Edit:
Static Random random = new Random();
...
It looks like you're trying to get a random number!
Clippy
Well you can try something like this:
static Random random = new Random();
public Student()
{
lock (random)
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
}
public bool readingLevel()//this always returns one value for the entire program.
{
return level;
}
The problem with your snippet seems to be that you are instantiating a new Random class with each of your class instances.
This is not the way Random is supposed to be used, but instead a single Random class instance should be used for acquiring multiple random numbers.
The Rationale for this is that Random in .Net uses a pseudo random algorithm based on state (a seed) that changes every time you ask for a new random number. By instantiating multiple random classes in a relatively short time span, there is a high chance that all of them will be initiated with the same seed (Based on system time) and all will give the same random number.
It looks like your random generator is an instance variable of the Student. Since the generator uses the current time as the seed, if you create a bunch of students within a short time, they will all have each have a generator with the same seed and the same results. You could make the random generator a static variable or, better yet, use constructor injection and pass the level into the Student's constructor.
class Student
{
private static Random random = new Random();
public Student()
{
level = random.NextDouble() < 0.5;
}
public bool readingLevel()
{
return level;
}
}
or use constructor injection so your student class is deterministic.
class Student
{
private boolean level;
public Student(boolean readingLevel)
{
this.level = readingLevel;
}
public boolean readingLevel()
{
return level;
}
}
Create only one instance of Random and reuse it. Creating multiple instances of random in quick succession seeds to the same value and thus leads to the same sequence.
If your code in single threaded you can simply use a static property to hold the instance of Random.
The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.
http://msdn.microsoft.com/en-us/library/h343ddh9.aspx
public Student()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
seems very much like a constructor for the Student class. In this constructor you are basically calculating a random number and storing it inside the level field. So if you use the same instance of Student throughout your entire program and call the readingLevel() method multiple times on this instance it will obviously return the same value -> the one that was done during the construction of this instance and that you stored in the level field.
So you might consider moving the random number generation logic into the readingLevel() method instead of simply returning the same value over and over again:
public class Student
{
private Random random = new Random();
public bool readingLevel()
{
int randomLevel = random.Next(1,3);
return (randomLevel % 2 == 0);
}
}
Now everytime you call this method on the same instance you should get a new calculation of a random number.
Some others have said this, but I think the point deserves underscoring with an example.
public class Student
{
Random random = new Random();
public Student()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
}
public bool readingLevel()//this always returns one value for the entire program.
{
return level;
}
}
public class Program
{
public static void Main()
{
var students = new List<Student>();
for (int i = 0; i < 10; i++)
students.Add(new Student());
//Now you have 10 Students; each Student has its own random number generator
//The generators were created within microseconds of each other, so they most likely have THE SAME SEED
//Because they have the same seed, they will generate identical sequences of numbers
//Each student's reading level is calculated from the first call to .Next(1, 3) on its own RNG.
//The RNGs have the same seed, so each will return the same value for the first call to .Next(1, 3)
//Therefore, all students will have the same reading level!
}
}
You are using random to simulate a true/false situation, so you are trying to limit the result to either 1 or 2. Given that you are doing an odd/even test on the result you might be better off doing:
int randomLevel = random.Next();
level = (randomLevel % 2 == 0);
Also If you create all your students in quick succession there's a good chance that your current code will return the same value for subsequent calls.
Well.
Consider what is happening here. When your Student is constructued, you get some random number, and then set it to the member variable level.
Then, at some other point, you call a function, readingLevel, which returns this previously set value.
Then, you may ponder to yourself: Exactly when would this function give a different value? Well, it will only do so when level gets a different value. And when does that happen? Well, it only happens in the constructor, so, that means, it never happens again for the life of the object ....
Try the following. Move the selection of the random level to the readingLevel function.
Random random = new Random();
public Student()
{
}
public bool readingLevel()//this always returns one value for the entire program.
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
return level;
}
That is because you are using the random.Next() and the level evaluation within the constructor of your class, remember that the constructor is only executed when you create a new instance of your object, for having it executed several times create a different method where you call the random and the level evaluation, that way you'll get different values every time or use Something like this:
public bool Level()
{
int randomLevel=random.Next(1,3);
level = (randomLevel % 2 == 0);
return level;
}
Random random = new Random(DateTime.Now.Ticks);

Categories

Resources