首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >"24“游戏的计算方案

"24“游戏的计算方案
EN

Code Review用户
提问于 2015-03-07 20:40:42
回答 1查看 258关注 0票数 3

今天晚上我很无聊,决定创建一个程序来计算"24“游戏中给定场景的所有解决方案。

这个游戏的目标是你试图成为第一个找到某张牌的答案的人。牌上有四个数字,从1到9不等。玩家可以使用减法、加、乘和除法来达到数字24,并且只能使用每个数字一次。

例子: 8,8,5,1可能导致8-5 = 3,3*1 = 3,3*8= 24.

我已经将操作符放入枚举中,所选的数字在方法的开头被放入一个列表中。下面的代码正确地计算解决方案,最后选择唯一的解决方案,并将其放入所显示的公共属性中。

对所有这些问题进行裁决的方法:

代码语言:javascript
运行
复制
    private void CalculateSolutions()
    {
        Solutions.Clear();
        var numbers = new List<int>(4) { NumberOne, NumberTwo, NumberThree, NumberFour };
        var solutions = new List<OperatorResult>();

        foreach (Operator operatorOne in Enum.GetValues(typeof (Operator)))
        {
            foreach (Operator operatorTwo in Enum.GetValues(typeof (Operator)))
            {
                foreach (Operator operatorThree in Enum.GetValues(typeof (Operator)))
                {
                    for (var numberOneCounter = 0; numberOneCounter < numbers.Count; numberOneCounter++)
                    {
                        var numberOne = numbers[numberOneCounter];
                        for (var numberTwoCounter = 0; numberTwoCounter < numbers.Count; numberTwoCounter++)
                        {
                            if (numberTwoCounter == numberOneCounter)
                                continue;

                            var numberTwo = numbers[numberTwoCounter];
                            for (var numberThreeCounter = 0;
                                numberThreeCounter < numbers.Count;
                                numberThreeCounter++)
                            {
                                if (numberThreeCounter == numberOneCounter || numberThreeCounter == numberTwoCounter)
                                    continue;

                                var numberThree = numbers[numberThreeCounter];
                                for (var numberFourCounter = 0;
                                    numberFourCounter < numbers.Count;
                                    numberFourCounter++)
                                {
                                    if (numberFourCounter == numberOneCounter ||
                                        numberFourCounter == numberTwoCounter ||
                                        numberFourCounter == numberThreeCounter)
                                        continue;

                                    var numberFour = numbers[numberFourCounter];
                                    var sum = GetTotalSum(numberOne, numberTwo, numberThree, numberFour, operatorOne,
                                        operatorTwo, operatorThree);
                                    if (sum != 24)
                                        continue;

                                    var result = new OperatorResult
                                    {
                                        OperatorOne = operatorOne,
                                        OperatorTwo = operatorTwo,
                                        OperatorThree = operatorThree,
                                        NumberOne = numberOne,
                                        NumberTwo = numberTwo,
                                        NumberThree = numberThree,
                                        NumberFour = numberFour
                                    };
                                    solutions.Add(result);
                                }
                            }
                        }
                    }
                }
            }
        }

        // Select only the unique solutions
        foreach (var solution in OperatorResult.GetUniqueSolutions(solutions))
            Solutions.Add(solution);
    }

枚举:

代码语言:javascript
运行
复制
    public enum Operator
    {
        Multiply = '*',
        Subtract = '-',
        Add = '+',
        Divide = '/'
    }

解决方案财产:

代码语言:javascript
运行
复制
    public static DependencyProperty SolutionsProperty = DependencyProperty.Register("Solutions",
        typeof (ObservableCollection<OperatorResult>), typeof (MainWindow));

    public ObservableCollection<OperatorResult> Solutions
    {
        get { return GetValue(SolutionsProperty) as ObservableCollection<OperatorResult>; }
        set { SetValue(SolutionsProperty, value); }
    }

OperatorResult类:

