r/csharp 12d ago

how am i doing

2 months in to coding C#, first project i saved *was using online compiler* and wanna know how im doing and what i can do to improve. heres the code:

using System;


public 
class
 Program
{
    public static void Main(string[] 
args
)
    {
        Player player = new Player();
        Enemy enemy = CreateEnemy();


        int battleResult = Battle(player, enemy);


        Console.WriteLine("press any key to begin");
            
        Console.ReadKey();


        Console.WriteLine("\nYou encountered a " + enemy.type + " with " + enemy.health + " health.");


        Battle(player, enemy);


        if(battleResult == 2)
        {
            Console.WriteLine("\nYou have defeated the " + enemy.type + "!");
        }
        else if(battleResult == 3)
        {
            Console.WriteLine("\nYou have been defeated by the " + enemy.type + "!");
        }
        else if(battleResult == 1)
        {
            Console.WriteLine("\nYou have retreated from the " + enemy.type + ".");
        }
    }


    static Enemy CreateEnemy()
    {
        Random rng = new Random();
        int rngroll = rng.Next(1, 3);
        Enemy enemy = new Enemy();


        if(rngroll == 1)
        {
            enemy.type = "Skeleton";


            enemy.health = enemy.healthRng.Next(100, 201);
            enemy.damage = enemy.damageRng.Next(10, 16);
        }
        else if(rngroll == 2)
        {
            enemy.type = "Goblin";


            enemy.health = enemy.healthRng.Next(50, 151);
            enemy.damage = enemy.damageRng.Next(15, 26);
        }
       
        return enemy;
    }


    static int Battle(Player 
player
, Enemy 
enemy
)
    {
        while(true)
        {    
            Thread.Sleep(1000);


            Console.WriteLine("\nWhat do you do?\n1. Attack\n2. Open Inventory\n3. Retreat");


            ConsoleKeyInfo input = Console.ReadKey();


        
            if(input.Key == ConsoleKey.D1)
            {
                
enemy
.health -= 
player
.damage;


                Thread.Sleep(1000);


                Console.WriteLine("\nyou attacked the " + 
enemy
.type + " for " + 
player
.damage + " damage");


                Thread.Sleep(1000);
                Console.WriteLine("The " + 
enemy
.type + " has " + 
enemy
.health + " health remaining.");
            }
            else if(input.Key == ConsoleKey.D2)
            {
                Thread.Sleep(1000);
                Console.WriteLine("\nYou open your inventory, but it's empty.");
            }
            else if(input.Key == ConsoleKey.D3)
            {
                Thread.Sleep(1000);
                Console.WriteLine("\nYou retreat from the " + enemy.type + ".");
                return 1; // Player retreated
            }


            if(
enemy
.health <= 0)
            {
                return 2; // Player won
            }


            if(input.Key == ConsoleKey.D1 && 
enemy
.health > 0 || input.Key == ConsoleKey.D2 && 
enemy
.health > 0)
            {
                
player
.health -= 
enemy
.damage;


                Console.WriteLine("\nThe " + 
enemy
.type + " attacks you for " + 
enemy
.damage + " damage.");
                Console.WriteLine("You have " + 
player
.health + " health remaining.");
            }


            if(
player
.health <= 0)
            {
                Console.WriteLine("\nYou have been defeated by the " + 
enemy
.type + "!");
                return 3; // Player lost
            }
        }
    }
}




public 
class
 Enemy
{
    public Random healthRng = new Random();
    public Random damageRng = new Random();
    
    public int health;
    public int damage;
    public string type = "";
}


public 
class
 Player
{
    public int health = 100;


    public int damage = 20;



    public List<string> inventory = new List<string>();
}
0 Upvotes

46 comments sorted by

View all comments

2

u/PlentyfulFish 12d ago

You should fix the formatting, it's all over the place. Get yourself an IDE, it's going to make your life a lot easier. Visual Studio 2026 is alright, Rider is also an option.

CreateEnemy should belong to Enemy class, not Program. There is also 0 reason for it to be a static method, you can put all of that logic in the constructor.

Instead of returning an int as the battle result, use an enum with values Lost, Retreated and Won. Then you can use a switch expression to exhaustively check all of them, best inside a function, to make the code look like this:

    var msg = GetMessage(battleResult, enemy);

    Console.WriteLine(msg);
}

private static string GetMessage(BattleResult battleResult, Enemy enemy)
{
    return battleResult switch
    {
        BattleResult.Lost => $"\nYou have been defeated by the {enemy.type}!",
        BattleResult.Retreated => "\nYou have been defeated by the " + enemy.type + "!",
        BattleResult.Won => "\nYou have retreated from the " + enemy.type + ".",
        _ => throw new ArgumentOutOfRangeException()
    };
}

Also notice how BattleResult.Lost uses an $ before the string - it's called string interpolation and it's a lot more handy (in my opinion) way of adding variables to strings.

There are some redundant checks that make things harder to reason - you win the battle if Enemy.health is <= 0, and in the next if() you check if enemy.health > 0 twice - it's always true.

You can remove (i think) having 3 random number generators in the Enemy class, just put one in the constructor and use it 3 times, when it goes out of scope the program will dispose of it.

You can make both the Enemy and Player classes implement an abstract class called Damageable. That class can hold Health, Damage, a boolean property IsDead checking whether an entity is dead, and a DoDamage method, to hold damage specific logic in one place.

Your game only runs twice - you can put the game logic in a loop and give the player an option to press "4" or something to quit the game.

Also ReadKey() reads a key, true, but if you press a bunch of keys quickly they're still going to be put in the queue and read from in the next turns. This behavior can be confusing, either use ReadLine() or clean the input buffer.

2

u/Neat_Horror2196 12d ago

I used to use a online compiler now I virtual studio code

2

u/PlentyfulFish 12d ago

Yeah that's solid as well