首页 > 编程语言 >Java实现扑克牌24点游戏

Java实现扑克牌24点游戏

时间:2023-06-25 10:56:22浏览次数:40  
标签:24 poker2 poker Java 扑克牌 poker1 poker3 operate append

游戏规则:

4张扑克牌 A~K分别代表 1点至13点,要求4张牌加减乘除后得到点数为24.(除法必须整除)

代码实现思路:

  1. 构建初始变量
    image

  2. 实现初始化变量值
    image

  3. 实现运算
    image

  4. 分析可能出现的运算组合
    image
    不考虑运算符优先级,组合3/5/7重复(最后会解释为什么不考虑运算符优先级,注1)

  5. 代码实现将扑克牌的排列组合,与所有运算可能取笛卡尔积进行运算判断
    image

  6. 接上文
    image

  7. 结果输出格式化
    image

点击查看代码
package algorithm;

import java.util.*;

/**
 * 扑克牌24点游戏,4张牌(1~13)加减乘除得到点数24
 */
public class Poker24 {

    //扑克牌最小值
    private static Integer minPoker = 1;

    //扑克牌最大值
    private static Integer maxPoker = 13;

    //正确结果
    private static Integer correctResult = 24;

    //运算数组   1 -> +    2 -> -    3 -> *    4 -> /
    private static Integer[] operateArr = {1, 2, 3, 4};

    //运算符 -> 用来格式化输出结果
    private static String[] operateStr = {"?","+", "-", "*", "/"};

    //扑克牌的所有组合
    private static List<Integer[]> pokerList = new ArrayList<>();

    //运算符的所有可能组合
    private static List<Integer[]> operateList = new ArrayList<>();

    public static void main(String[] args) {

        //2_1.构建扑克牌的所有组合
        for (int poker1 = minPoker; poker1 <= maxPoker; poker1++) {
            for (int poker2 = minPoker; poker2 <= maxPoker; poker2++) {
                for (int poker3 = minPoker; poker3 <= maxPoker; poker3++) {
                    for (int poker4 = minPoker; poker4 <= maxPoker; poker4++) {
                        pokerList.add(new Integer[]{poker1, poker2, poker3, poker4});
                    }
                }
            }
        }

        //2_2.构建加减乘除运算的所有可能排序      ->       4张扑克 三次运算
        for (int ope1 = 1; ope1 <= operateArr.length; ope1++) {
            for (int ope2 = 1; ope2 <= operateArr.length; ope2++) {
                for (int ope3 = 1; ope3 <= operateArr.length; ope3++) {
                    operateList.add(new Integer[]{ope1, ope2, ope3});
                }
            }
        }

        //3.实现扑克牌的加减乘除   ->  calculator


        //4.列出一组扑克牌的7种组合情况    -> 从前向后顺序执行 不需要考虑优先级
        //1   poker1    poker2     poker3      poker4
        //2   (poker1    poker2)     (poker3      poker4)
        //3   (poker1    poker2     poker3)      poker4         -> 执行顺序同第一种
        //4   poker1    (poker2     poker3)      poker4
        //5   poker1    (poker2     poker3      poker4)
        //6   poker1    poker2     (poker3      poker4)         -> 执行顺序,同第二种
        //7   (poker1    poker2)     poker3      poker4         -> 执行顺序,同第一种

        //5.将扑克牌的排列组合,与所有运算可能取笛卡尔积进行运算判断
        List<PokerResult> resultPokerList = new ArrayList<>();
        pokerList.forEach(poker -> {
            List<String> tempResultList = new ArrayList<>();
            operateList.forEach(operate -> {
                //第一种poker1    poker2     poker3      poker4
                int calculator1 = calculator(
                        calculator(
                                calculator(poker[0], poker[1], operate[0]),
                                poker[2],
                                operate[1]),
                        poker[3],
                        operate[2]
                );
                if (calculator1 == correctResult) {
                    String resultStr = toResultStr(poker, operate, 1);
                    tempResultList.add(resultStr);
                }

                //第二种(poker1    poker2)     (poker3      poker4)
                int calculator2 = calculator(
                        calculator(poker[0], poker[1], operate[0]),
                        calculator(poker[2], poker[3], operate[2]),
                        operate[1]);
                if (calculator2 == correctResult) {
                    String resultStr = toResultStr(poker, operate, 2);
                    tempResultList.add(resultStr);
                }

                //第四种 poker1    (poker2     poker3)      poker4
                int calculator4 = calculator(
                        calculator(
                                poker[0],
                                calculator(poker[1], poker[2], operate[1]),
                                operate[0]
                        ),
                        poker[3],
                        operate[2]);
                if (calculator4 == correctResult) {
                    String resultStr = toResultStr(poker, operate, 4);
                    tempResultList.add(resultStr);
                }

                //第五中 poker1    (poker2     poker3      poker4)
                int calculator5 = calculator(
                        poker[0],
                        calculator(
                                calculator(poker[1], poker[2], operate[1]),
                                poker[3],
                                operate[2]
                        ),
                        operate[0]);
                if (calculator5 == correctResult) {
                    String resultStr = toResultStr(poker, operate, 5);
                    tempResultList.add(resultStr);
                }
            });
            if(tempResultList.size() != 0){
                PokerResult pokerResult = new PokerResult(poker, tempResultList);
                Optional<PokerResult> first = resultPokerList.stream()
                        .filter(resultPoker -> resultPoker.getCode().equals(pokerResult.getCode()))
                        .findFirst();
                if(!first.isPresent()){
                    resultPokerList.add(new PokerResult(poker,tempResultList));
                }
            }
        });
        System.out.println("debug to see result");
        resultPokerList.forEach(resultPoker -> System.out.println(resultPoker.toString()));
        System.out.println(resultPokerList.size());
    }

