I'm new to c# and don't completely understand for loops. I am working on a text-based wizard game recommended by brackeys on youtube. At the start of the game, you are asked to chose your spell, let's say "bugs(costs 13mana, deals 2dmg)" you have 3 spell slots and 10hp. When it's time to attack calculations are done etc to reduce the enemy's(frog(10hp)) hp. So after the frog attacks, I want to start over the battle(loop) for me to attack again and the frog to attack again. And the game will be over when either I or the enemy has 0hp. I know for sure I'm coding right but the way I'm using classes and functions are too much and I bet there are simpler ways to do it but I just don't know.
I'm not sure this project is too big for a beginner but yea lol. I was thinking of using a for loop but I don't completely understand how it works.
When I run it only loops the part that asked which spell you want to use and minuses your mana and spell slots. It only loops that and doest attack Also, I'm kinda new to this site so I don't know the proper way of laying out my work.
class Wizard
{
//Wiz Profile
public string name;
public int myHp = 10;
public int myMana = 20;
public string userAttack;
public string favoriteSpell;
private int spellSlots;
private float xp;
public static int Count;
/////////////////////////
//Spells Profile
public int bugsDmg = 2;
public int bugsMana = 13;
public int rottingFodderDmg = 3;
public int rottingFodderMana = 10;
public int owlDmg = 5;
public int owlMana = 10;
//////////////////////////////////////////
//Enemies Profile
public int frogHp = 10;
//Here is where I attempted to make the loop
public void Gameover()
{
while(myHp > 0){
Gameactive();
}
}
//I don't use this I just got this in brackets tutorial I will use it when
getting user name and spell not really sure of to use functions taking stuff
in the brackets
public Wizard(string _name, string _favoriteSpell)
{
name = _name;
favoriteSpell = _favoriteSpell;
spellSlots = 3;
xp = 0f;
Count++;
}
//This is done after the spell calculation is done
public void Battle()
{
userAttack = Console.ReadLine();
if((userAttack == "Bugs") || (userAttack == "bugs"))
{
CastSpell();
frogHp =frogHp - bugsDmg;
Console.WriteLine("You casted " + userAttack + ". Dealth " + bugsDmg + "
damage!");
Thread.Sleep(5000);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Frog hp: " + frogHp +"hp" + " Your hp: " + myHp + "hp Your
mana: " + myMana + "mana");
Console.WriteLine("Spell Slots: " + spellSlots + " slots left");
Console.WriteLine("----------------------------------------");
Thread.Sleep(3000);
}
if( (userAttack == " Rotting Fodder") || (userAttack == "rottingfodder") ||
(userAttack == "rotting fodder"))
{
CastSpell();
frogHp =frogHp - rottingFodderDmg;
Console.WriteLine("You casted " + userAttack + ". Dealth " + rottingFodderDmg +
" damage!");
Thread.Sleep(5000);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Frog hp: " + frogHp +"hp" + " Your hp: " + myHp + "hp Your
mana: " + myMana + "mana");
Console.WriteLine("Spell Slots: " + spellSlots + " slots left");
Console.WriteLine("----------------------------------------");
Thread.Sleep(3000);
}
}
//This is called when an enemy(the frog) attacks
public void Enemyattack()
{
myHp = myHp - rottingFodderDmg;
Console.WriteLine("You got hit with rotting fodder");
Thread.Sleep(2000);
Console.WriteLine("Dealth" + rottingFodderDmg + " damage!");
Thread.Sleep(3000);
Console.WriteLine("----------------------------------------");
Console.WriteLine("Frog hp: " + frogHp +"hp Your hp: " + myHp + "hp Your
mana: " + myMana + "mana");
Console.WriteLine("Spell Slots: " + spellSlots + " slots left");
Console.WriteLine("----------------------------------------");
}
//This is the calculation that happens when a player chooses a spell
public void CastSpell(){
if((userAttack == "Bugs") || (userAttack == "bugs"))
{
myMana = myMana - bugsMana;
spellSlots--;
Console.WriteLine("-15 mana, -1 Spell Slot");
Thread.Sleep(5000);
}
if( (userAttack == " Rotting Fodder") || (userAttack == "rottingfodder") ||
(userAttack == "rotting fodder"))
{
myMana = myMana - rottingFodderMana;
spellSlots--;
Console.WriteLine("-15 mana, -1 Spell Slot");
Thread.Sleep(5000);
}
Gameover();
}
public void Meditate(){
Console.WriteLine(name + " meditates to regain spell slots.");
spellSlots = 2;
}
////////////////I assumed by making this into a func. I will be able to loop the part
///that takes user input then to attack again
public void Gameactive()
{
Console.WriteLine("Select Your Spell to attack: \nBugs(costs 15 mana) Rotting
Fodder(costs 4 mana)");
Battle();
Thread.Sleep(5000);
Console.WriteLine("Standby Phase...");
Thread.Sleep(2);
Console.WriteLine("Frog is attacking...");
Thread.Sleep(2000);
Enemyattack();
}
}
class Program
{
static void Main(string[] args)
{
Console.Title = "WizardMadness";
//Making a new wizard
string userName;
string userGender;
string userFavoriteSpell;
Wizard player1 = new Wizard(/*userName*/"Aaron", "Bugs" /*userFavoriteSpell*/);
Console.WriteLine(Wizard.Count + " wizard created.");
Console.WriteLine("Time to go into battle");
Thread.Sleep(3000);
Console.WriteLine("You ran into a Frog!");
Thread.Sleep(2000);
Console.WriteLine("--------------------------------------------------");
Console.WriteLine("Frog hp: 10hp Your hp: 10hp Your mana: 20mana\nSpell Slots:
3 slots available");
Console.WriteLine("--------------------------------------------------");
Thread.Sleep(5000);
player1.Gameactive();
Welcome to programming! There are a few things you can do to up your code and clean it up a little.
Use .ToLower() for your if statements
Consider using a DO WHILE loop for your game state
You can NEST your if statements
if
{
if
{
}
else if
{
}
else
{
}
}
Using libraries will clean up your code, separating your methods and functions can really help you trouble shoot and debug as well. Making your "main" 30 lines instead of 300
Learn what an if statement actually does. Think of it like this, your program runs top to bottom, so once it goes through that statement it is done, unless there is a loop to reprompt and make it go through it again, but once that statement is cleared, it will not be seen again ( you can nest your if statements in your do while loops)
Hope this helps! Not complete answers, but programming is about logic, and once you figure it out it will click, good luck!
Related
Hi guys I need help solving a c# problem. This is the code being run as you can see it repeats 1bottles and 1 bottle on the picture I would like to know how to remove the "1 bottles on the wall take one down" and keep "1 bottle on the wall" please help
class Program
{
static void Main(string[] args)
{
string strBottles = "bottles";
int bottles = 100;
while (bottles <= 100)
{
Console.WriteLine(bottles + strBottles + " on the wall" + " take one down");
if(bottles == 1)
{
strBottles = "bottle";
Console.WriteLine(bottles + strBottles + " on the wall");
break;
}
bottles--;
}
}
}
You need to check the value before the first message printing, add an if check like so,
if(bottles>1)
Console.WriteLine(bottles + strBottles + " on the wall" + " take one down");
Choosing a possible infinite do/while with a break condition that can or cannot be fullfilled is a bad idea
I will try this aproach:
string strBottle = "bottle";
int iBottles = 100;
for (int bottles = iBottles; bottles >=1; bottles--)
{
Console.WriteLine(bottles + strBottle + (bottles>1?"s":"") +" on the wall" + (bottles > 1 ? " take one down":""));
}
Think about what the code is doing when bottles == 1.
First it hits this line
Console.WriteLine(bottles + strBottles + " on the wall" + " take one down");
then it enters the if statement:
if(bottles == 1)
{
strBottles = "bottle";
Console.WriteLine(bottles + strBottles + " on the wall");
break;
}
If you want only the "1bottle on the wall", then the if statement needs to come first:
while (bottles > 0)
{
if(bottles == 1)
{
Console.WriteLine($"{bottles} bottle on the wall");
break;
}
Console.WriteLine($"{bottles} bottles on the wall take one down");
bottles--;
}
Other improvements:
while (bottles <= 100) - bottles starts at 100 and decreases so this statement will always be true. If you changed the initial number of bottles to int bottles = 101 the code wouldn't execute the while loop in your version. You never want it to go below 1 so the condition should be while (bottles > 0)
You don't really need the string strBottles, it's redundant and can be removed
If you're using C# 6.0 or above take a look at string interpolation. It provides a more readable way to format strings with expressions: $"{bottles} bottles on the wall"
I'm making a simple poll/survey to check where user can go to work. I went with yes or no answers. I made a point counter, so it can check user information if he answered yes then add one point. I want to make a function that displays a question and check user input instead of writing same do while loop for each question. I made an array for collecting "user points". But, the problem is that since program is jumping to loop and adding +1 point it just can't return a value to this "point array". This value is somewhere else in memory but not in array. This results to not properly working summary. It just shows everywhere 0 points to each possible work. What I've made wrong or what can I make to make it working properly?
Here's my code (I probably messed up formatting braces by copy/paste):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace Survey
{
class Program
{
static void Main(string[] args)
{
//here's my Question Bank
ArrayList QuestionList = new ArrayList();
QuestionList.Add("1. Question");
QuestionList.Add("2. ...");
QuestionList.Add("3. ...");
QuestionList.Add("4. ...");
QuestionList.Add("5. ...");
QuestionList.Add("6. ...");
QuestionList.Add("7. ...");
QuestionList.Add("8. ...");
QuestionList.Add("9. ...");
QuestionList.Add("10. ...");
//here's my work list.
ArrayList WorkList = new ArrayList();
WorkList.Add("IT");
WorkList.Add("Architect");
WorkList.Add("Politician");
WorkList.Add("Driver");
WorkList.Add("Designer");
//here's an array, where I want to hold "points". The higher points the more probably user will get suggestion where to work.
int[] Work;
Work = new int[5] { 0, 0, 0, 0, 0 };
Console.WriteLine("Hi. Say 'y' if you agree or 'n' if not.");
displayQuestion(QuestionList[0], Work[0]);
displayQuestion(QuestionList[1], Work[1]);
displayQuestion(QuestionList[2], Work[2]);
displayQuestion(QuestionList[3], Work[3]);
displayQuestion(QuestionList[4], Work[4]);
displayQuestion(QuestionList[5], Work[4]);
displayQuestion(QuestionList[6], Work[1]);
displayQuestion(QuestionList[7], Work[2]);
displayQuestion(QuestionList[8], Work[0]);
displayQuestion(QuestionList[9], Work[3]);
// here's calculating maximum points
int max;
max = Work[0];
for (int i=0; i<5; i++)
{
if (Work[i] > max)
max = Work[i];
}
for (int i = 0; i < 5; i++)
{
if(Work[i]==max)
Console.WriteLine("You can work as: " + WorkList[i]);
}
//Summary
Console.WriteLine("Points as: " + WorkList[0] + " = " + Work[0]);
Console.WriteLine("Points as: " + WorkList[1] + " = " + Work[1]);
Console.WriteLine("Points as: " + WorkList[2] + " = " + Work[2]);
Console.WriteLine("Points as: " + WorkList[3] + " = " + Work[3]);
Console.WriteLine("Points as: " + WorkList[4] + " = " + Work[4]);
Console.ReadLine();
}
//here's the PROBLEM (I think)
public static int displayQuestion(object whichQuestion, int WorkPoints)
{
string answer;
do
{
Console.WriteLine(whichQuestion);
answer = Console.ReadLine();
if (answer == "y")
{
WorkPoints++;
}
} while (answer != "y" && answer != "y");
return WorkPoints;
}
}
}
actually you're assigning the new score to the return value of the displayQuestion Method and not using it.
public static int displayQuestion(object whichQuestion, int WorkPoints)
so a possible approach is tu use the ref keyword as Samvel said or assign the return value of the method to work[i]:
Work[0] = displayQuestion(QuestionList[0], Work[0]);
Change the function to the following:
public static int displayQuestion(object whichQuestion)
{
string answer;
int WorkPoints = 0;
do
{
Console.WriteLine(whichQuestion);
answer = Console.ReadLine();
if (answer == "y")
{
WorkPoints++;
}
} while (answer != "y" && answer != "n");
return WorkPoints;
}
}
and then use it this way:
Work[0] += displayQuestion(QuestionList[0]);
I wrote a basic number guessing game from C#. It seems to return the 3rd option ("Wrong choice! Please try again.") every time no matter what var c is chosen by the user. I was trying with characters (s instead of 1 and w instead of 2 etc with c as a string) but it gave the same results. Not sure where it's going bad.
using System;
namespace Challanges
{
class Program
{
static int guess = 500;
static int low = 1;
static int high = 1000;
static bool cont = false;
static void Guess() //guesses and adjusts variables according to input.
{
int c;
Console.WriteLine("Is your number greater or less than: " + guess + Environment.NewLine + "If it is less than, press 1; if it is greater, press 2." + Environment.NewLine + "If it is your number, press 3.");
c = Convert.ToInt32(Console.Read());
if (c == 1)
{
high = 500;
guess = low + high / 2;
}
else if (c == 2)
{
low = 500;
guess = low + high / 2;
}
else if (c == 3)
{
Console.WriteLine("Congratulations!! We found your number!");
cont = true;
}
else
{
Console.WriteLine("Wrong choice! Please try again.");
Console.ReadKey();
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!" + Environment.NewLine + "Let's play a guessing game. Think of a number between 1 and 1000." + Environment.NewLine + "Type your number :)");
int x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Your number is: " + x + Environment.NewLine + "Too easy?");
Console.ReadKey();
Console.WriteLine("Think of a number");
if(cont == false)
{
Guess();
} else
{
Console.ReadKey();
}
}
}
}
As mentioned in the comments before, Console.Read() returns a character code. The character code for the number 1 is 49, thus your conditions fail and the else block is executed.
What you wanted to do was use Console.ReadLine()which returns a string instead of character codes. If you cast that string into an Int32 you should be able to evaluate your conditions correctly.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm new.
my problem:
class Battle
{
public void Fight(string charOne, string charTwo)
{
void CurrentHealth()
{
Console.WriteLine(charOne.name + "'s Health: " +
charOne.currentHealth + "/" + charOne.maxHealth +
" | " + charTwo.name + "'s Health: " + charTwo.currentHealth +
"/" + charTwo.maxHealth);
}
}
}
the ".name" and ".currentHealth" are not working.
charOne would be a class instance, and charTwo would be another class instance.
[UPDATE BELOW]
Below was the code that was originally working in the main program class, and I was trying to move it in to a class, where I could pass in some parameters to the class, so the Hero could fight other monsters in the future. This single time monster was "mosquito".
I just want to be able to replace a "mosquito" with a "wolf" class and maybe "hero2" instead of "hero". Hope this makes more sense.
void CurrentHealth()
{
Console.WriteLine(hero.name + "'s Health: " + hero.currentHealth + "/" + hero.maxHealth + " | " + mosquito.name + "'s Health: " + mosquito.currentHealth + "/" + mosquito.maxHealth);
}
void Attack(int dmg)
{
Console.WriteLine(hero.name + " Dealt " + dmg + " damage to " + mosquito.name + ".");
}
while (mosquito.currentHealth > 0 && hero.currentHealth > 0)
{
Console.Clear();
int damage = hero.AttackAction();
mosquito.currentHealth = mosquito.currentHealth - damage;
int newHealth = mosquito.currentHealth;
Attack(damage);
CurrentHealth();
Console.WriteLine();
Console.WriteLine("Press any key to continue.");
Console.Read();
}
if (mosquito.currentHealth <= 0)
{
Console.WriteLine("Right on! You are Victorious!!!");
}
else if (hero.currentHealth <= 0)
{
Console.WriteLine("Oh no.. you are dead...");
}
else
{
Console.WriteLine("You reached the end.");
}
public void Fight(MyCharacterClass charOne, MyCharacterClass charTwo)
Try it like this, of course change your own class with MyCharacterClass
I am a newbie and I am stuck in this problem. I can the players stats, scores and names but I can't make the scoreboard work properly. I have worked 2 days trying to figure it out now I am asking you guys.
I have top 10 scoreboard but I cant make the placement. Higher score should have higher placement.
This is my code:
int PlayerCount = PlayerSystem.Players.Count;
if(PlayerCount == 1)
{
Score[0].text = PlayerSystem.Players[0].Name + ": " + PlayerSystem.Players[0].Score.ToString();
}
if (PlayerCount == 2)
{
if(PlayerSystem.Players[0].Score > PlayerSystem.Players[1].Score)
{
Score[0].text = PlayerSystem.Players[0].Name + ": " + PlayerSystem.Players[0].Score.ToString();
Score[1].text = PlayerSystem.Players[1].Name + ": " + PlayerSystem.Players[1].Score.ToString();
}
else if(PlayerSystem.Players[1].Score > PlayerSystem.Players[0].Score)
{
Score[1].text = PlayerSystem.Players[0].Name + ": " + PlayerSystem.Players[0].Score.ToString();
Score[0].text = PlayerSystem.Players[1].Name + ": " + PlayerSystem.Players[1].Score.ToString();
}
}
I commented over 200 lines of code because it didnt worked. But I hope you get the idea. Thank you if you readed my post. I really apreciate it if you help me how to do it. Thank you.
First sort the player score.
using System.Linq;
....
List<Player> Players = PlayerSystem.Players.OrderByDescending(p=>p.Score).ToList();
Then assign the scores in a loop to your GUI.
for(int i=0; i<10; ++i)
{
var player = PlayerSystem.Players[i];
Score[i].text = player.Name + ": " + player.Score;
}