首页 > 解决方案 > 有没有聪明的方法让这个填充更少?如果是怎么办?

问题描述

有没有简单的方法来编写这些代码行?

if(character == "Orc Lord")
{
    int hp = Character.hp = 100;
    int str = Character.MaxHit = 20;
    int hpp = Character.hpElf = 100;
    Console.WriteLine(hp);
    Console.SetCursorPosition(90, 0);
    Console.Write("Robot: " + BotChar[BotIndex]);
    Console.SetCursorPosition(90, 2);
    Console.WriteLine(hpp);
    while (hpp != 0)
    {
        string attack = Functionality.Select(new string[] { "attack" });

        if(BotChar[BotIndex] == "Dog Lord")
        {
            if (attack == "attack")
            {
                Console.SetCursorPosition(108, 0);
                Console.Write(hpp - str);
            }
        }
    }   
    if(hpp == 0)
    {
        Environment.Exit(0);
    }
}

if(character == "another game character")我不想写每一个角色战斗机会,而是用更少的代码来写。

if (character == "Human Lord")
{
    int hp = Character.hp = 100;
    int str = Character.MaxHit = 20;
    int hpp = Character.hpElf = 100;

    Console.WriteLine(hp);
    Console.SetCursorPosition(90, 0);
    Console.Write("Robot: " + BotChar[BotIndex]);
    Console.SetCursorPosition(90, 2);
    Console.WriteLine(hpp);

    while (hpp != 0)
    {
        string attack = Functionality.Select(new string[] { "attack" });

        if (BotChar[BotIndex] == "Dog Lord")
        {
            if (attack == "attack")
            {
                Console.SetCursorPosition(108, 0);
                Console.Write(hpp - str);
            }
        }
    }

    if (hpp == 0)
    {
        Environment.Exit(0);
    }
}

只是为了更多的文字

if (character == "Elf Lord")
{
    int hp = Character.hp = 100;
    int str = Character.MaxHit = 20;
    int hpp = Character.hpElf = 100;

    Console.WriteLine(hp);
    Console.SetCursorPosition(90, 0);
    Console.Write("Robot: " + BotChar[BotIndex]);
    Console.SetCursorPosition(90, 2);
    Console.WriteLine(hpp);

    while (hpp != 0)
    {
        string attack = Functionality.Select(new string[] { "attack" });

        if (BotChar[BotIndex] == "Dog Lord")
        {
            if (attack == "attack")
            {
                Console.SetCursorPosition(108, 0);
                Console.Write(hpp - str);
            }
        }
    }

    if (hpp == 0)
    {
        Environment.Exit(0);
    }
}

if (character == "Dog Lord")
{
    int hp = Character.hp = 100;
    int str = Character.MaxHit = 20;
    int hpp = Character.hpElf = 100;
    Console.WriteLine(hp);
    Console.SetCursorPosition(90, 0);
    Console.Write("Robot: " + BotChar[BotIndex]);
    Console.SetCursorPosition(90, 2);
    Console.WriteLine(hpp);
    while (hpp != 0)
    {
        string attack = Functionality.Select(new string[] { "attack" });

        if (BotChar[BotIndex] == "Dog Lord")
        {
            if (attack == "attack")
            {
                Console.SetCursorPosition(108, 0);
                Console.Write(hpp - str);
            }
        }
    }
    if (hpp == 0)
    {
        Environment.Exit(0);
    }
}

if (character == "Cat Lord")
{
    int hp = Character.hp = 100;
    int str = Character.MaxHit = 20;
    int hpp = Character.hpElf = 100;

    Console.WriteLine(hp);
    Console.SetCursorPosition(90, 0);
    Console.Write("Robot: " + BotChar[BotIndex]);
    Console.SetCursorPosition(90, 2);
    Console.WriteLine(hpp);

    while (hpp != 0)
    {
        string attack = Functionality.Select(new string[] { "attack" });

        if (BotChar[BotIndex] == "Dog Lord")
        {
            if (attack == "attack")
            {
                Console.SetCursorPosition(108, 0);
                Console.Write(hpp - str);

            }
        }
    }

    if (hpp == 0)
    {
        Environment.Exit(0);
    }
}

我正在考虑动态地执行此操作,但我不知道该怎么做。

标签: c#.net

解决方案


首先从识别所有重复项开始。我在这些行前添加了评论。除了少数例外,大多数复制粘贴的代码都是可以减少的重复代码。

        if (character == "Elf Lord")
        {
            int hp = Character.hp = 100;     // this is written "oddly"
            int str = Character.MaxHit = 20;
            int hpp = Character.hpElf = 100;
            // Console.WriteLine(hp);
            // Console.SetCursorPosition(90, 0);
            // Console.Write("Robot: " + BotChar[BotIndex]);
            // Console.SetCursorPosition(90, 2);
            // Console.WriteLine(hpp);
            // while (hpp != 0)
            // {
                // string attack = Functionality.Select(new string[] { "attack" });

                // if (BotChar[BotIndex] == "Dog Lord")
                // {
                //    if (attack == "attack")
                //    {
                //        Console.SetCursorPosition(108, 0);
                //        Console.Write(hpp - str);
                //    }
                // }
            // } 
            // if (hpp == 0)
            // {
            //    Environment.Exit(0);
            // }
        }

