Code doesn't work when using Classes/methods - c#

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

Related

Create a list from a number entered by user

I've entered a number between 1 and 10, I now want to create a list to that size entered and store new integers to each element from more input.
so I enter 5 into the console, I now want to create a list of size 5, so that I can store 5 new integers into each element, here is my code so far -
I'm not looking for code to solve this, but a point in the right direction of what I need to learn to be able to do this,
thanks
using System;
using System.Collections.Generic;
namespace Monsters1
{
class Program
{
static void Main(string[] args)
{
int totalOfMonsters = numberOfMonsters();
Console.WriteLine("Total Number of Monsters = " + totalOfMonsters);
Console.WriteLine();
int numberOfHitPoints = HitPoints();//store this number into list - monstersInput?
List<int> monstersInput = new List<int>(totalOfMonsters) ;
}
public static int numberOfMonsters()
{
string monsterNumbers;
int min = 1;
int max = 10;
int result;
do
{
Console.WriteLine("Enter a number between 1 and 10 for Number of Monsters.");
monsterNumbers = Console.ReadLine();
result = int.Parse(monsterNumbers);
if (result < min || result > max) ;
else
break;
} while (true);
return result;
}
public static int HitPoints()
{
// enter a number of hit points and store to list monsters
int hitPoints;
int min = 1;
int max = 100;
string hit;
do
{
Console.WriteLine("Enter a Hit Number between 1 and 100 : ");
hit = Console.ReadLine();
hitPoints = int.Parse(hit);
if (hitPoints < min || hitPoints > max) ;
else
break;
} while (true);
return hitPoints;
}
//public static string Total()
//{
// //final output to console with element list and hit points
// do
// {
// Console.WriteLine("Monster no.? has number of hit points");
// } while (true);
//}
}
}
Since you do know about loops, the best approach I can think of is:
Ask for an integer from 1 to 10 and store it in a variable (totalOfMonsters)
Create a list with size equal to totalOfMonsters (monstersInput)
Create a loop that repeats itself "totalOfMonsters" times.
3.a Inside the loop ask on each iteration for the number of hitPoints and add it to the list.
You are already doing step 1 and 2:
static void Main(string[] args)
{
int totalOfMonsters = numberOfMonsters();
Console.WriteLine("Total Number of Monsters = " + totalOfMonsters);
Console.WriteLine();
int numberOfHitPoints = HitPoints();//store this number into list - monstersInput?
List<int> monstersInput = new List<int>(totalOfMonsters);
}
But for step 3 you have to create a loop, you had the right idea with the line:
int numberOfHitPoints = HitPoints();
The only thing missing is the loop and saving each new element on the list. Since you don't want code solutions, let me give at least and outline on how you can do this:
//Creating loop to fill the hitPoints of every monsters
int someCounter = 1;
do
{
//ask for the hitpoints
//save the hitpoints in the list
//increase the value of the counter
}
while(someCounter <= sizeOfYourList);

Method does not return random number from another method

