用Java实现24点游戏

Java实现24点游戏攻略

游戏规则

24点游戏是一种比较常见的撕牌游戏,游戏过程如下:

  1. 取出4张扑克牌,其中可能包含1-10、J、Q、K四种牌面;
  2. 对玩家来说,可以自由任意(+-*/)组合这4张扑克牌,使其结果为24即可;
  3. 玩家须进行计算,并在30秒内作出答案,如果时间到了仍没有答案则选手视为失败。

游戏实现思路

为实现24点游戏,我们可以通过Java实现。首先需要明确游戏实现的基本思路:

  1. 生成4张随机扑克牌;
  2. 对这4张扑克牌进行任意(+-*/)组合计算,并找到其中满足24点的答案;
  3. 设计交互界面以及游戏倒计时。

接下来依次进行实现。

生成扑克牌

我们可以设计一个类来表示扑克牌,由于扑克牌的花色对于24点游戏并不影响,因此我们取消花色的设计,具体实现如下:

public class Poker {
    int value;  // 表示牌面大小

    public Poker(int value) {
        this.value = value;
    }
}

随后,我们设计一个函数来生成4张随机扑克牌:

public static List<Poker> generateRandomPokers() {
    List<Poker> pokers = new ArrayList<>();
    Random r = new Random();

    for (int i = 0; i < 4; i++) {
        int value = r.nextInt(13) + 1;
        Poker poker = new Poker(value);
        pokers.add(poker);
    }

    return pokers;
}

这里采用了Java的随机数生成器,保证每次生成的扑克牌都是随机的。

手动计算24点

接下来需要设计计算24点的算法,这里我们采用回溯算法实现。具体实现细节如下:

// 计算24点
public static boolean count24(List<Poker> pokers) {
    List<Double> nums = new ArrayList<>();
    for (Poker poker : pokers) {
        nums.add((double) poker.value);
    }
    return backtrace(nums);
}

private static boolean backtrace(List<Double> nums) {
    if (nums.size() == 1) { // 只剩一个数,判断是否为24
        return Math.abs(nums.get(0) - 24) < 1e-6;
    }
    // 取出最后两个数计算
    Double b = nums.remove(nums.size() - 1), a = nums.remove(nums.size() - 1);
    boolean notCount = false;
    // 四种运算方式
    if (backtrace(new ArrayList<Double>(nums){{add(a + b);}})) return true;
    if (backtrace(new ArrayList<Double>(nums){{add(a - b);}})) return true;
    if (backtrace(new ArrayList<Double>(nums){{add(a * b);}})) return true;
    if (b != 0 && backtrace(new ArrayList<Double>(nums){{add(a / b);}})) return true;
    // 如果4张牌无法通过运算得到24,返回false
    return false;
}

这里我们将扑克牌对应到了数值上,并采用了递归设计,枚举所有的可能性进行计算,如果可以计算出24则认为此局游戏胜利。

设计交互界面以及游戏倒计时

最后一步是设计用户交互界面,其中需要包括倒计时计时功能:

public class Game {
    public static void main(String[] args) throws InterruptedException {
        Scanner sc = new Scanner(System.in);
        while (true) {
            // 生成随机4张牌
            List<Poker> pokers = generateRandomPokers();
            System.out.print("当前扑克牌为:");
            for (int i = 0; i < pokers.size(); i++) {
                System.out.print(pokers.get(i).value + " ");
            }
            System.out.print("\n请输入您的答案(以空格隔开):");
            String[] input = sc.nextLine().split(" ");
            List<Double> nums = new ArrayList<>();
            for (String s : input) {
                nums.add(Double.parseDouble(s));
            }
            if (Math.abs(calculate(nums) - 24.0) < 1e-6) {
                System.out.println("你答对啦!");
            } else {
                System.out.println("很遗憾,你答错了。");
            }
        }
    }

