c# - 有没有聪明的方法让这个填充更少?如果是怎么办?
问题描述
有没有简单的方法来编写这些代码行?
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);
}
}
我正在考虑动态地执行此操作,但我不知道该怎么做。
解决方案
首先从识别所有重复项开始。我在这些行前添加了评论。除了少数例外,大多数复制粘贴的代码都是可以减少的重复代码。
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 生命值,睡眠一轮)。有多种方法可以继续使用上述模型来支持这样的......这超出了这个答案的范围。
推荐阅读
- javascript - 对象的对象总是返回未定义的 $.each
- python - 执行 pathos.multiprocessing 功能时 Kivy 应用程序克隆/无响应
- javascript - Chrome Devtool 控制台中关于 {} + 0 的结果
- c - “有效类型”的解释?
- powerbi - 如何在矩阵 Power BI 中计算运行总计
- asp.net-core - 在 ASP.NET MVC Core 2.2 Web 应用程序中不使用工具的捆绑和缩小
- javascript - 如何在 React Native 上使用 fetch 登录 API 并捕获登录错误?
- sql-server - 运行总计跳过某些值
- python - Python Reshape Column Into Multiple Columns - Alternating Rows
- angular - RxJs 采摘与 NgRx 选择