JAVA实现24点游戏

一. 内容

​ 从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能

二. 步骤

1. 算法分析

随机产生四个数,通过数组限制其均为不同的随机数,将所有运算顺序情况排列出来,刚开始有4个数,拿出两个数进行第一次运算,运算后得出三个数,然后在这三个数中再拿出两个进行第二次运算,运算后就只有两个数了,第三次运算就是将这两个数进行计算,得出最后值,判断最后这个值是否为24,若为24,则输出表达式,若不是,则输出提示消息。然后在这4个数确定位置的情况下,再来改变操作符,即每次2个数进行运算的时候,有4种情况。在下一次计算的时候同样有4种情况,最后一次计算(第3次)同理。这样就找到了所有解的情况。

2. 概要设计

在这里插入图片描述

3. 测试

实现结果:
在这里插入图片描述
在这里插入图片描述

4. 调试

在这里插入图片描述
在这里插入图片描述

5. 代码实现

package Game;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class Compute {
    //定义随机产生的四个数
   static int[] poker = new int[4];
    //转换后的num1,num2,num3,num4
    static int m[]=new int [4];
    static String n[] = new String[4];
    //用来判断是否有解
    static boolean flag = false;
    //存放操作符
    static char[] operator = { '+', '-', '*', '/' };

    public static void main(String[] args){
        Random rand = new Random();
        System.out.println("随机产生四个数字,使用+,-,*,/进行计算,使最后计算结果为24");
        for(int i=0;i<4;i++){
            //随机生成四个不同的int型数
            while(true){
                int number = rand.nextInt(13)+1;
                if(!contains(poker,number)){
                    poker[i] = number;
                    break;
                }
            }
            if(poker[i]==1){
                System.out.println("A");//如果随机生成的数为1,则显示为扑克牌牌面中的A
            }
            else if(poker[i]==11){
                System.out.println("J");//如果随机生成的数为11,则显示为扑克牌牌面中的J
            }
            else if(poker[i]==12){
                System.out.println("Q");//如果随机生成的数为12,则显示为扑克牌牌面中的Q
            }
            else if(poker[i]==13){
                System.out.println("K");//如果随机生成的数为13,则显示为扑克牌牌面中的K
            }
            else
                System.out.println(poker[i]);
        }
        System.out.println("可能的结果有:");
        calculate();
    }

    public static boolean contains(int[] arr, int key) {
        for (int i=0; i<arr.length; i++) {
            //如果相等返回true
            if (arr[i] == key){
                return true;
            }
        }
        return false;
    }

    //计算生成24的函数
    public static void calculate(){
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        //存放数字,用来判断输入的4个数字中有几个重复的,和重复的情况
        for (int i = 0; i < poker.length; i++) {
            if(map.get(poker[i]) == null){
                map.put(poker[i], 1);
            }
            else {
                map.put(poker[i], map.get(poker[i]) + 1);
            }
        }
         if(map.size() == 4){
            //4个数都不同的情况
             int i,j,k,l;

             for (i=0; i<4; i++)    //4的排列 4!=24,每种情况调用calculation
                 for (j=0; j<4; j++)
                     if (j!=i)           //第2数和第1个数不能重复
                         for (k=0; k<4; k++)
                             if (k!=j && k!=i) //第3数和第1,2个数不能重复
                                 for (l=0; l<4; l++)
                                     if (l!=i && l!=j && l!=k) //第4数和第1,2,3个数不能重复
                                     {
                                     calculation(poker[i],poker[j],poker[k],poker[l]);//调用calculation函数,进行进行加、减、乘、除运算
                                     }
        }
        if(flag==false)
            System.out.println("这四张牌面数字无法经过运算得到24!");
    }

    public  static void show(int[] m, int p){
        if(m[p]==1){
            n[p]="A";}
        if(m[p]==2){
            n[p]="2";}
        if(m[p]==3){
            n[p]="3";}
        if(m[p]==4){
            n[p]="4";}
        if(m[p]==5){
            n[p]="5";}
        if(m[p]==6){
            n[p]="6";}
        if(m[p]==7){
            n[p]="7";}
        if(m[p]==8){
            n[p]="8";}
        if(m[p]==9){
            n[p]="9";}
        if(m[p]==10){
            n[p]="10";}
        if(m[p]==11){
            n[p]="J";}
        if(m[p]==12){
            n[p]="Q";}
        if(m[p]==13){
            n[p]="k";}
    }
    public static void calculation(int num1, int num2, int num3, int num4){

        for (int i = 0; i < 4; i++){
            //第1次计算,先从四个数中任意选择两个进行计算
            char operator1 = operator[i];
            int firstResult = calcute(num1, num2, operator1);//先选第一,和第二个数进行计算
            int midResult = calcute(num2, num3, operator1);//先选第二和第三两个数进行计算
            int tailResult = calcute(num3,num4, operator1);//先选第三和第四俩个数进行计算
            for (int j = 0; j < 4; j++){
                //第2次计算,从上次计算的结果继续执行,这次从三个数中选择两个进行计算
                char operator2 = operator[j];
                int firstMidResult = calcute(firstResult, num3, operator2);
                int firstTailResult = calcute(num3,num4,operator2);
                int midFirstResult = calcute(num1, midResult, operator2);
                int midTailResult= calcute(midResult,num4,operator2);
                int tailMidResult = calcute(num2, tailResult, operator2);
                for (int k = 0; k < 4; k++){
                    //第3次计算,也是最后1次计算,计算两个数的结果,如果是24则输出表达式
                    char operator3 = operator[k];
                    //在以上的计算中num1,num2,num3,num4都是整型数值,但若要输出为带有A,J,Q,K的表达式,则要将这四个数都变为String类型,下同
                    if(calcute(firstMidResult, num4, operator3) == 24){
                        m[0]=num1;
                        m[1]=num2;
                        m[2]=num3;
                        m[3]=num4;
                        for(int p=0;p<4;p++){
                            show(m, p);
                        }
                        System.out.println("((" + n[0] + operator1 + n[1] + ")" + operator2 + n[2] + ")" + operator3 + n[3]);
                        flag = true;//若有表达式输出,则将说明有解,下同
                    }
                    if(calcute(firstResult, firstTailResult, operator3) == 24){
                        System.out.println("(" + n[0] + operator1 + n[1] + ")" + operator3 + "(" + n[2] + operator2 + n[3] + ")");
                        flag = true;
                    }
                    if(calcute(midFirstResult, num4, operator3) == 24){
                        m[0]=num1;
                        m[1]=num2;
                        m[2]=num3;
                        m[3]=num4;
                        for(int p=0;p<4;p++){
                            show(m, p);
                        }
                        System.out.println("(" + n[0] + operator2 + "(" + n[1] + operator1 + n[2] + "))" + operator3 + n[3]);
                        flag = true;
                    }
                    if(calcute(num1,midTailResult, operator3) == 24){
                        m[0]=num1;
                        m[1]=num2;
                        m[2]=num3;
                        m[3]=num4;
                        for(int p=0;p<4;p++){
                            show(m, p);
                        }
                        System.out.println(" " + n[0] + operator3 + "((" + n[1] + operator1 + n[2] + ")" + operator2 + n[3] + ")");
                        flag = true;
                    }
                    if(calcute(num1,tailMidResult,operator3) == 24){
                        m[0]=num1;
                        m[1]=num2;
                        m[2]=num3;
                        m[3]=num4;
                        for(int p=0;p<4;p++){
                            show(m, p);
                        }
                        System.out.println(" " + n[0] + operator3 + "(" + n[1] + operator2 + "(" + n[2] + operator1 + n[3] + "))");
                        flag = true;
                    }
                }
            }
        }
    }
    //给定2个数和指定操作符的计算
    public static int calcute(int count1, int count2, char operator) {
        if (operator == '+') {
            return count1 + count2;
        }
        else if (operator == '-') {
            return count1 - count2;
        }
        else if (operator == '*') {
            return count1 * count2;
        }
        else if ((operator == '/' )&& (count2 != 0) && (count1%count2==0)) {
            return count1 / count2;
        }
        else {
            return -1;
        }
    }
}

三. 心得体会

通过查看别人的思想,学习到了24点游戏系统计算的思路,计算的重点就是理解四个数先计算两个数得出一个数,再在剩下的三个数中进行第二次计算,依次知道计算完成;除此之外,还知道了如何生成不同随机数。总之,收获很大,我会继续努力的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值