I am making a board game. In the game there is a set of task tiles, where each tile has a requirement for the player to meet. For example:
Tile 1: The player needs 3 stone to complete this task.
Tile 2: The player needs 2 blue cards to complete this task.
Tile 3: The player needs 3 red cards to complete this task.
etc.
Players can collect these tiles and, if they meet the conditions of the tile, score points. All of a player’s inventory data (amount of resources, number of cards, etc.) is held in a Player class:
public class Player : Monobehaviour
{
// The int value is the amount of the resource the player owns
public Dictionary<ResourceType, int> ResourceHolder
= new Dictionary<ResourceType, int>
{ {ResourceType.stone, 0}, {ResourceType.wood, 0} };
public Dictionary<CardType, int> CardHolder
= new Dictionary<CardType, int>
{ {CardType.blue, 0}, {CardType.red, 0} };
}
public enum ResourceType
{
stone,
wood
}
public enum CardType
{
blue,
red
}
Instead of creating a new class for every tile (which seems like a bad idea, but I could be wrong), I’ve thought about creating a single Task class and having each tile do something different based on an array of methods. Each tile would have an index, which is how it’s CheckRequirements() method would be determined:
public class Task : MonoBehaviour
{
public Player Owner;
public int TileIndex;
// All the different checks a tile could make
private Func<Player, bool>[] CheckArray = new Func<Player, bool>[]
{ player => CheckStone3(player), () => CheckRedCard2(player) };
public bool CheckRequirements()
{
return CheckArray[TileIndex](Owner);
}
// Actions that CheckArray holds
private bool CheckStone3(Player p)
{
if (p.ResourceHolder[ResourceType.stone] >= 3)
return true;
return false;
}
private bool CheckRedCard2(Player p)
{
if (p.CardHolder[CardType.red] >= 2)
return true;
return false;
}
// etc. etc. ...
}
The Player could have a List storing all the task tiles they have, then the Player would merely need to call CheckRequirements() on the task to see if they meet the task’s requirements. However, this is still hard-coded. Is there a way to make an array of methods where each method can take in different parameters? Then I could do something like:
private bool CheckResource(Player p, ResourceType resource, int amount)
{
if (p.ResourceHolder[resource] >= amount)
return true;
return false;
}
In the future there may be a great number of things to check, and they may require checking things not stored in the Player class (e.g. It needs to be Round 2 to complete this task). The array of methods seems better than making a bunch of classes, but still not great. Plus each Tile will be holding this massive array and only access a small portion of it, which seems wasteful.
What are some suggestions as to how to create these tiles so that it’s easy to expand in the future? Should I continue with the array of functions or do something else?