优化代码以轻松编辑

时间:2018-04-20 20:12:50

标签: c#

在我的游戏中有一个文本根据是否购买了某些Upgrades来输出代码我开始编码就像这样

if (UpgradeManager.Instance.HasUpgrade("basicFunction") && !UpgradeManager.Instance.HasUpgrade("basicCounter"))
{
    codeString = "protected void GainUnits(){ units += " + gains + ";}";
}
else if (UpgradeManager.Instance.HasUpgrade("basicCounter") && UpgradeManager.Instance.HasUpgrade("basicFunction"))
{
    codeString = "private timer = 20; private void Update(){ if(timer > 0){GainUnits();}" + "protected void GainUnits(){ units += " + gains + ";}";
}
else if (UpgradeManager.Instance.HasUpgrade("basicCounter") && !UpgradeManager.Instance.HasUpgrade("basicFunction"))
{
    codeString = "private timer = 20; private void Update(){ if(timer > 0){GainUnits();}" + "units += " + gains;
}
else
{
    codeString = "units += " + gains;
}

随着我添加越来越多的升级,我意识到我必须在已经存在的情况下添加越来越多的规则,因为在游戏中添加了更多的工作而创造了指数量的工作

所以我的问题是如何优化它以减轻工作量?

2 个答案:

答案 0 :(得分:0)

您可以尝试更易于维护的方法:

    // arrange a list of bool predicates and corresponding handlers
    var policies = new KeyValuePair<Func<bool>, Action>[]
    {
        new KeyValuePair<Func<bool>, Action>(
            () => {return UpgradeManager.Instance.HasUpgrade("basicFunction") && !UpgradeManager.Instance.HasUpgrade("basicCounter");},
            () => {codeString = "protected void GainUnits(){ units += " + gains + ";}";}),
        new KeyValuePair<Func<bool>, Action>(
            () => {return UpgradeManager.Instance.HasUpgrade("basicCounter") && UpgradeManager.Instance.HasUpgrade("basicFunction");},
            () => {codeString = "private timer = 20; private void Update(){ if(timer > 0){GainUnits();}" + "protected void GainUnits(){ units += " + gains + ";}";}),
        new KeyValuePair<Func<bool>, Action>(
            () => {return UpgradeManager.Instance.HasUpgrade("basicCounter") && !UpgradeManager.Instance.HasUpgrade("basicFunction");},
            () => {codeString = "private timer = 20; private void Update(){ if(timer > 0){GainUnits();}" + "units += " + gains;}),
        new KeyValuePair<Func<bool>, Action>(
            () => {return true;}, // last one should be always true
            () => {codeString = "units += " + gains;}),
    };

    // now let iterate over the policies
    foreach(var policy in policies)
    {
        if (policy.Key()) // evaluate predicates one-by-one
        {
            policy.Value();
            break; // if predicated matched, do the action and break out of the loop
        }   
    }

根据必要的逻辑,您可以使用不同的容器(可以提供更好的性能或灵活性等)。

答案 1 :(得分:0)

else if (UpgradeManager.Instance.HasUpgrade("basicCounter") && !UpgradeManager.Instance.HasUpgrade("basicFunction"))
{
    codeString = "private timer = 20; private void Update(){ if(timer > 0){GainUnits();}" + "units += " + gains;
}

那里看起来不像有效的代码。我假设你想直接在if-block中增加它,就像这样?

"if(timer > 0){ units += " + gains + "; }"

您可以从隔离每个标志修改的代码部分开始:

  • basicCounter:添加timer并实施增加单位的Update()
  • basicFunction:封装单位递增的方式

考虑到这一点,解构代码更容易:

  • 增加单位:

    GainUnits();            // if basicFunction
    units += __GAINS__;     // if !basicFunction
    
  • 计数器:

    private timer = 20;
    
    private void Update() {
    if(timer > 0) {
        /* use the code from <increasing units> */
    }
    }
    
  • 核心实施:

    /* use code from <counter> */          // if basicCounter
    /* use code from <increasing units> */ // if !basicCounter
    

然后把它重新组合在一起:

string GenerateCode()
{
    return string.Join("\n", GetImplementationCode());
}

IEnumerable<string> GetImplementationCode()
{
    return UpgradeManager.Instance.HasUpgrade("basicCounter")
        ? GetCounterCode()
        : GetIncreaseUnitsCode();
}
IEnumerable<string> GetCounterCode()
{
    yield return "private timer = 20;";

    yield return "private void Update() {";
    yield return "if(timer > 0) {";

    foreach (var loc in GetIncreaseUnitsCode())
    {
        yield return loc;
    }

    yield return "}";
    yield return "}";
}
IEnumerable<string> GetIncreaseUnitsCode()
{
    if (UpgradeManager.Instance.HasUpgrade("basicFunction"))
    {
        yield return "GainUnits();";
    }
    else
    {
        var gains = /* insert logics here */;
        yield return $"units += {gains};";
    }
}