Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading causing code bloat

Tags:

c#

overloading

I am trying to develop my understanding of OOP so I created a console adventure game. I have a battle class which basically has 3 methods:

public static void StartFight(Dragon dragonWarrior, Goblin goblinEnemy)
public static string YouAttack(Dragon dragonWarrior, Goblin goblinEnemy)
public static string EnemyAttack(Goblin goblinEnemy, Dragon dragonWarrior)

The first calls the other 2 until someone dies. YouAttack and EnemyAttack include messages like:

Console.WriteLine("{0} the dragon attacks {1} and has dealt {2} damage",
                  dragonWarrior.Name, goblinEnemy.Name, damageDone);

In all, lets says that my 3 methods collectively takes 90 lines of code.

My problem is this. Lets say, I have an orc. I can easily copy and paste the methods and overload them like this:

public static void StartFight(Orc orcWarrior, Goblin goblinEnemy)

But that's going to generate a lot of bloat. Especially as the number of object Warriors increase (Centaur, Demon, Dwarf etc etc)

So is there a way of passing an object and the compiler figuring out what object has been passed? If there is, does anyone know of a good tutorial? Is there another solution that I can research??

I am aware that this might be a rubbish question but I am entirely self taught. I don't have any friends or tutors that code so every problem can be a struggle. Thank you in advance

like image 362
Beginner Avatar asked Jul 03 '26 01:07

Beginner


2 Answers

What you are looking for is called Inheritance (link) and Polymorphism (link) - both are one of the 3 major pillars of OOP (with third one being Encapsulation (link))

They allow you to use objects of which you do not know the exact class, but for which you can still describe the API or methods.

Some example use can be found here: What is the real significance(use) of polymorphism

In your example, lets say Dragon and Orc extend the Warrior class, and lets say that Goblin and Gnome extend the Enemy class. Then your methods would look like this:

public static void StartFight(Warror warrior, Enemy enemy)
public static string YouAttack(Warror warrior, Enemy enemy)
public static string EnemyAttack(Enemy enemy, Warror warrior)

And you could pass any object that extends the Enemy or Warrior class.

This inheritance tree is only an example, as others have mentioned, you can (and should) design it to your needs, more or less abstract that is.

like image 126
Tadija Bagarić Avatar answered Jul 04 '26 13:07

Tadija Bagarić


To make good abstraction, I think you need to go through many tutorials... But you can start from something simple:

public interface IUnit
{
    string Name   { get; }
    int    HP     { get; set; }
    int    Armor  { get; }
    int    Damage { get; }
}

public class Goblin : IUnit
{
    public string Name { get; } = "Goblin";

    public int HP { get; set; } = 80;

    public int Armor  => 3;
    public int Damage => 8;
}

public class Knight : IUnit
{
    public string Name { get; } = "Knight";

    public int HP { get; set; } = 120;

    public int Armor  => 5;
    public int Damage => 12;
}

public class BattleSystem
{
    public void ProcessAttack (IUnit attacker, IUnit target)
    {
        Console.WriteLine (attacker.Name + " is attacking " + target.Name);

        int damage = Math.Max (0, attacker.Damage - target.Armor);

        target.HP -= damage;

        if (target.HP <= 0)
        {
            Console.WriteLine ("Enemy unit died...");
        }
    }
}

Try to avoid using concrete types like Goblin, Warrior etc. If one unit have second special weapon, you need to implement abstraction that will allow any unit to have second weapon (but most of them will use only one weapon of course).

Game programming patterns

like image 35
apocalypse Avatar answered Jul 04 '26 14:07

apocalypse



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!