一个猜数字的小游戏

晚上闲着无聊,用C#写了类似文曲星上面的那个猜数字的小游戏。 (这款游戏还算经典,当年在它上面可玩了不少时间)

image

算法其实很简单,首先电脑随机生成一个数字,然后和输入的数字比较,返回比较结果即可。

class Numbers
{
    public int[] Value { get; set; }

    public Numbers()
    {
        var data = RandomShuffle(10);
        Value = new int[] { data[0], data[1], data[2], data[3] };
    }

    public Numbers(params int[] value)
    {
        if (value.Length != 4)
            throw new ArgumentException();

        this.Value = value;
    }

    public int Guess(params int[] num)
    {
        int count_a = 0;
        int count_b = 0;

        for (int i = 0; i < Value.Length; i++)
        {
            if (num[i] == Value[i])
                count_a++;

            if (Value.Contains(num[i]))
                count_b++;
        }

        count_b -= count_a;
        return count_a * 10 + count_b;
    }

    static int[] RandomShuffle(int count)
    {
        var data = new List<int>();
        for (int i = 0; i < count; i++)
        {
            data.Add(i);
        }
        var rand = new Random();

        var result = new List<int>();
        var alg = new Func<List<int>, int>(d =>
        {
            var index = rand.Next(d.Count);
            var ret = d[index];
            d.RemoveAt(index);
            return ret;
        });

        while (data.Count > 0)
        {
            result.Add(alg(data));
        }
        return result.ToArray();
    }
}

玩了一下后,便想让电脑来自动猜数字,网上搜了一下,好像算法还不少,不过大部分看得比较晕。好像效率高的只需要5.2步即可猜出来。我一向认为对于简单的东西没必要搞得那么复杂,用一个简洁而直观的实现更容易阅读和扩展。这里是我的实现算法,非常简单,大概就50行左右,好像最多的时候需要7步。对这个算法就没必要讨论了,有兴趣的可以参看这个网页:http://www.javaworld.com.tw/jute/post/page?bid=35&sty=1&age=0&tpg=1&s=105

class Guesser
{
    List<int[]> dicList = new List<int[]>();

    public Guesser()
    {
        for (int i = 123; i <= 9876; i++)
        {
            var a = (i / 1000) % 10;
            var b = (i / 100) % 10;
            var c = (i / 10) % 10;
            var d = (i) % 10;

            //
目前的规则是没有重复数字,其实有重复数字也不影响这个算法
            if (a == b || a == c || a == d || b == c || b == d || c == d)
                continue;

            dicList.Add(new int[] { a, b, c, d });
        }
    }

    public void FiltWithResult(int[] input,int result)
    {
        if (result == 40)
            return;

        var n = new Numbers(input);
        dicList.RemoveAll(dic => n.Guess(dic) != result);
    }

    public int[] GetGuessValue()
    {
        //return dicList[0];
        return dicList[new Random().Next(dicList.Count)];
    }

    //
这个函数用来自动猜数字
    public int Guess(Func<int[],int> resultFunc)
    {        
        int index = 0;
        var PharseToNumber = new Func<int[], int>(n => n[0] * 1000 + n[1] * 100 + n[2] * 10 + n[3]);
        while (true)
        {
            var guessValue = GetGuessValue();
            var ret = resultFunc(guessValue);
            
            Console.WriteLine("{0}: {1} -- {2}", ++index, PharseToNumber(guessValue), ret);
            if (ret == 40)
            {
                Console.WriteLine("result is " + PharseToNumber(guessValue));
                return PharseToNumber(guessValue);
            }

            FiltWithResult(guessValue, ret);
        }
    }
}

加上这个类后,便能实现电脑猜数字了,在网上找了几个猜数字的在线游戏,用它来猜了几把,都能很快的猜出来。然后我又把原来那个游戏程序改写了一下,让它自动生成待猜的数字后后自己右去猜,感觉还是挺有意思的。另外,网上查了一下,貌似有的网游里面就有猜数字的游戏,猜对了送礼物什么的。如果用这个玩意儿让它自动猜个一天的话,估计也能换不少小钱花。^_^ 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值