I'm very new to C# and have a very limited understanding of the "proper code" to use. I had the goal to imitate the old Pokemon battle systems as best I could with what I know and am having a hard time linking a stored int value for HP between two methods (assuming that's the right word), to calculate new Hp when the second method interacts with the main method. Had a hard time finding an answer for that in searches so here is the code:
" static void Main(string[] args)
{
Random Gen = new Random();
int enemyhealth = (150);
int playerhealth = (100); //the line i need to use
int edefense = (20);
int pattack = (30);
int rate = Gen.Next(1,5);
int critical = 0; "
static void enemyattack()
{
Random Gen1 = new Random();
int pdefense = (20);
int eattack = (20);
int erate = Gen1.Next(1, 5);
int ratattack = Gen1.Next(1,3);
int critical1 = 0;
Console.WriteLine("Enemy Ratta gets ready!");
Console.ReadKey();
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("\nEnemy Ratta attacks!\n");
Console.WriteLine("----------------------------------------------------------------------------");
ratattack = Gen1.Next(1,3);
if (ratattack = 1)
{
Console.WriteLine("Enemy Ratta used Tail Whip!");
pdefense = (pdefense - erate);
Console.ReadKey();
Console.WriteLine("----------------------------------------------------------------------------");
erate = Gen1.Next(1, 5);
if (erate <= 3)
{
Console.WriteLine("\nIt wasn't very effective!");
}
else
{
Console.WriteLine("\nIt was super effective!");
}
Console.WriteLine("Squirtle's Defense decreased by " + erate + "");
Console.WriteLine("----------------------------------------------------------------------------");
}
else if (ratattack == 2)
{
Console.WriteLine("\nRatta used Tackle");
erate = Gen1.Next(1, 5);
if (erate >= 5)
{
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("\nCRITICAL HIT!!!!");
Console.WriteLine("----------------------------------------------------------------------------");
Console.WriteLine("----------------------------------------------------------------------------\n");
Console.ReadKey();
Console.WriteLine("It was super effective!");
Console.ReadKey();
eattack = eattack + 10;
}
else
{
critical1 = Gen1.Next(1, 5);
eattack = critical1 + eattack;
}
phealth = Math.Abs((eattack - pdefense) - playerhealth); ***//This Line is where I'm having trouble because phealth is used in my first method as a stored integer and the new calculation for phealth won't interact with the phealth in the origional main, i simply belive I haven't learned that part of c#, I only have 5 hours of youtube tutorials.***
Console.WriteLine("Ratta dealt " + Math.Abs(eattack - pdefense) + " damage!");
eattack = 30;
Console.WriteLine("\n----------------------------------------------------------------------------");
Console.ReadKey();
Console.ReadKey();
}
}
}
}
Make Static method , or simply add your variable in the main Class (where Main method Stored)
Here example
class Program
{
int HP;
int Main()
{
HP=0; //Now you HP is 0;
Method();
}
void Method()
{
HP+=50; //Now you HP is 50
}
}
I would break things down into separate classes. For example you should have a Player class that contains all the information for the player. You can't have methods like that in your main program. You need to keep everything separate. Make a class for each object you need.
public class Player
{
int currentHp = 100;
int maxHp = 100;
int atkPower = 20;
int defense = 20;
string playerName = "Ashe"
public Player() {}
public void TakeDamage(int damage)
{
currentHp = currentHp - damage;
}
}
public class Enemy
{
int currentHp = 100;
int maxHp = 100;
int atkPower = 20;
int defense = 20;
string enemyName= "Rattata"
public Enemy(){}
public int AttackPlayer(Player player)
{
// all of your attack logic, pass in the player here
player.TakeDamage(someAmountofDamage);
}
}
Then in your main program:
static void Main(string[] args)
{
Player myPlayer = new Player();
Enemy myEnemy = new Enemy();
myEnemy.AttackPlayer(player);
}
Related
I have a very simple C# program, with several switch cases.
Every case uses the same function with the only difference variable value - that is, everything is hard-coded. Not pretty but it works.
Instead of repeating the same function, i tried to define classes/methods which is called instead. But it does not work as intended.
First, in my program I declare the following variables;
int hp = 100;
int gold = 10;
Then I have a switch/cases with the following (part of) function;
int monster2 = 10;
gold = gold - 2;
while (monster2 > 0 && hp > 0)
{
int dmgdone = rnd.Next(5, 15);
Console.WriteLine("You deal " + dmgdone);
monster2 = monster2 - dmgdone;
int dmg = rnd.Next(1, 10);
Console.WriteLine("You take " + dmg);
hp = hp - dmg;
if (monster2 <= 0)
{
Console.WriteLine("Monster is slain");
gold = gold + 1;
}
if (hp <= 0)
{
Console.WriteLine("You where killed");
}
}
Console.ResetColor();
break;
Point is that the function adjust the variables hp and gold, and when the function ends, the user gets back to the beginning of the switch function with "correct" value of hp and gold.
I did try to write class/methods with the same function for every switch cases with the correct parameter value for the methods. However, the variable value of hp and gold is constantly 100 and 10 when using this method, it doesnt get changed in the main method. How do I change the variables in the main method, from the functions/methods in a different class?
Here is how I did the new solution;
I called the method with;
loc.goToLocation1();
and here is the class for the above;
class location1
{
public void useYourSword(int hp, int gold, string name, string age)
{
Random rnd = new Random();
int monster = 10;
gold = gold - 1;
while (monster > 0 && hp > 0)
{
int dmgdone = rnd.Next(1, 10);
Console.WriteLine("You deal " + dmgdone);
monster = monster - dmgdone;
int dmg = rnd.Next(1, 10);
Console.WriteLine("You take " + dmg);
hp = hp - dmg;
if (monster <= 0)
{
Console.WriteLine("Monster is slain");
gold = gold + 1;
}
if (hp <= 0)
{
Console.WriteLine("You where killed");
}
}
Console.ResetColor();
}
}
primitive variables of the type int or float are what are called value types, which means that the variable refers to the value of those items, and if you copy the variable, or pass it to a function, you copy the data it contains.
There are also reference types, like instances of classes(AKA objects) where the variable refers to an address, and that address points to the data. In these cases, there is only one set of data per object, and when you copy the variable or pass it to a function, you only copy the address which points to the same data.
So, if you had a class for Player, and you passed the player to your method, and you changed it's HP, you would be able to observe that change from your caller method
Example:
public class Player
{
public int HP{get; set;}
public Player()
{
HP = 100;
}
}
...
public static void Main(string[] args)
{
Player player = new Player();
reduceHP(player);
Console.WriteLine("HP: {0}, player.HP);
}
public static void reduceHP(Player player)
{
player.HP -= 10;
}
of course, you can also use the ref and out keywords, but it's not a very good design to use them unless they're really needed
Even though you definetely shouldn't use OOP (i.e. working with classes and objects) like that, you could use references. It would work like that:
internal static class P
{
private static void Main ()
{
int hp = 100;
int gold = 10;
Console.WriteLine("Before:");
Console.WriteLine($"\tHP: {hp}\n\tGold: {gold}\n");
location1 loc1 = new location1();
loc1.useYourSword(ref hp, ref gold, "", "");
Console.WriteLine("After:");
Console.WriteLine ($"\tHP: {hp}\n\tGold: {gold}");
Console.ReadLine ();
}
}
class location1
{
public void useYourSword (ref int hp, ref int gold, string name, string age)
{
Random rnd = new Random ();
int monster = 10;
gold = gold - 1;
while (monster > 0 && hp > 0)
{
int dmgdone = rnd.Next (1, 10);
Console.WriteLine ("You deal " + dmgdone);
monster = monster - dmgdone;
int dmg = rnd.Next (1, 10);
Console.WriteLine ("You take " + dmg);
hp = hp - dmg;
if (monster <= 0)
{
Console.WriteLine ("Monster is slain");
gold = gold + 1;
}
if (hp <= 0)
{
Console.WriteLine ("You where killed");
}
}
Console.ResetColor ();
}
}
Which results in:
Before:
HP: 100
Gold: 10
You deal 5
You take 8
You deal 4
You take 2
You deal 5
You take 1
Monster is slain
After:
HP: 89
Gold: 10
class Myclass
{
public string Driver1()
{
string a = "";
Console.Write("Please enter drivers name: ");
a = Console.ReadLine();
return a;
}
public int numberOfTrips()
{
int a = 0;
{
Console.Write("Enter the number of trips: ");
a = Convert.ToInt32(Console.ReadLine());
}
return a;
}
public List<float> Payments()
{
List<float> a = new List<float>();
float input;
for (int i = 0; i<numberOfTrips(); i++)
{
Console.Write("Enter payment {0}: ", (1 + i));
input = float.Parse(Console.ReadLine());
Console.WriteLine("Payment added");
a.Add(input);
}
return a;
}
}
class Program
{
static void Main(string[] args)
{
Myclass a = new Myclass();
string name = a.Driver1();
int trip = a.numberOfTrips();
float total = a.Payments().Sum();
Console.WriteLine("\nDriver: {0}\n" + "Number of trips: {1}\n" + "Total payment: {2}\n", name, trip, total);
}
}
The issue i am having is that the "public int numberOfTrips()" method is running twice before it gets to the method containing the for loop. I think this is to do with the fact i am using it within the for loop to specify when the loop should stop. I am guessing i have done this wrong so how would i correct this? I need the user to be able to set the how many times it will ask for payment.
Any help is appreciated.
Just pass the number from numberOfTrips as a parameter to Payments:
public List<float> Payments(int tripCount)
{
List<float> a = new List<float>();
float input;
for (int i = 0; i < tripCount; i++)
{
Console.Write("Enter payment {0}: ", (1 + i));
input = float.Parse(Console.ReadLine());
Console.WriteLine("Payment added");
a.Add(input);
}
return a;
}
In your Main method:
Myclass a = new Myclass();
string name = a.Driver1();
int trip = a.numberOfTrips();
float total = a.Payments(trip).Sum();
Instead of calling numberOfTrips() in Main() as well as in Payments() you might try creating an instance variable or static variable in MyClass. Then you can fetch the number of trips from that variable after all payments are calculated.
That is correct. The first time it runs is in Main to set the 'trip' variable. The second time it runs is in Payments, inside the for loop declaration.
I'll keep this succinct. I am learning C# and exploring the possibilities of the language. Being a python programmer by heart, I am fairly new to the .NET realm.
I am currently writing a Towers of Hanoi console application. I already understand the recursion part of the code as that is not challenging.
Here is my current code for my peg class.
namespace Tower_of_hanoi
{
class PegClass
{
private int pegheight;
private int y = 3;
int[] rings = new int[0];
public PegClass()
{
// default constructor
}
public PegClass(int height)
{
pegheight = height;
}
// other functions
public void AddRing(int size)
{
Array.Resize(ref rings, rings.Length + 1);
rings[rings.Length - 1] = size;
}
public void DrawPeg(int x)
{
for (int i = 1; i <= pegheight; i++)
{
Console.SetCursorPosition(x, y);
Console.WriteLine("|");
y++;
}
if (x < 7)
{
x = 7;
}
Console.SetCursorPosition(x - 7, y); // print the base
Console.WriteLine("----------------");
}
}
}
And this is my code for the main class to display the pegs. I have facilitated the printing of the pegs by putting them in a method.
namespace Tower_of_hanoi
{
class Program
{
static void Main(string[] args)
{
PegClass myPeg = new PegClass(8);
PegClass myPeg2 = new PegClass(8);
PegClass myPeg3 = new PegClass(8);
DrawBoard(myPeg, myPeg2, myPeg3);
Console.ReadLine();
}
public static void DrawBoard(PegClass peg1,PegClass peg2,PegClass peg3)
{
Console.Clear();
peg1.DrawPeg(20);
peg2.DrawPeg(40);
peg3.DrawPeg(60);
}
}
}
My question remains,
How does one move "rings" over to "pegs" in a console application? I understand how this would work in WinForms, but I want a challenge.
Thank you everyone in advance,
youmeoutside
All you have to do ,is modify the DrawPeg method to accept the number of current "rings"
public void DrawPeg(int x, int numberOfRings = 0)
{
for (int i = pegheight; i >= 1; i--)
{
string halfRing = new string(' ', i);
if (numberOfRings > 0)
{
if (i <= numberOfRings)
halfRing = new string('-', numberOfRings - i + 1);
}
Console.SetCursorPosition(x - halfRing.Length * 2 + i + (halfRing.Contains("-") ? (-i + halfRing.Length) : 0), y);
Console.WriteLine(halfRing + "|" + halfRing);
y++;
}
if (x < 7)
{
x = 7;
}
Console.SetCursorPosition(x - 7, y); // print the base
Console.WriteLine("----------------");
}
Then ,you can call your DrawBoard method with your current values (Now they are hard-coded)
public static void DrawBoard(PegClass peg1, PegClass peg2, PegClass peg3)
{
Console.Clear();
peg1.DrawPeg(20, 1);
peg2.DrawPeg(40, 2);
peg3.DrawPeg(60, 4);
}
Now all you have to do ,is call the methods with different numbers of rings every time your player makes a move
The program is a simple number guessing game however when i randomize the guesses unity tends to pick the same number multiple times is there a way to have it know what numbers it already picked? an also is there a way to make it automatically go to the lose scene if it can't pick another number? any help is appreciated ^_^
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class NumberGuesser : MonoBehaviour {
int min;
int max;
int guess;
int maxGuessesAllowed = 15;
public Text text;
//guess = (max + min) / 2;
// Use this for initialization
void Start () {
min = 1;
max = 1000;
NextGuess();
max = max + 1;
}
// Update is called once per frame
public void guessHigher () {
min = guess;
NextGuess ();
}
public void guessLower() {
max = guess;
NextGuess();
}
void NextGuess(){
guess = (max + min) / 2;
//guess = Random.Range (min,max);//Randomizes Guesses
//print (guess);
text.text = guess.ToString ();
maxGuessesAllowed = maxGuessesAllowed - 1;
if (maxGuessesAllowed <= 0) {
Application.LoadLevel ("Win");
}
}
}//main
Try this:
List<int> alreadyGuessed = new List<int>();
...
int NextGuess()
{
int theGuess = Random.Range(min, max);
while(alreadyGuessed.Contains(theGuess))
theGuess = Random.Range(min, max);
alreadyGuessed.Add(theGuess);
return theGuess;
}
It keeps track of what has been guessed and keeps on guessing until the guess has not been guessed before.
Just add this at top of your code
List<int> used = new List<int>();
you may want to add this using too
using System.Collections.Generic;
and then change your NextGuess function to this
void NextGuess()
{
guess = Random.Range (min,max);
while(used.Contains(guess))
guess = Random.Range (min,max);
used.Add (guess);
text.text = guess.ToString ();
maxGuessesAllowed = maxGuessesAllowed - 1;
if (maxGuessesAllowed <= 0) {
Application.LoadLevel ("Win");
}
}
I am trying to learn C# and doing some questions i googeld. This is the task to do:
*"Beginner level:
The task is to make
a dice game where the user throws 3
Each 12-sided dice (numbers
shall be randomly selected and stored in an array / field or list).
Add up the total of the dice and show on the screen.
Create a function / method that accepts a figure
(the total sum of the dice). Function / method
should return the text "Good throw" if the figure
is higher or equal to 20.
In all other cases, the text
"Sorry" is returned.
Call the function / method in the main method
and prints the total and the text.
Advanced level:
This is an extension of the task where you must use a class to simulate a dice. The user shall have the option of writing a x y-sided dice himself.
If the total sum of a roll of the dice generates a score that is> 50% of the maximum score, the words "good throw" is displayed.
This logic can be in your main method.
Create the class described in the class diagram and use appropriate
way in your code."*
The thing is that i cant get it to work, the array in my class do not save my numbers im typing in... I only get the reslut 0. I think i have just done some big misstake i cant see...
This is the Main code:
static void Main(string[] args)
{
List<Dice> _Dice = new List<Dice>();
int a = 0;
int times = int.Parse(Interaction.InputBox("Write how many times you want to repeat the game:"));
while (a != times)
{
int antThrow = int.Parse(Interaction.InputBox("Write how many times you want each dice to get thrown:"));
int xChoice = int.Parse(Interaction.InputBox("Write how many dice you want to throw:"));
int yChoice = int.Parse(Interaction.InputBox("Write how many sides you want each dice should have:"));
_Dice.Add(new Dice(xChoice,yChoice, antThrow));
a++;
}
int e = 1;
foreach (var item in _Dice)
{
Interaction.MsgBox(string.Format("Result of game {0}: {1}", e++, item.Tostring()));
}
}
This is the Dice class:
class Dice
{
static int _xChoice, _yChoice, _throw;
static List<int> sum = new List<int>();
static int w = 0;
static int _sum;
static int[,] dice = new int[_xChoice, _yChoice];
public string Tostring()
{
int half = _sum / 2;
if (half <= _sum/2)
{
return "Good throw!" + _sum;
}
else
{
return "Bad throw!";
}
}
void random()
{
Random rnd = new Random();
while (w != _throw)
{
for (int i = 0; i < dice.GetLength(0); i++)
{
for (int j = 0; j < dice.GetLength(1); j++)
{
dice[i, j] = rnd.Next(1, _yChoice);
_sum += dice[j, i];
sum.Add(_sum);
}
}
w++;
}
}
public Tarning(int Xchoice, int Ychoice, int throw)
{
_throw = thorw;
_xChoice = Xchoice;
_yChoice = Ychoice;
}
}
Your main problem is in the static keyword. Static field means that there's only
one field for all the instances, which is not your case: you need each instance of Dice has its own fields' values.
class Dice {
// no static here
private int _xChoice, _yChoice, _throw;
// no static here
private List<int> sum = new List<int>();
// no static here
private int w = 0;
// no static here
private int _sum;
// no static here
private int[,] dice = new int[_xChoice, _yChoice];
// BUT, you want a random generator for all the instances, that's why "static"
private static Random rnd = new Random();
// When overriding method mark it with "override"
// And Be Careful with CAPitalization:
// the method's name "ToString" not Tostring
public override string ToString() {
...
}
void random() {
// Do not create Random generator each time you call it:
// It makes the random sequences skewed badly!
// Istead use one generator for all the calls, see the code above
// private static Random rnd = new Random();
// Random rnd = new Random();
...
}
...
class Program
{
static void Main(string[] args)
{
var dice = new List<DiceLogic>();
int a = 0;
int times = GetTimes();
while (a != times)
{
int antThrow = GetAntThrow();
int xChoice = GetXChoice();
int yChoice = GetYChoice();
dice.Add(new DiceLogic(xChoice, yChoice, antThrow));
a++;
}
int e = 1;
foreach (var item in dice)
{
Console.WriteLine("Result of game {0}: {1}", e++, item.Tostring());
}
Console.ReadLine();
}
private static int GetTimes()
{
while (true)
{
Console.WriteLine("Write how many times you want to repeat the game:");
int times;
var result = int.TryParse(Console.ReadLine(), out times);
if (result) return times;
Console.WriteLine("Value must be a number.");
}
}
private static int GetAntThrow()
{
while (true)
{
Console.WriteLine("Write how many times you want each dice to get thrown:");
int antThrow;
var result = int.TryParse(Console.ReadLine(), out antThrow);
if (result) return antThrow;
Console.WriteLine("Value must be a number.");
}
}
private static int GetXChoice()
{
while (true)
{
Console.WriteLine("Write how many dice you want to throw:");
int getXChoice;
var result = int.TryParse(Console.ReadLine(), out getXChoice);
if (result) return getXChoice;
Console.WriteLine("Value must be a number.");
}
}
private static int GetYChoice()
{
while (true)
{
Console.WriteLine("Write how many sides you want each dice should have:");
int getXChoice;
var result = int.TryParse(Console.ReadLine(), out getXChoice);
if (result) return getXChoice;
Console.WriteLine("Value must be a number.");
}
}
}
public class DiceLogic
{
public string Tostring()
{
int maxScore = _diceSides*_dices;
if (_result >= maxScore / 2)
{
return "Good throw! " + _result;
}
return "Bad throw! " + _result;
}
private readonly int _dices;
private readonly int _diceSides;
private readonly int _throwDice;
private int _result;
private void CalculateResult()
{
var rnd = new Random();
for (int i = 0; i < _dices; i++)
{
int currentResult = 0;
for (int j = 0; j < _throwDice; j++)
{
currentResult = rnd.Next(0, _diceSides);
}
_result += currentResult;
}
}
public DiceLogic(int dices, int diceSides, int throwEachDice)
{
_dices = dices;
_diceSides = diceSides;
_throwDice = throwEachDice;
CalculateResult();
}
}
This is an example of how you could implement what they are asking, go through te code line by line with the debugger so you understand what is going on.
You never call the method random(). Therefore, the value of your member variable _sum is never changed and remains 0. You need to call the method random() somewhere. You should probably make it public and call it from your main method after you have set up all your dice.
Furthermore, your member variables in the Dice class are all static! That means that the different Dice instances will all share the same values. I think this is not intended. You should make the variables instance variables by removing the static modifier.
Your method Tarning is not called and it takes a reserved word “throw” [I believe it was supposed to be thorw]. The method is not void so it must return a type.
Random() is not invoked and does display anything.
Dice has not constructor that has 3 arguments within its braces but it’s declared as _Dice.Add(new Dice(xChoice,yChoice, antThrow));