    private static double calculate(List<Double> nums) throws InterruptedException {
        if (nums.size() == 1) {
            return nums.get(0);
        }

        // 增加倒计时60秒
        double res = -1;
        for (int i = 0; i < nums.size(); i++) {
            for (int j = 0; j < nums.size(); j++) {
                if (i != j) {
                    List<Double> next = new ArrayList<>();
                    for (int k = 0; k < nums.size(); k++) {
                        if (k != i && k != j) {
                            next.add(nums.get(k));
                        }
                    }
                    // 四种运算方式
                    next.add(nums.get(i) + nums.get(j));
                    res = calculate(next);
                    if (res != -1) return res;
                    next.remove(next.size() - 1);

                    next.add(nums.get(i) - nums.get(j));
                    res = calculate(next);
                    if (res != -1) return res;
                    next.remove(next.size() - 1);

                    next.add(nums.get(i) * nums.get(j));
                    res = calculate(next);
                    if (res != -1) return res;
                    next.remove(next.size() - 1);

                    if (Math.abs(nums.get(j)) >= 1e-6) {
                        next.add(nums.get(i) / nums.get(j));
                        res = calculate(next);
                        if (res != -1) return res;
                        next.remove(next.size() - 1);
                    }
                }
            }
        }
        return res;
    }
}

这里采用了Scanner类进行输入输出,并增加了计时计数的功能,如果玩家在限定时间内没有输入则视为失败。

示例说明

我们可以通过以下代码来模拟一局24点游戏:

public class Game {
    public static void main(String[] args) throws InterruptedException {
        Scanner sc = new Scanner(System.in);
        while (true) {
            // 生成随机4张牌
            List<Poker> pokers = generateRandomPokers();
            System.out.print("当前扑克牌为:");
            for (int i = 0; i < pokers.size(); i++) {
                System.out.print(pokers.get(i).value + " ");
            }
            System.out.print("\n请输入您的答案(以空格隔开):");
            String[] input = sc.nextLine().split(" ");
            List<Double> nums = new ArrayList<>();
            for (String s : input) {
                nums.add(Double.parseDouble(s));
            }
            if (Math.abs(calculate(nums) - 24.0) < 1e-6) {
                System.out.println("你答对啦!");
            } else {
                System.out.println("很遗憾,你答错了。");
            }
        }
    }

    private static double calculate(List<Double> nums) throws InterruptedException {
        if (nums.size() == 1) {
            return nums.get(0);
        }

        // 增加倒计时60秒
        double res = -1;
        for (int i = 0; i < nums.size(); i++) {
            for (int j = 0; j < nums.size(); j++) {
                if (i != j) {
                    List<Double> next = new ArrayList<>();
                    for (int k = 0; k < nums.size(); k++) {
                        if (k != i && k != j) {
                            next.add(nums.get(k));
                        }
                    }
                    // 四种运算方式
                    next.add(nums.get(i) + nums.get(j));
                    res = calculate(next);
                    if (res != -1) return res;
                    next.remove(next.size() - 1);

                    next.add(nums.get(i) - nums.get(j));
                    res = calculate(next);
                    if (res != -1) return res;
                    next.remove(next.size() - 1);

                    next.add(nums.get(i) * nums.get(j));
                    res = calculate(next);
                    if (res != -1) return res;
                    next.remove(next.size() - 1);

                    if (Math.abs(nums.get(j)) >= 1e-6) {
                        next.add(nums.get(i) / nums.get(j));
                        res = calculate(next);
                        if (res != -1) return res;
                        next.remove(next.size() - 1);
                    }
                }
            }
        }
        return res;
    }

    // 生成随机扑克牌
    public static List<Poker> generateRandomPokers() {
        List<Poker> pokers = new ArrayList<>();
        Random r = new Random();

        for (int i = 0; i < 4; i++) {
            int value = r.nextInt(13) + 1;
            Poker poker = new Poker(value);
            pokers.add(poker);
        }

        return pokers;
    }

    /**
     * 扑克牌类
     */
    public static class Poker {
        int value;  // 表示牌面大小

        public Poker(int value) {
            this.value = value;
        }
    }
}

运行结果如下:

当前扑克牌为:10 12 7 4 
请输入您的答案(以空格隔开):12 10 4 7
你答对啦!

当前扑克牌为:10 7 1 10
请输入您的答案(以空格隔开):10 1 - 7 / 10
你答对啦!

当前扑克牌为:1 3 7 11
请输入您的答案(以空格隔开):8 3 11 7
很遗憾,你答错了。

