phadaphunk
phadaphunk

Reputation: 13313

Get an object out of a mixed type collection

Hi I'm new to OOP and I need help on a little problem. I used a collection called Monsters to store 3 types of object. Spiders, Farmers, Gollum(irrelevant). My collection as an indexer but when I use it to get an object out of the collection the object is typeless but I really need to TypeCast my next opperation.

    private void Form1_Load(object sender, EventArgs e)
    {
        CurrentOpponent Opponent = new CurrentOpponent();
        Gollum myGollum = new Gollum();
        AngryFarmer myFarmer = new AngryFarmer();
        Ugly_Spider mySpider = new Ugly_Spider();
        myMonsters.AddGollum(myGollum);
        myMonsters.AddFarmer(myFarmer);
        myMonsters.AddUgly(mySpider);
        progressBar1.Increment(100);
        progressBar2.Increment(100);
        Monster myCurrentOpponent = Opponent.randomEncounter();
        //textBox1.Text = (this is where i need the type for a cast)myCurrentOpponent.name
    }

Here is the randomEncounter where i extract the object

    class CurrentOpponent
    {
        public Monster randomEncounter()
        {
            Random _random = new Random();
            int opp = _random.Next(4);
            return myMonsters[opp];

        }

And finally the indexer wich returns a monster (parent of all 3 monster types)

    public Monster this[int xxx]
    {
        get
        {
            return (Monster)List[xxx];
        }
    }

Help would be really appreciated..!! Thanks in advance

Upvotes: 3

Views: 914

Answers (4)

culithay
culithay

Reputation: 305

Ideally, AngryFarmer, Ugly_Spider and Gollum should all inherit from Monster

I have learn your problem like the problem in the Tetris game: 1/ You have Monsters like I have Shapes. 2/ Each kind of Monster have it own properties (Health, Magic Point,...) and behaviours (attack, run, cast spell,..) like the Blocks have properties (color, position, state,..) and behaviours (go down, rotate right, rotate left,...)

In the scene of the game you want to random a Monster that have the specific properties and behaviours, like I want to random a Shape. If it is your problem you can try my code:

public abstract class CMonster
{
    int _HP;
    int _MP;
    //..and something like this
    public int HP
    {
        get { return this._HP; }
        set { this._HP=value;}
    }
    public int MP
    {
        get { return this._MP; }
        set { this._MP = value; }
    }

    public abstract void Run();
    public abstract void Attach();
    public abstract void CastSpell();
}

public class CUgly_Spider : CMonster
{
    public CUgly_Spider()
    {
        this.MP = 100;//your value here
        this.HP = 100;//your value here
    }
    public override void Attach()
    {
        //your implemetation here
    }

    public override void Run()
    {
        //your implemetation here
    }

    public override void CastSpell()
    {
        //your implemetation here
    }
}


public class CGollum : CMonster
{
    public CGollum()
    {
        this.MP = 100;//your value here
        this.HP = 100;//your value here
    }
    public override void Attach()
    {
        //your implemetation here
    }

    public override void Run()
    {
        //your implemetation here
    }

    public override void CastSpell()
    {
        //your implemetation here
    }
}

class Test
{
    private void InitTheGame()
    {
        CMonster curMonster=null;
        Random rnd = new Random();
        //sample random
        if ((rnd.Next() % 2) == 0)
        {
            curMonster = new CGollum();
        }
        else
        {
            curMonster = new CUgly_Spider();
        }

        curMonster.Run();//when (rnd.Next() % 2) == 0 then the Gollum is doing else the Ugly_Spider
        curMonster.Attach();//when (rnd.Next() % 2) == 0 then the Gollum is doing else the Ugly_Spider
        curMonster.CastSpell();//when (rnd.Next() % 2) == 0 then the Gollum is doing else the Ugly_Spider
    }
}

I hope that can help you.

Upvotes: 0

Renato Gama
Renato Gama

Reputation: 16529

you may wanna try it by using interfaces also! have a look...

public interface IMonster
{
    String Name { get; }
    Int32 Health { get; set; }
}

public class Spider : IMonster
{
    public Spider()
    {
        _health = 100;
    }

    public string Name
    {
        get { return "Spider"; }
    }

    private int _health;
    public int Health
    {
        get { return _health; }
        set { _health = value; }
    }
}

public class Gollum : IMonster
{
    public Gollum()
    {
        _health = 250;
    }

    public string Name
    {
        get { return "Gollum"; }
    }

    private int _health;
    public int Health
    {
        get { return _health; }
        set { _health = value; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        List<IMonster> monsters = new List<IMonster>()
                                      {
                                          new Gollum(),
                                          new Spider()
                                      };

        IMonster randomMonster = GetRandomMonster(monsters);
        Console.WriteLine(randomMonster.Name + "/" + randomMonster.Health);
    }

    private static IMonster GetRandomMonster(List<IMonster> monsters)
    {
        //Your code for getting a random monster goes here!
        throw new NotImplementedException();
    }
}

I like very much this approach... Imagine you have an element on your game that initially is not exactly a monster. Say it is a random element on your game that after a given event it becomes a monster that your Hero (say a game like heroes of mighty and magic) have to fight with. If you decided to add this feature long time after you created the game, it would become harmful/difficult/risky to change it, as this element might have already be inheriting from another class. If you were using interfaces you would simply implement it on this entity and it would promptly be capable of behaving like any other IMonster in your game. It means that this random entity would be able to be passed as a param to the method Fight(IHero hero, IMonster monster);

Upvotes: 0

Keith Nicholas
Keith Nicholas

Reputation: 44298

you need to use interfaces...... IMonster..... IMonster then has a name

then make all your monsters implement IMonster

and just have a List of IMonsters

Upvotes: 0

Etienne de Martel
Etienne de Martel

Reputation: 36851

Ideally, AngryFarmer, Ugly_Spider and Gollum should all inherit from Monster:

public class AngryFarmer : Monster
{
    // ...
}
// etc.

You could then just use a List<Monster>:

myMonsters = new List<Monster>();
myMonsters.Add(new AngryFarmer()); // works because AngryFarmer is a kind of Monster

This will allow you to use polymorphism.

Upvotes: 3

Related Questions