代码语言:javascript
运行
复制
public class OperatorResult
{
    public Operator OperatorOne { get; set; }
    public Operator OperatorTwo { get; set; }
    public Operator OperatorThree { get; set; }
    public int NumberOne { get; set; }
    public int NumberTwo { get; set; }
    public int NumberThree { get; set; }
    public int NumberFour { get; set; }

    /// <summary>
    /// Gets the unique solutions.
    /// </summary>
    /// <param name="solutions">The solutions.</param>
    public static IEnumerable<OperatorResult> GetUniqueSolutions(List<OperatorResult> solutions)
    {
        var uniqueSolutions = new List<OperatorResult>();
        foreach (var solution in solutions.Where(solution => uniqueSolutions.Count(p => p.Equals(solution)) == 0))
            uniqueSolutions.Add(solution);
        return uniqueSolutions;
    }

/* Resharper's generated Equals and GetHashCode functions are also present here.
   And the equals method does more than just a pure compare.
   This equals method should also filter: 6*8/4*2 is duplicate of 6*8*2/4 */
}

正如您所看到的,这不是最漂亮的代码,在循环方面有七个层次。圈复杂度是16,我找不到办法把它降到10以下。

我能做些什么来减少循环的数量吗?其他改善的迹象也很受欢迎!

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-03-07 22:21:02

首先,在您的Equals中实现OperatorResult

代码语言:javascript
运行
复制
public override bool Equals(object obj)
{
    return Equals(obj as OperatorResult);
}

public bool Equals(OperatorResult operatorResult)
{
    return operatorResult != null && 
           operatorResult.OperatorOne == this.OperatorOne && 
           operatorResult.OperatorTwo == this.OperatorTwo && 
           operatorResult.OperatorThree == this.OperatorThree && 
           operatorResult.NumberOne == this.NumberOne && 
           operatorResult.NumberTwo == this.NumberTwo && 
           operatorResult.NumberThree == this.NumberThree && 
           operatorResult.NumberFour == this.NumberFour;
}

public override int GetHashCode()
{
    var result = 0;
    result = (result * 397) ^ (int)OperatorOne;
    result = (result * 397) ^ (int)OperatorTwo;
    result = (result * 397) ^ (int)OperatorThree;
    result = (result * 397) ^ NumberOne;
    result = (result * 397) ^ NumberTwo;
    result = (result * 397) ^ NumberThree;
    result = (result * 397) ^ NumberFour;
    return result;
}

使用它,您不需要GetUniqueSolutions,只需使用Distinct即可。

现在,您的代码可以表示为以下linq查询:

代码语言:javascript
运行
复制
void CalculateSolutions()
{
    var numbers = new List<int>(4) { 8, 8, 5, 1 };

    var solutions = 
       (from operatorOne in (IEnumerable<Operator>)Enum.GetValues(typeof(Operator))
        from operatorTwo in (IEnumerable<Operator>)Enum.GetValues(typeof(Operator))
        from operatorThree in (IEnumerable<Operator>)Enum.GetValues(typeof(Operator))
        from numberOne in numbers
        from numberTwo in GetRemainingNumbers(numbers, numberOne)
        from numberThree in GetRemainingNumbers(numbers, numberOne, numberTwo)
        from numberFour in GetRemainingNumbers(numbers, numberOne, numberTwo, numberThree)
        where GetTotalSum(numberOne, numberTwo, numberThree, numberFour, 
                          operatorOne, operatorTwo, operatorThree) == 24
        select new OperatorResult
        { 
            OperatorOne = operatorOne,
            OperatorTwo = operatorTwo,
            OperatorThree = operatorThree,
            NumberOne = numberOne,
            NumberTwo = numberTwo,
            NumberThree = numberThree,
            NumberFour = numberFour,
        }).Distinct();
}

IEnumerable<int> GetRemainingNumbers(IEnumerable<int> numbers, params int[] usedNumbers)
{
    var result = numbers.ToList();
    foreach (var number in usedNumbers)
    {
        result.Remove(number);
    }
    return result;
}
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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