If statements not working

Hey! This is probably very easily solved, but I simply can’t find what’s wrong with my code. This is what I want it to do: If I enter “attack” it attacks, then if I enter “defend” it defends, and if I then enter “attack” again, it does that, and so on and so on. It simply loops from the beginning and ignores what you just wrote.

And this is what it does:
Let’s say I enter “attack”. It then does the “attack”, but then no matter what I enter after that, it only does “attack”. So even if I write “defend” or “bkjwkjfknd” it still just attacks.

What am I missing? I’ve tried so many different things, for example, changing the if else-statements to just several if-statements, I’ve also tried using switch cases, and that got a different error (the first answer I entered was ignored completely, the second answer was done, and then the first answer was ignored, but the second was done and so on).

Here’s my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            Random random = new Random();
            Random attack = new Random();

            //player variables
            int playerHealth = 50;
            int playerAttack = attack.Next(5, 15);
            string playerName;

            //strings with enemy type and name + randomising
            string[] enemyType = "warrior|goblin|elf|evil princess".Split('|');
            int typeChoice = new Random().Next(enemyType.Length);
            string[] enemyName = "Leia|Nora|Baron|Cahira".Split('|');
            int nameChoice = new Random().Next(enemyType.Length);

            // enemy variables
            int enemyHealth = 50;
            int enemyAttack = attack.Next(5, 15);
            string randomEnemyType = enemyType[typeChoice];
            string randomEnemyName = enemyName[nameChoice];


            // Starting of the game
            Console.WriteLine("What is your name?");
                playerName = Console.ReadLine();

            // here I have a lot of text not relevant to the problem

            Console.WriteLine("What will you do? Type 'attack' or 'defend'.");
            string input = Console.ReadLine();

            do
            {
                if (input == "attack")
                {
                    enemyHealth -= playerAttack;
                    playerHealth -= enemyAttack;
                    Console.WriteLine("\n" + playerName + " attacks " + randomEnemyName + "! " + randomEnemyName + " attacks back!");
                }
                else if (input == "defend")
                {
                    Console.WriteLine("\n" + playerName + " puts up their shield and defends themselves. ");
                    playerHealth -= enemyAttack / 2;
                }
                else
                {
                    Console.WriteLine("\nThat is not a valid command. Please write 'attack' or 'defend'.");
                }


                // health status
                Console.WriteLine(playerName + "s health is now " + playerHealth + " and " + randomEnemyName +
                            "s health is now " + enemyHealth + ". What will you do next?");

                Console.ReadLine();

            } while (playerHealth > 0 && enemyHealth > 0);


            if (playerHealth <=0)
            {
                Console.WriteLine(randomEnemyName + " slayed " + playerName + "!!");
                Console.ReadLine();
            }
            if (enemyHealth <=0)
            {
                Console.WriteLine(playerName + " slayed " + randomEnemyName + "!!");
                Console.ReadLine();
            }
        }
        }
    }

add input = Console.ReadLine(); instead of just Console.ReadLine(). You’re only assigning your string once (before the loop)

A.Killingbeck is spot on.

Protip, you can create arrays directly, instead of using split:

string[] enemyType = {
    "warrior",
    "goblin",
    "elf",
    "evil princess"
};
1 Like

Haha, ah! It was that easy! Much thanks to you, sir. It now works (almost) flawlessly. The only thing not working now is when you die/win. I’ve put down that if the health is 0, or less than zero, they’re dead, but for some reason, say I have 5 in health, and then the enemy hits 6 in health, then instead of just dying, it tells me I have -1 in health, and then the next move it tells me I died. Why’s that? And how do I fix this?

I tried the code you have, or something similar before I did the code I currently have, but that didn’t work perfectly. Maybe I just had some other errors, but are there any differences between the list you have up here, and the one I have? Could I literally just exchange my block of code for yours, and I wouldn’t have to change anything else within my code?

Yes, pretty much. In both instances you’ll get a string array with those four entries in it. The Split command is slightly slower, but not to the degree that the difference is ever noticeable.

The advice is mainly because the way I suggested is easier to read and add new entries to.

The printing that you’ve got less than 0 health before you’re dead is because that’s the order in which you’ve written the code in the while loop.

1 Like

Aha, okay! Thanks for the explanation!

Also, how would I go about it if I don’t want that to happen then? Because I want it to as soon as you go under 0, or is at 0, you die. It’s not ideal that you see that you have -something instead of just dying.

You could use the break; statement, which instantly ends a loop, if either the player or the enemy has less than 0 health after applying damage.

If you do that, you don’t need that check in the while part of the loop, so you can just do while(true).

EDIT: by the way, how does this relate to Unity?

Where would I put the break? Inside, before or after the do while loop? And do I have to remove some of my code? (because you said that I don’t need that check in the while part, but I don’t understand how the loop then knows what is true, if I just put true?)

And about Unity: I didn’t know it had to do with Unity as long as it was made in Unity. Sorry.

So your do-while code looks like:

do
{
    *check input*
    *print health info*
    *read input*
} while (playerHealth > 0 && enemyHealth > 0);

you could instead do:

do
{
    *check input*
    if(playerHealth <= 0 || enemyHealth <= 0) {
        break;
   }
   *print health info*
    *read input*
} while (true);

That means that the printing health info and reading input part of the loop would be skipped when you break out of the loop.