    //计算方法
    public static int calculator(int num1, int num2, int operate) {
        int res = 0; // res 用于存放计算的结果
        switch (operate) {
            case 1:
                res = num1 + num2;
                break;
            case 2:
                res = num1 - num2;// 注意顺序
                break;
            case 3:
                res = num1 * num2;
                break;
            case 4:
                try{
                    if (num1 % num2 == 0) {
                        res = num1 / num2;
                    } else {
                        res = 999;
                    }
                }catch (Exception e){
                    //除数为0会报错,捕获
                    res = 999;
                }
                break;
            default:
                break;
        }
        return res;
    }



    public static String toResultStr(Integer[] poker, Integer[] operate, Integer type) {
        StringBuilder resultBuilder = new StringBuilder();
        switch (type) {
            case 1:
                //    poker1    poker2     poker3      poker4
                resultBuilder.append(poker[0]).append(operateStr[operate[0]]).append(poker[1])
                        .append(operateStr[operate[1]]).append(poker[2]).append(operateStr[operate[2]]).append(poker[3]);
                break;
            case 2:
                //   (poker1  poker2)     (poker3      poker4)
                resultBuilder.append("(").append(poker[0]).append(operateStr[operate[0]]).append(poker[1]).append(")")
                        .append(operateStr[operate[1]]).append("(").append(poker[2]).append(operateStr[operate[2]]).append(poker[3]).append(")");
                break;
            case 3:
                //  (poker1    poker2     poker3)      poker4
                resultBuilder.append("(").append(poker[0]).append(operate[0]).append(poker[1])
                        .append(operate[1]).append(poker[2]).append(")").append(operate[2]).append(poker[3]);
                break;
            case 4:
                //   poker1    (poker2     poker3)      poker4
                resultBuilder.append(poker[0]).append(operateStr[operate[0]]).append("(").append(poker[1])
                        .append(operateStr[operate[1]]).append(poker[2]).append(")").append(operateStr[operate[2]]).append(poker[3]);
                break;
            case 5:
                //   poker1    (poker2     poker3      poker4)
                resultBuilder.append(poker[0]).append(operateStr[operate[0]]).append("(").append(poker[1])
                        .append(operateStr[operate[1]]).append(poker[2]).append(operateStr[operate[2]]).append(poker[3]).append(")");
                break;
            case 6:
                //   poker1    poker2     (poker3      poker4)
                resultBuilder.append(poker[0]).append(operate[0]).append(poker[1]).append(operate[1])
                        .append("(").append(poker[2]).append(operate[2]).append(poker[3]).append(")");
                break;
            case 7:
                //   poker1    poker2     (poker3      poker4)
                resultBuilder.append(poker[0]).append(operateStr[operate[0]]).append(poker[1]).append(operateStr[operate[1]])
                        .append("(").append(poker[2]).append(operateStr[operate[2]]).append(poker[3]).append(")");
                break;
        }
        return resultBuilder.toString();
    }
}

class PokerResult{

    PokerResult(Integer[] resultPoker,List<String> resultString){
        this.resultPoker = resultPoker;
        this.resultString = resultString;

        Arrays.sort(this.resultPoker);
        StringBuilder builder = new StringBuilder();
        for (Integer poker : this.resultPoker) {
            builder.append(poker);
        }
        this.code =  Integer.parseInt(builder.toString());
    }

    // 扑克牌
    private Integer[] resultPoker;

    // 对应的组合集
    private List<String> resultString;

