代码改变世界

文曲星猜数游戏的一个简单实现

2009-07-08 22:17 by Anders Cui, ... 阅读, ... 评论, 收藏, 编辑

最近比较希望能做一些敏捷开发的实践,昨晚向Nick Wang请教了一下,结合自己的体会,感觉应当从单元测试开始入手,逐步了解XP的相关内容。Nick刚刚出了个小题目,感觉这是学习TDD的一个好机会。

今天看到麒麟.NET的一个非TDD实现,一时手痒也尝试了一下。由于我没有玩过那个游戏,写完后才发现有问题,就偷懒把麒麟.NET生成随机数的方法给“借”了过来。


namespace GuessGame
{
    
public class GuessGame
    {
        
public static readonly int NUMBER_COUNT = 4;
        
        
private int[] answers = null;
        
private int rightNumberCount;
        
private int wrongNumberCount;
        
private int wrongPositionCount;

        
public GuessGame()
        {
            Init();

            GenerateDistinctRandomNumbers();
        }

        
private void Init()
        {
            rightNumberCount 
= 0;
            wrongNumberCount 
= 0;
            wrongPositionCount 
= 0;
        }

        
private void Reset()
        {
            Init();
        }

        
private void GenerateDistinctRandomNumbers()
        {
            answers 
= new int[NUMBER_COUNT];

            Random random 
= new Random();
            
bool allowZero = true;
            
for (int i = 0; i < NUMBER_COUNT; i++)
            {
                
int n = random.Next(10);
                
if (n == 0 && allowZero)
                {
                    answers[i] 
= n;
                    allowZero 
= false;
                }
                
else
                {
                    
while (answers.Contains(n))
                    {
                        n 
= random.Next(10);
                    }
                    answers[i] 
= n;
                }
            }
        }

        
public bool IsRight
        {
            
get
            {
                
return (rightNumberCount == NUMBER_COUNT);
            }
        }

        
public string Result
        {
            
get
            {
                
return string.Format("{0}A{1}B", rightNumberCount, wrongPositionCount);
            }
        }

        
public void Calculate(int[] inputs)
        {
            
if (inputs == null || inputs.Length != NUMBER_COUNT)
            {
                
throw new Exception("Invalid inputs.");
            }

            Reset();

            
for (int i = 0; i < NUMBER_COUNT; i++)
            {
                
int index = Array.IndexOf(answers, inputs[i]);
                
if (index < 0)
                {
                    wrongNumberCount
++;
                }
                
else if (index != i)
                {
                    wrongPositionCount
++;
                }
                
else
                {
                    rightNumberCount
++;
                }
            }
        }
    }

    
class Program
    {
        
private static readonly int GUESS_TIME = 6;

        
static void Main(string[] args)
        {
            PlayGuessGame();

            Console.ReadLine();
        }

        
private static void PlayGuessGame()
        {
            
int[] inputs = null;
            GuessGame game 
= new GuessGame();

            
int i = 1;
            
while (i <= GUESS_TIME)
            {
                inputs 
= GetInput();
                game.Calculate(inputs);
                Console.WriteLine(game.Result);

                
if (game.IsRight)
                {
                    Console.WriteLine(
"Congratulations!");
                    
break;
                }

                i
++;
            }

            
if (!game.IsRight)
            {
                Console.WriteLine(
"i think you are not very clever");
            }
        }

        
private static int[] GetInput()
        {
            
int numberCount = GuessGame.NUMBER_COUNT;
            
int[] inputs = new int[numberCount];

            Console.WriteLine(
"Input {0} numbers: ", numberCount);
            
for (int i = 0; i < numberCount; i++)
            {
                Console.Write(
"  number {0}: ", i + 1);
                inputs[i] 
= Convert.ToInt32(Console.ReadLine());
            }

            
return inputs;
        }
    }
}


完成这些代码的过程采用了我在编写自文档化的代码介绍的方法,即从伪代码开始,期望写出比较具有可读性的代码。发现写这样的小程序还是不错的:)