首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >把相似的方法和不同的文本结合起来?

把相似的方法和不同的文本结合起来?
EN

Code Review用户
提问于 2013-01-07 15:11:46
回答 3查看 198关注 0票数 1

我做了一个流行的猜数游戏,并包括一个人工智能版本,选择随机数。AI版本的Console输出略有不同,差别很小,例如:

代码语言:javascript
复制
I generated a number between 1 and 100. Can you guess it?
You generated a number between 1 and 100. Let me try

首先我做了这个:

代码语言:javascript
复制
Console.WriteLine("{0} generated a number between 1 and 100. {1}", ai? "I" : "You", ai? "Can you guess it?", "Let me try");

由于这需要再做几次,它看起来非常笨拙,但是可以在一个中等长度的方法中实现这两个版本。在此之后,我分离了不同的版本,并创建了两个更简洁的方法GuessUserGuessAI,但它们都有许多相似的代码,除了Console.WriteLine(x)之外,几乎所有东西都是相同的。

有聪明的方法将这两个版本组合成一个小方法吗?

完整版本

EN

回答 3

Code Review用户

回答已采纳

发布于 2013-01-07 18:05:28

我不能说它会更高效,或者设计得更好,但有一种选择是利用多态性,为此创建一组类。

代码语言:javascript
复制
public abstract class GuessBase
{
   protected abstract string GuessMessage { get; }
   protected abstract string WrongMessage { get; }
   protected abstract string RightMessage { get; }

   protected abstract int GetGuess();

   public void DoGuessing()
   {
        Console.WriteLine(GuessMessage);
        while (guess != number)
        {
            if (GetGuess() != number)
                Console.WriteLine(WrongMessage, guess);
            tries++;
        }
        Console.WriteLine(RightMessage, number, tries);
        Console.ReadLine();
    } 
}
public class AIGuess : GuessBase
{
   protected override string GuessMessage
   {
      get
      {
         return "You generated a number between 1 and 100. Let me try";
      }
   }
   // Similar for WrongMessage and RightMessage

   protected override int GetGuess()
   {
      return Pick(number, ref guess);
   }
   // Put Pick() method here.
}
public class UserGuess : GuessBase
{
   protected override string GuessMessage
   {
      get
      {
         return "I generated a number between 1 and 100. Can you guess it?";
      }
   }
   // Similar for WrongMessage and RightMessage

   protected override int GetGuess()
   {
      int guess;
      int.TryParse(Console.ReadLine(), out guess); // This won't do what you want if the user doesn't provide a valid number.
      return guess;
   }
}

然后,在您的主要代码中,执行以下操作:

代码语言:javascript
复制
GuessBase guess;
if (/* AI */) guess = new AIGuess();
else guess = new UserGuess();
guess.DoGuessing();
票数 4
EN

Code Review用户

发布于 2013-01-07 22:58:09

虽然我更喜欢这种多态方式,但是您可以选择下面的内容。注意,我已经删掉了一些精神分裂症自言自语,并且改进了变量的使用。

代码语言:javascript
复制
class Program
{
    static readonly Random Rng = new Random();
    static int min;
    static int max = 100;

    private static void Main()
    {
        var number = Rng.Next(1, 100);
        Console.WriteLine("Do you want to [g]uess or [c]hoose?");

        string choice = Console.ReadLine() ?? "";

        if (choice.StartsWith("c"))
        {
            Console.WriteLine("Insert your number between 1 and 100:");
            int.TryParse(Console.ReadLine(), out number);

            Console.WriteLine("You generated a number between 1 and 100. Let me try");
            int previousGuess = 0;
            var tries = Guess(number, () => Pick(number, ref previousGuess));
            Console.WriteLine("Great, the answer was {0}. It took me {1} tries.", number, tries);
        }
        else
        {
            Console.WriteLine("I generated a number between 1 and 100. Can you guess it?");
            var tries = Guess(number, () => int.Parse(Console.ReadLine()));
            Console.WriteLine("Great, the answer was {0}. It took you {1} tries.", number, tries);
        }

        Console.ReadLine();
    }

    private static int Guess(int number, Func<int> guessMethod)
    {
        int tries = 1;
        while(true)
        {
            var guess = guessMethod();
            if (guess != number)
            {
                Console.WriteLine("No, it's {0} than {1}.", guess < number ? "higher" : "lower", guess);
                tries++;
            }
            else
            {
                return tries;
            }
        } 
    }

    private static int Pick(int number, ref int guess)
    {
        if (guess > number)
            max = guess;
        else
            min = guess;
        return guess = Rng.Next(min, max);
    }
}
票数 3
EN

Code Review用户

发布于 2013-01-08 03:01:02

好吧,我把这两件事合并成一个方法,我认为它既优雅又适合这个简短的程序。我知道类似于Bobson提议的抽象,但我认为这样做太过分了。有什么评论吗?

代码语言:javascript
复制
Random rng = new Random();
int min = 0, guess = 0, tries = 0, max = 100, number = rng.Next(1, 100);
bool ai = false;

Console.WriteLine("Do you want to [g]uess or [c]hoose?");
string choice = Console.ReadLine();
if (choice.StartsWith("c"))
{
    Console.WriteLine("Insert your number between 1 and 100:");
    int.TryParse(Console.ReadLine(), out number);
    ai = true;
}

string message = ai  ? "You generated a number between 1 and 100. Let me try"
                     : "I generated a number between 1 and 100. Can you guess it?";
Console.WriteLine(message);

while (guess != number)
{
    int.TryParse(ai  ? (guess > number ? rng.Next(min, max = guess) : rng.Next(min = guess, max)).ToString()
                     : Console.ReadLine(),
                     out guess);
    if (guess != number)
        Console.WriteLine("No, it's {0} than {1}. Try again.", guess < number ? "higher" : "lower", guess);
    tries++;
}
message = ai  ? "Great, the answer was {0}. It took me {1} tries."
              : "Great, the answer was {0}. It took you {1} tries.";
Console.WriteLine(message, number, tries);
Console.ReadLine();
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/20229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档