    private Integer code;


    public Integer[] getResultPoker() {
        return resultPoker;
    }

    public void setResultPoker(Integer[] resultPoker) {
        this.resultPoker = resultPoker;
    }

    public List<String> getResultString() {
        return resultString;
    }

    public void setResultString(List<String> resultString) {
        this.resultString = resultString;
    }

    public Integer getCode() {
        return code;
    }

    public void printResult() {
        System.out.println(this.code);
    }

    @Override
    public String toString() {
        return "PokerResult{" +
                "resultPoker=" + Arrays.toString(resultPoker) +
                ", resultString=" + resultString +
                '}';
    }
}


注1:不考虑运算符优先级,因为按优先级运算的排列组合也会出现.
列: 1 + 3 * 2 + 4 代码执行顺序为(1+ 3) * 2 + 4,会出现组合为2 * 3 + 1 + 4的组合解决

标签:24,poker2,poker,Java,扑克牌,poker1,poker3,operate,append
From: https://www.cnblogs.com/xueqizheng/p/17502392.html

相关文章

  • Java学习之mysql为什么可以实现可重复读
    什么是mvccMysql的隔离级别是‘可重复读’,即:事务A在读到一条数据之后,此时事务B对该数据进行了修改操作并提交,那么事务A再读该数据,依然还是原来的内容。它的实现原理是MVCC(Multi-VersionConcurrencyControl)多版本并发控制,MVCC保证当前查询为快照读,所以不受其他事务影响。什......
  • Java 插入排序
    publicstaticint[]insertSort(int[]nums){for(inti=1,len=nums.length;i<len;i++){intcurrent=nums[i];intj=i-1;for(;j>=0&&current<nums[j];j--)num......
  • JavaScript中最好的明暗模式主题切换
    了解如何使用JavaScript、CSS自定义属性、本地存储和系统设置为您的网站构建终极主题Toggle™️。无需框架!我曾经不同意浅色和深色模式切换。“切换开关是用户系统偏好设置!”我会天真地感叹,选择让prefers-color-schemeCSS媒体查询控制我个人网站上的主题。没有切换。没有选择......
  • Java 设计模式实战系列—策略模式
    从优惠打折活动说起电商平台为了增加销量经常搞一些活动,比如618、双十一,还有一些节假日活动,根据销量的变化又经常更新不同的活动。最开始为了增加销量,全场都六折://打六折publicBigDecimalsixDiscount(BigDecimalamount){BigDecimaldiscount=BigDecimal.valueOf(0......
  • 学习笔记-Java动态代理的简单使用
    代理模式一种设计模式简单地说,在代理模式中存在三个角色用户代理被代理的对象用户调用代理,代理去调用被代理的对象以此来实现功能的增强动态代理在java中有两种实现方法JDK中的Proxy类CGLIBJDK中的Proxy类步骤实现InvocationHandler接口......
  • 深入理解 Java 中的 ThreadLocal
    1.什么是ThreadLocal在Java多线程编程中,我们经常会遇到共享变量的并发访问问题。为了解决这个问题,Java提供了ThreadLocal类,它允许我们在每个线程中存储和访问线程局部变量,而不会影响其他线程的数据。2.使用ThreadLocal使用ThreadLocal很简单,我们只需要创建一个Thre......
  • [java] 利用反射,将对象A中与对象B中字段名相同的属性值赋予对象B
    前言:最近开发遇到了这样一个需求,前端提交的表单对应类是origin,但后端数据库表对应类是target,两者中有重合字段,origin类中有待处理字段(例如String[]ids),我想到的解决方案是将origin对象中与target对象的同名字段值赋予target,再将待处理字段拆分后赋予target进行存储。首先想到的就......
  • java循环
    whilewhile(){}do{}while();for(;;){}增强for循环for(声明语句:表达式){}publicclasszqfor{  publicstaticvoidmain(String[]args){​    int[]a={10,20,30,40,50};    for(intx:a){      System.out.println(x);   ......
  • 6.24闲话
    还有不到1个月就要考NOI了,很紧张。今天有一位考上中科大的同学来机房玩,羡慕他可以提前上大学而我还要上一年高三。忽然想起当初我决定停课学OI是因为讨厌文化课,到机房可以逃掉两年文化课,但没想到到了机房还是要学文化课,好在考试变少了很多,也没有班级排名和年级排名。以往的文化......
  • [java学习] Spring的分页插件的使用
    概述:SSM集成常会使用到分页,Spring中提供了方便实用的分页插件  第一步:在Mybatis配置文件(SqlMapConfig.xml)中配置插件组件:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDConfig3.0//EN""http://myb......