因此,当前存在的“非重复”代码是不同的字符(大概)具有不同的统计信息。让我们从对共同特征进行分类开始:

class Stats {
    string Name { get; set; }
    int MaxHp { get; set; }
    int Strength { get; set; }
    int CurrentHp { get; set; }
}

现在,让我们假设只有一个角色和机器人开始战斗:

var elfLord = new Stats { Name = "Elf Lord", MaxHp = 100, Strength = 10 };
var dogLord = new Stats { Name = "Dog Lord", MaxHp = 50, Strength = 4 };

他们打架:

Fight(elfLord, dogLord);

然后所有重复和重复的代码都可以移动到一个方法:

void Fight(Stats f1, Stats f2) {
    Console.WritLine(f1.Name + " vs. " + f2.Name);
    // Do whatever calculations, ONLY using the two parameters supplied.
    // In the called case, f1.Name == "Elf Lord" (given from caller),
    // and f2.Name == "Dog Lord" given (given from caller)
    // (Assuming full-heals at the start..)
    f1.CurrentHp = f1.MaxHp;
    f2.CurrentHp = f2.MaxHp;
    int turnsLeft = 10;

    // Use >= as check on != 0 will loop forever on OVERDAMAGE
    while (f1.CurrentHp > 0 && f2.CurrentHp > 0 && turnsLeft-- > 0) { 
      // Pseudo code showing how this can get complex, yet remain in little chunks, handling a small part of the task.
      // Perhaps the order of f1/f2 is reversed each round based on an initiative roll..
      // ..but just as in a more complex game, rules can be broken down.
      // And the best part is, NO COPY AND PASTE TO MAINTAIN/FIX THIS CODE!
      // "mX" = Move Order. These are also Stats objects and thus effectively aliases.
      // For a 3+ battle system, movements should be handled as a collection.
      Stats m1, m2;
      if (InitiativeSuccess(f1, f2)) {
        m1 = f1; m2 = f2;
      } else {
        m1 = f2; m2 = f1;
      }

      var m1Attack = GetAttack(GetRandomAttack(), m1, m2);
      var m2Attack = GetAttack(m1Attack /* allow counter */, m2, m1);
      ApplyAttack(m1Attack, m1, m2);
      ApplyAttack(m2Attack, m2, m1);
    }

    if (f1.CurrentHp <= 0 && f2.CurrentHp <= 0) {
      Console.WritLine("Mutual defeat.");
    } else if (f1.CurrentHp <= 0) {
      Console.WriteLine(f1.Name + " defeated.");
    } else if (f2.CurrentHp <= 0) {
      Console.WriteLine(f2.Name + " defeated.");
    } else { // draw (no more turns)
      Console.WriteLine("Both fighters give up.")
    }
}

现在,可以将非重复代码移出,它可能看起来像这样:

// One of many approaches, a simple switch here would also suffice.
// Methods break up logic and unify (reduce duplication of) code.
Stats CreateLordFromName(string lordName) {
  var elfLord = new Stats { Name = "Elf Lord", MaxHp = 100, Strength = 10 };
  var catLord = new Stats { Name = "Meowth Lord", MaxHp = 9, Strength = 999 };
  var namesToLords = new [] { elfLord, catLord }.ToDictionary(v => v.Name, v => v);
  return namesToLords[lordName];
}

Stats hero = CreateLordFromName(character);
Stats bot = CreateLordFromName(BotChar[BotIndex]);

Fight(hero, bot);

在不同实体之间添加交互时,它会变得更有趣。但是,它是上述的扩展:对相似之处进行分类。

其他相似之处可能是角色的攻击。考虑一下这实际上是如何扩展的。随着领域复杂性的增加,新的类型和分类可能会很有用。

var slash = new SlashAttack(); // class SlashAttack : IAttack
var stab = new StabAttack();   // class StabAttack : IAttack

var hero = new Character {
    Stats = ..,
    Attacks = new [] { slash, stab } // IAttack[] array/collection
};

var catLord = new Character {
    Stats = ..,
    Attacks = new [] { meow, hiss, loveLicks }
};

Fight(hero, ..);

对于有趣的交互,考虑可能还有一个“宠物”攻击可以对抗“猫王”导致猫打盹(+1 生命值,睡眠一轮)。有多种方法可以继续使用上述模型来支持这样的......这超出了这个答案的范围。


推荐阅读