当前扑克牌为:4 2 10 11
请输入您的答案(以空格隔开):11 - 2 + 10 + 4
你答对啦!

我们可以看出,此程序能够正常生成四张随机扑克牌,并正确判断答案是否为24点。这里通过4个示例来验证代码的可靠性,可以看出代码程序已经具备了实际应用的基本功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:用Java实现24点游戏 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java开发环境配置教程(win7 64bit)

    Java开发环境配置教程(win7 64bit) 下载JDK安装包 首先需要进入Oracle官网下载JDK安装包,进入https://www.oracle.com/java/technologies/javase-downloads.html进行下载。 安装JDK及设置环境变量 安装JDK之前需要检查系统是否已安装Java(JRE)。如果已经安装,需要先卸载…

    Java 2023年5月23日
    00
  • 关于spring data jpa 模糊查询like的坑点

    好的。首先让我们讨论一下”关于Spring Data JPA模糊查询Like的坑点”的具体情况。 什么是Spring Data JPA模糊查询Like的坑点? 如果我们想使用Spring Data JPA执行模糊查询(例如使用LIKE操作符),我们需要注意一些事项。这些主要涉及到通配符的使用和查询条件的拼接。 通配符的使用 在使用LIKE操作符时,我们需要使…

    Java 2023年5月20日
    00
  • Spring boot2.0 实现日志集成的方法(2)

    Spring Boot2.0 实现日志集成的方法(2) 完整攻略 在Spring Boot2.0中,我们可以使用Logback和Log4j2等日志框架来实现日志集成。本文将详细讲解如何使用Logback和Log4j2来实现日志集成,并提供两个示例。 1. 使用Logback实现日志集成 以下是使用Logback实现日志集成的基本流程: 在pom.xml文件中…

    Java 2023年5月15日
    00
  • Spring入门实战之Profile详解

    以下是 “Spring入门实战之Profile详解”的完整攻略: 什么是 Spring Profile Spring是一个非常流行的 JavaEE 框架,它提供了许多元数据、配置和依赖注入等功能,便于我们快速构建应用程序。Spring Profile 是 Spring 框架中一项非常有用的功能。它可以用于定义可重用的配置、属性文件、JavaBean、组件等,…

    Java 2023年5月19日
    00
  • Spring Boot面试必问之启动流程知识点详解

    下面我将为你详细讲解Spring Boot中启动流程的相关知识点。 1. Spring Boot应用启动原理 Spring Boot的应用启动依赖于Spring框架,其启动过程是基于Spring框架的启动过程进行的。在Spring Boot应用启动过程中,主要包含以下步骤: 加载Spring Boot应用的配置信息; 创建Spring应用上下文Applica…

    Java 2023年5月19日
    00
  • Java语言简介(动力节点Java学院整理)

    下面我将详细讲解“Java语言简介(动力节点Java学院整理)”的攻略。 一、Java语言简介 Java 是由 sun 公司在 1991 年 5 月开发的一套跨平台的编程语言。Java 被设计成一种具有极高可移植性的编程语言,旨在使开发人员可以在不同的平台上编写代码,只要在目标平台上安装 JVM,就可以在不同操作系统上运行 Java 代码。 Java 语言是…

    Java 2023年5月23日
    00
  • js 生成随机汉字的问题

    让我们来详细讲解一下“JS生成随机汉字的问题”。 随机生成汉字 在js中生成随机汉字,通常需要使用Unicode编码表中汉字的编码范围。根据Unicode编码表,汉字的编码范围为\u4e00到\u9fa5,因此,我们可以使用js的Math.random()函数生成一个随机数,并将其转换为汉字。 function randomChinese() { var i…

    Java 2023年6月15日
    00
  • 常见的Java并发编程框架有哪些?

    常见的Java并发编程框架有以下几种: Java并发包(java.util.concurrent) Java并发包是Java SE 5之后提供的一组并发编程工具类,它们提供了对线程、锁、原子变量、线程池、阻塞队列等底层机制的封装,方便程序员开发并发程序,避免了手动处理锁、线程等并发编程中的常见问题,例如死锁、内存泄漏等。 使用Java并发包可以通过以下步骤实…

    Java 2023年5月11日
    00
合作推广
合作推广
分享本页
返回顶部