Reputation: 179
I am making this 2-D game where I want to be able to build structures. The player must be able to benefit from certain structures. Today the game looks like this:
(the blue dot is the player, other dots are ais)
I have made a class named Structure and three other classes that inherits from Structure. These classes are more or less empty. The tiles of the game has there own class named Tile. In this class I have written some things but the code of interest is this:
public LinkedList<Structure> Structures = new LinkedList<Structure>();
When i build a structure (a fireplace for example) the code looks like this:
Bundle.map.tile[Bundle.player.X, Bundle.player.Y].Structures.
AddFirst(new Fireplace());
The part I´m uncertain about is how I check if the list contain a fireplace for example (which is a class named Fireplace) or any other building. For example if a player finds a fireplace on a tile he/she will regain warmth. This does not work. Perhaps I have the wrong approach to all this, in either case please provide me with an code example.
Conclusion of answer:
bool anyFireplace = Bundle.map.tile[Bundle.player.X, Bundle.player.Y].Structures.OfType<Fireplace>().Any();
if (anyFireplace)
{
Warmth = MaxWarmth;
}
else
{
if (Warmth > 0)
{
Warmth--;
}
else
{
HP--;
}
}
Upvotes: 2
Views: 690
Reputation: 23685
You could use, for example, Enumerable.OfType<TResult>()
and Enumerable.Any(TSource)
as follows:
LinkedList<Structure> structures = new LinkedList<Structure>();
// Add Different Types of Structures
Boolean anyFireplace = structures.OfType<Fireplace>().Any();
Just make sure you have:
using System.Linq;
in your using directives at the top of your source and a reference to the System.Core assembly module. You could also use Count() method if you need to know the exact number of fireplaces inside the LinkedList, otherwise Any() is more efficient in Linq objects.
Upvotes: 2
Reputation: 5760
I would suggest using the is
keyword. It is used to check whether a variable has a certain type. For example:
object example = "Hello World!";
bool isString = example is string; // Evaluates to true
And you could use that in your code as such:
foreach (Structure s in Structures)
{
if (s is FirePlace)
{
// Warmup the player
}
}
Also, I would suggest using List<T>
instead of LinkedList<T>
, since List<T>
is (generally) much faster.
As you might have gathered from some of the other answers, multiple ways lead to Rome here, many ways. However, according to this test, the is
way of doing it outperforms all other suggested ways (thanks to Hogan btw for this test):
OfType time: .6702958, GetType time: .2268946, Property time: .1400208, Is time: .1112995
And this way is
cleaner IMHO.
Upvotes: 2
Reputation: 70523
Maybe having the class name describe the object is not advisable. You will have to use reflection which is kinda slow. AND you only get one description (the class name). You will want more than just one. You might want to consider a base object like this:
public abstract class MapObject
{
public int x,y; // object location
public string myclass; // object class
public string mytype; // object type
// etc
// constructor
public MapObject(string myclass, string mytype);
}
Then the a fireplace might look like this
public class FirePlace : MapObject
{
public FirePlace()
: base("Builtin furniture", "Fireplace") { }
// etc
}
Now you can loop over all MapObjects for ones of mytype = "Fireplace"
Upvotes: 0
Reputation: 24383
You can use LINQ to Objects for this:
LinkedList<Structure> list = ...
List<Fireplace> fireplaces = list.OfType<Fireplace>().ToList();
fireplaces
is then a list of all the elements in the list of type Fireplace
- or an empty list if none exist.
If you just want to know if one exists or not, you can adapt this to:
bool hasFirplace = list.OfType<Fireplace>().Any();
Upvotes: 1
Reputation: 1784
You can use the Type to know that:
foreach(var s in Structures)
{
var type = s.GetType();
if(type == typeof(FirePlace)
{
(your code here)
}
}
For a single method
public bool HasType<T>(IEnumerable<T> list, Type t)
{
return list.Any(e=>e.GetType() == t);
}
The usage should be like:
if(HasType(Structures,typeof(FirePlace))
{
(code here)
}
At last you can turn this into an extension method, but I leave that option to you ;)
Upvotes: -1