It was hard to find right title for this problem. I had little problem earlier with this dice game and I solved it, thanks for the guys in here Stackoverflow.
My game is 99% ready now, but somehow main program cannot return the dice numbers. This game is meant to break when player have three wins and that makes him a winner. That why there is round.
Console should look like this:
Name of player 1:
Name of player 2:
Round 1
"Player 1 name": 5 + 4 = 9
"Player 2 name": 1 + 2 = 3
Round 2 et cetera
And when player get three wins it is winner. I have also two other class but problem is with Dice so I do not attach the others here.
Class game
using System;
using System.Collections.Generic;
using System.Text;
using static System.Console;
namespace Dicegame
{
static class Game
{
static int winline = 3;
static int round = 1;
public static void Aja()
{
Player p1 = new Player
(
Helpers.Syote.Merkkijono("Name of player 1: ")
);
Player p2 = new Player
(
Helpers.Syote.Merkkijono("Name of player 2: ")
);
Dice dice1 = new Dice();
Dice dice2 = new Dice();
for (int i = 1; p1.Points < winline | p1.Points < winline; i++)
{
int p1throw1 = dice1.Throw(), p1throw2 = dice2.Throw(), p1total = p1throw1 + p1throw2,
p2throw1 = dice1.Throw(), p2throw2 = dice2.Throw(), p2total = p2throw1 + p2throw2;
round++;
}
}
}
}
Class Dice
using System;
using System.Collections.Generic;
using System.Text;
using static System.Random;
namespace Dicegame
{
class Dice
{
static Random randomnumber = new Random();
public int Count { get; set; }
public int ThrowCount { get; set; }
public Dice()
{
ThrowCount = 0;
}
public int Throw()
{
int Count = randomnumber.Next(1, 7);
ThrowCount++;
return Count;
}
}
}
You simply never actualise the points of P1 or P2.
Also you use a for loop where a simple while loop would work way better:
while(p1.Points < winline || p2.Points < winline)
{
p1.AddPoints(dice1.Throw() + dice2.Throw());
p2.AddPoints(dice1.Throw() + dice2.Throw());
round++;
}
I post my solution of this I hope it helps someone in future. Commented all so it is easy to understand for beginners also.
do
{
if (p1.Points == WINLINE || p2.Points == WINLINE)
{
break; // Break this loop when either one reach WINLINE points (3)
}
else
{
// Get random numbers for each throw between 1-6 and sum them together
int p1throw1 = dice1.Throw(), p1throw2 = dice2.Throw(), p1total = p1throw1 + p1throw2,
// Get random numbers for each throw between 1-6 and sum them together
p2throw1 = dice1.Throw(), p2throw2 = dice2.Throw(), p2total = p2throw1 + p2throw2;
// Write round number which is how many times dice is thrown. Split with 2, because same dice is throwed two times in one round
WriteLine($"Round {dice1.ThrowCount / 2}");
// Write given player names and points of each throw and after all sum of those points
WriteLine($"{p1.Name}: {p1throw1} + {p1throw2} = {p1total}");
WriteLine($"{p2.Name}: {p2throw1} + {p2throw2} = {p2total}");
// If player 1 get more points than player 2, add one point for player 1 and reset player 2 points
if (p1total > p2total)
{
p1.Points++;
p2.Points = 0;
}
// If player 2 get more points than player 1, add one point for player 2 and reset player 1 points
else if (p1total < p2total)
{
p2.Points++;
p1.Points = 0;
}
else // If something else (same points for both) do nothing
{
}
}
}
while (true);
// When do loop broke print results of the game
if (p1.Points == WINLINE) // Print this if player 1 wins
{
WriteLine($"Winner of the game is {p1.Name} and total rounds: {dice1.ThrowCount / 2}.");
}
else if (p2.Points == WINLINE) // Print this if player 2 wins
{
WriteLine($"Winner of the game is {p2.Name} and total rounds: {dice1.ThrowCount / 2}");
}

Need Help fixing incorrect output to console window.

I'm working on an assignment for school that consists of both a Program.cs file and a separate class called Car. I have written all code for the Car class and pasted already provided code into the program.cs file. The resulting output is
2010 Ford Focus is going 20 MPH.
2018 Chevy Cruze is going 0 MPH.
The assignment calls for an expected output of
2010 Ford Focus is going 28 MPH.
2018 Chevy Cruze is going 18 MPH.
I need to know how to get the window to output the expected speed of 28 for Car 1 and 18 for car 2. I'm assuming that I'm not supposed to alter the code that was provided for program.cs to accomplish the right output for the application/assignment.
public class Car
{
private int Speed;
private string Make;
private string Model;
private int Year;
public Car (string make, string model, int year, int speed)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = speed;
}
public Car(string make, string model, int year)
{
this.Make = make;
this.Model = model;
this.Year = year;
this.Speed = 0;
}
public int SpeedUp()
{
this.Speed = Speed++;
return (Speed);
}
public int SlowDown()
{
if (Speed > 0)
{
this.Speed = Speed--;
}
return (Speed);
}
public void Display()
{
Console.WriteLine(Year + " " + Make + " " + Model + " is going " + Speed + " MPH.");
Convert.ToString(Console.ReadLine());
}
}
and here is the given code that goes in program.cs
class Program
{
static void Main(string[] args)
{
int car1Speed = 20;
int car2Speed = 0;
Car car1 = new Car("Ford", "Focus", 2010, car1Speed);
Car car2 = new Car("Chevy", "Cruze", 2018, car2Speed);
for (int i = 0; i < 60; i++)
{
if (i % 2 == 0)
{
car2Speed = car2.SpeedUp();
}
if (i % 3 == 0)
{
car1Speed = car1.SpeedUp();
}
if (i % 5 == 0)
{
car1Speed = car1.SlowDown();
car2Speed = car2.SlowDown();
}
}
car1.Display();
car2.Display();
}
}
The line of code
this.Speed = Speed++;
Has no effect on the value of this.Speed.
The line of code is roughly equivalent to
int temp = this.Speed; // We store the original value of Speed.
this.Speed = Speed + 1; // We add one to Speed and assign it back to Speed.
this.Speed = temp; // We immediately replace Speed with the original value of Speed.
This is the due to the behavior of the '++' operator which, when appended to the end of a variable will add 1 to its current value and then assigns the result back to the variable. This operator however temporarily stores the original value and uses that as the result of the expression. This temporary result of the ++ operator is ultimately what you are assigning to this.Speed due to the '=' operator you're using in the same expression, this in turn is what is causing the variable to not actually be modified.
The correct usage would be to simply call
Speed++;
This will perform the addition of 1 and assignment back to Speed, and also discard the temporary variable, as it is not being assigned anywhere.
This issue also exists in your SpeedDown method with the '--' operator.
In your Car.cs class, here is a better way to increment the speed without modifying the Program.cs file:
public int SpeedUp()
{
this.Speed += 1;
return (Speed);
}
public int SlowDown()
{
if (Speed > 0)
{
this.Speed -= 1;
}
return (Speed);
}
That produces the output that you're after.

