24点游戏(Java)

题目:24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
24点游戏是经典的纸牌益智游戏

package chengxushejizuoye3;
import java.util.ArrayList;
import java.util.List;

import com.hbhs.algorithm.HBHSAssert;

/**
 * 计算21点游戏<BR>
 * 给定数字数组,通过+,-,*,/算法得出最终的24点
 *
 * @author walter.xu
 */
public class Count24 {
	public static void main(String[] args) {
        List<Integer> result = new ArrayList<Integer>();
        result.add(2);
        result.add(8);
        result.add(2);
        result.add(2);
        int totalCount = 24;
        List<String> operatioins = point(result, totalCount, false);
        for (String str : operatioins) {
            System.out.println(str);
        }  
}
	 /**
     * 算法思想<BR>
     * 1 将所有的数值按照指定的规则生成所有的可排序的序列
     * 2 针对每一个序列分别计算+,-,*,/操作,并计算最终结果,如果成功记记录下当前的值
     *
     * @param patternList
     * @param result
     * @return
     */
    public static List<String> point(List<Integer> patternList, int result, boolean easyOperation) {

        HBHSAssert.isTrue(patternList == null || patternList.size() < 2, "Pattern must be more two");
        List<String> resultList = new ArrayList<String>();
        // 创建可使用的操作:加减乘除等
        List<String> availableOperationList = generateAvailableOperations(easyOperation);
        // 构造操作的全排列组合
        List<List<String>> operationList = Permutation.permutation(availableOperationList, patternList.size() - 1, true);
        // 构造扑克牌点数的全排列
        List<List<Integer>> intList = Permutation.permutation(patternList);
        // 依次迭代,并计算结果
        for (int i = 0; i < operationList.size(); i++) {
            List<String> currentOperationList = operationList.get(i);
            for (List<Integer> currentIntGroup : intList) {
                // 计算并生成公式结果,如果不为空,则表示该公式最终结果满足24点
                String caclExpression = caclAndGenerateExpression(currentIntGroup, currentOperationList, result);
                if (caclExpression != null) resultList.add(caclExpression);
            }
        }
        return resultList;
    }

    // 计算该组合并生成计算表达式
    private static String caclAndGenerateExpression(List<Integer> currentIntGroup, List<String> currentOperationList, int result) {
        int currentCount = currentIntGroup.get(0);    // 获取第一个值作为当前结果值
        int j = 1;                                    // 下一个值得序号
        for (; j < currentIntGroup.size(); j++) {
            if ("+".equalsIgnoreCase(currentOperationList.get(j - 1))) {
                if (currentIntGroup.get(j) < currentIntGroup.get(j - 1)) break;   // 满足互换率,防止重复计算
                currentCount += currentIntGroup.get(j);
            } else if ("-".equalsIgnoreCase(currentOperationList.get(j - 1))) {
                if (currentIntGroup.get(j) < currentIntGroup.get(j - 1)) break;   // 满足互换率,防止重复计算
                currentCount -= currentIntGroup.get(j);
            } else if ("*".equalsIgnoreCase(currentOperationList.get(j - 1))) {
                if (currentIntGroup.get(j) < currentIntGroup.get(j - 1)) break;   // 满足互换率,防止重复计算
                currentCount *= currentIntGroup.get(j);
            } else if ("/".equalsIgnoreCase(currentOperationList.get(j - 1))) {
                if (currentIntGroup.get(j - 1) % currentIntGroup.get(j) > 0) break;
                currentCount /= currentIntGroup.get(j);
            } else if (">>".equalsIgnoreCase(currentOperationList.get(j - 1))) {
                currentCount = currentCount >> currentIntGroup.get(j);
            } else if ("<<".equalsIgnoreCase(currentOperationList.get(j - 1))) {
                currentCount = currentCount << currentIntGroup.get(j);
            } else if ("^".equalsIgnoreCase(currentOperationList.get(j - 1))) {
                int times = currentIntGroup.get(j);
                int temp = currentCount;
                times--;
                while (times > 0) {
                    currentCount *= temp;
                    times--;
                }
            }
        }
        // 仅当全部参数都使用,并且结果等于期望结果时表示为我们所需要的组合
        if (j == currentIntGroup.size()&&currentCount == result) {
            return formatResult(currentIntGroup, currentOperationList, result);
        }
        return null;
    }

    private static List<String> generateAvailableOperations(boolean easyOperation) {
        List<String> operationList = new ArrayList<String>();
        operationList.add("+");
        operationList.add("-");
        operationList.add("*");
        operationList.add("/");
        if (!easyOperation) {
            operationList.add(">>");
            operationList.add("<<");
            operationList.add("^");
        }
        return operationList;
    }


    private static String formatResult(List<Integer> intList, List<String> operationgList, int result) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < operationgList.size(); i++) {
            str.append("(");
        }
        str.append(intList.get(0));
        for (int i = 1; i < intList.size(); i++) {
            str.append("").append(operationgList.get(i - 1)).append(intList.get(i)).append(")");
        }
        str.append(" = ").append(result);
        return str.toString();

    }

    /**
     * 排列组合类<BR>
     * 用于排列组合各种情况适用
     *
     * @author walter.xu
     */
    private static class Permutation {
        public static <T> List<List<T>> permutation(List<T> args) {
            return permutation(args, false);
        }

        public static <T> List<List<T>> permutation(List<T> args, boolean repeatable) {
            return permutation(args, args.size(), repeatable);
        }

        public static <T> List<List<T>> permutation(List<T> args, int totalSize, boolean repeatable) {
            List<List<T>> resultList = new ArrayList<List<T>>();
            List<T> secondPart = new ArrayList<T>();
            permutation(args, secondPart, resultList, totalSize, repeatable);
            return resultList;
        }

        private static <T> void permutation(List<T> firstPart, List<T> secondPart, List<List<T>> resultList,
                                            int totalSize, boolean repeatable) {
            if (totalSize == secondPart.size()) {
                resultList.add(secondPart);
                return;
            }
            for (int i = 0; i < firstPart.size(); i++) {
                List<T> currentFirstPart = new ArrayList<T>(firstPart);
                List<T> currentSecondPart = new ArrayList<T>(secondPart);
                currentSecondPart.add(firstPart.get(i));
                if (!repeatable) {
                    currentFirstPart.remove(i);
                }
                permutation(currentFirstPart, currentSecondPart, resultList, totalSize, repeatable);
            }
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值