Friday, June 1, 2018

unity - Creating a Nations Stockpile


If I created different XML files for each Nations' Stockpiles and made an XMLmanager to do updates such as resource consumption and trade, wouldn't that be too much resource intensive? I mean, if I had to access each Nations' stockpiles every tick and update them (Quantity, Price, Quality).


Is there any other faster way to manage all those updates?


From the back and forth in the comments, I've came up with this approach.



public class Nation
{
public string NationName;
public int Population;

public void NationCreator(string name, int pop)
{
NationName = name;
Population = pop;
}


public class Stockpile
{
public int food;
public int water;
public int wood;

//Then methods to work with that stockpile
}
}


However, after some thinking and reading, my next approach to this problem will be Arrays but I only know how to make an array of one particular type like:


double[] balance = { 2340.0, 4523.69, 3421.0};

How could I do an array like this (Lua style array) in C# language?:


raw_material = {
cotton = {
Value = 17.50
}
}


Answer



I'd be inclined to do something a little like this:


First we define somewhere our collection of resource types (assuming this is a controlled list that will only be expanding occasionally during development. If you want dynamic resource types that can be expanded by mods / DLC, the Type Object Pattern can serve that need. But for most cases we can keep it simpler.)


public enum ResourceType {
Food,
Water,
Wood
// Add resources here as needed.
}


Next our stockpile can be implemented as a key-value store that maps resource IDs to the quantity of resource held. (If you need, instead of an int, the content of this structure can be a struct ResourceRecord including not just quantities but storage capacity, production rates, expiration date, quality, etc...)


Dictionary _stockpile = new Dictionary();    

public int GetResourceStock(ResourceType kind) {
int held = 0;
_stockpile.TryGetValue(kind, out held);
return held;
}

public void AddResource(ResourceType kind, int quantity) {

// For safety & debugging, you may want to Assert here that quantity > 0.
int held = GetResourceStock(kind);
_stockpile[kind] = held + quantity;
}

public bool TryWithdrawResource(ResourceType kind, int quantity) {
int held = GetResourceStock(kind);
if(held < quantity)
return false; // I lack enough funds to spend.


_stockpile[kind] = held - quantity;
return true; // Transaction completed successfully.
}

Here I've shown this as a dictionary, for maximum flexibility. This might be overkill for your needs though - if your list of resources is small & fixed, an array indexed by the enum-as-integer would work fine - I show that style in another answer. Or if any given stockpile can contain only a few (dozens of) resource types, a List would be comparably fast to search.


What's nice about this is that now you can define resource production & costs in data. If our food and water resources are particular named variables, then we need different lines of code to check & modify each one. But by abstracting this out, the same code can act on any single resource or collection of resources with only data changes. For example, we can model costs & purchase checks for any number of resources like this:


public struct CostEntry {
public ResourceType resource;
public int quantity;
}


public bool CanAfford(CostEntry[] costs) {
foreach(var cost in costs) {
if(GetResourceStock(cost.resource) < cost.quantity)
return false;
}
return true;
}

public bool TryPurchase(CostEntry[] costs) {

// If we can't afford it, stop right away.
if(CanAfford(costs) == false)
return false;

// Now that we know we can afford it, spend all the required resources.
foreach(var cost in costs) {
TryWithdrawResource(cost.resource, costquantity);
}
return true; // Done.
}

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...