Keeping track of points in simple console game

I'm having a hard time wrapping my mind around this. Every time the player makes a wrong guess, it should subtract his/her bet from the initial balance.
Since it is in a loop, it always takes the initial balance from the beginning spits out the same balance every time. (obviously)
I've tried assigning different variables and just can't seem to figure it out.
I've omitted the medium and hard difficulty methods as they are of no use right now, until I figure out this one.
My Main() only calls the setDifficulty(). Nothing else.
class Control
{
int selectedNumber = 0;
Random num = new Random();
bool playAgain = true;
int difficulty = 0;
int bet = 0;
int initialBalance = 20;
int runningCredits = 0;
int credits = 0;
public Control()
{ }
//sets game difficulty
public void SetDifficulty()
{
Console.Clear();
Console.WriteLine("Please select level of difficulty between 1 - 100");
difficulty = int.Parse(Console.ReadLine());
if (difficulty >= 1 && difficulty <= 20)
LetsPlayEasy();
else if (difficulty >= 21 && difficulty <= 50)
LetsPlayMedium();
else if (difficulty >= 51 && difficulty <= 100)
LetsPlayHard();
else
{
SetDifficulty();
}
}
//easy level method
public void LetsPlayEasy()
{
//variables
int userGuess;
int numGuesses = 0;
selectedNumber = num.Next(1, 101);
Console.BackgroundColor = ConsoleColor.DarkYellow;
Console.Clear();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Difficulty level = EASY");
Console.WriteLine("\nBeggining credit balance = " + initialBalance);
Console.WriteLine("\nPlease place a bet. You will lose those credits for every incorrect guess!");
bet = int.Parse(Console.ReadLine());
do
{
Console.WriteLine("\nGuess a number between 1 and 100.");
userGuess = Convert.ToInt32(Console.ReadLine());
numGuesses++;
UI output = new UI();
output.CompareNumbers(userGuess, ref selectedNumber, ref playAgain, ref numGuesses);
runningCredits = (initialBalance - bet);
Console.WriteLine("\nYou have " + runningCredits + " credits remaining.");
} while (playAgain == true);
}
class UI
{
Random num = new Random();
int keepGoing;
public UI()
{ }
//compare user's guess to selected number
public void CompareNumbers(int userGuess, ref int selectedNumber, ref bool playAgain, ref int numGuesses)
{
Control difficulty = new Control();
Admin say = new Admin();
if (userGuess > selectedNumber)
{
Console.Beep(600, 300);
Console.WriteLine("\nToo High! Guess Again!");
}
else if (userGuess < selectedNumber)
{
Console.Beep(300, 300);
Console.WriteLine("\nToo Low! Guess Again!");
}
else
{
Console.Beep(350, 300);
Console.Beep(380, 200);
Console.Beep(380, 100);
Console.Beep(500, 1100);
Console.WriteLine("\n\nCongrats! It took you " + numGuesses + " guesses to win.");
numGuesses = 0;
Console.WriteLine("Press 1 to play again or 2 to quit.");
keepGoing = int.Parse(Console.ReadLine());
while (keepGoing != 1 && keepGoing != 2)
{
Console.WriteLine("\n\nPlease type either 1 or 2 only!");
keepGoing = int.Parse(Console.ReadLine());
}
if (keepGoing == 2)
{
playAgain = false;
say.Goodbye();
}
else
{
Console.Clear();
difficulty.SetDifficulty();
}
}
}
}
}
Initialise runningBalance to initialBalance and only use this value for calculations. If you only need initialBalance once, you can also do it by simply switching runningBalance to initialBalance without initializing runningBalance.
Console.WriteLine("\nBeggining credit balance = " + initialBalance);
Console.WriteLine("\nPlease place a bet. You will lose those credits for every incorrect guess!");
bet = int.Parse(Console.ReadLine());
runningBalance = initialBalance
do
{
Console.WriteLine("\nGuess a number between 1 and 100.");
userGuess = Convert.ToInt32(Console.ReadLine());
numGuesses++;
UI output = new UI();
output.CompareNumbers(userGuess, ref selectedNumber, ref playAgain, ref numGuesses);
runningCredits -= bet;
Console.WriteLine("\nYou have " + runningCredits + " credits remaining.");
} while (playAgain == true);
runningCredits = (initialBalance - bet);
You don't change initialBalance or bet in the loop, so every iteration has the same value of runningCredits.
Outside the loop, do this:
runningCredits = initialBalance;
Inside the loop, do this:
runningCredits -= bet;
Note: you don't have any code to check in the loop to see if the user guessed right or wrong (and as such, the user always loses and you always subtract out the bet).

How to add integers in different methods

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);
}

Categories