24点求解

24点游戏
一:题目分析
24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
基本思路:方法:穷举。
对四个数的运算实则还是算两个,只是进行多步,因此要得到所有可能的组合做到不重不漏同时编程易于实现,我采用定运算顺序变数字顺序的做法,即把运算顺序定下来,前两个先算,将达到的结果与下一个数运算,重复操作即可,变得是运算的数字,这种做法还可以推广到n个数n点,因此对四个数全排列,依次对四个数的前两个数进行四则运算,使四个数变成3个,2个,1个, 结果为24点即满足要求。’
二.算法构造
首先定义数组调用随机数生成函数将4个数存入数组,再定义集合通过多重循环把4个数的排列组合存入集合,遍历集合元素,将取出的4个数依次进行四则运算,由于‘-‘’和‘/’数字交换结果不同所以共有六种情况,构建多重循环遍历各种组合结果等于24则输出表达式,这里的表达式自己构建形式。
三.代码实现

package Point_24;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
class Game{
	//生成四个数的全排列存入集合
   private static ArrayList<double[]> Permutation(double[] a) {
   	ArrayList<double[]> arrayList = new ArrayList<>();
   	for (int i = 0; i < 4; i++) {
   		for (int j = 0; j < 4; j++) {
   			if (i == j)
   				continue;
   			for (int k = 0; k < 4; k++) {
   				if (j == k || k == i)
   					continue;
   				for (int m = 0; m < 4; m++) {
   					if (m == k || m == j || m == i)
   						continue;
   					double[] b = new double[] { a[i], a[j], a[k], a[m] };
   					arrayList.add(b);
   				}
   			}
   		}
   	}
   	return arrayList;
   }
   //对两个数进行四则运算返回结果
   private static double getNum(double a, double b, int i) {
   	switch (i) {
   	case 0:
   		return a + b;
   	case 1:
   		return a - b;
   	case 2: 
   		return b-a;
   	case 3: 
   		return a * b;
   	case 4:  
   		return a / b;
   	case 5:
   		return b / a;
   	}  	
   	return 0;
   }
   //得到算式的所有结果并输出
   public static String getPoint24Answer(double[] num) {
   	char []t=new char[] {'+','-','-','*','/','/'};
   	ArrayList<double[]> intlist = Permutation(num);
   	for (int z = 0; z < intlist.size(); z++) {
   		double a[] = intlist.get(z);   	 
   		for (int i = 0; i < 6; i++) {
   			double a12 = getNum(a[0],a[1], i);
   			for (int j = 0; j < 6; j++) {
   				double a123 = getNum(a12, a[2], j);
   				for (int k = 0; k < 6; k++) {
   					double a1234 = getNum(a123, a[3], k);
   					//由于-和/交换数得的是不同结果,对应程序里即i,j,k=2或者5时输出形式有变化,
   					//这里构建多重判断语句觉得结果输出形式
   					if(a1234==(double)24) {
   						if(i==2||i==5) {
   							if(j==2||j==5) {
   								if(k==2||k==5)
   									//ijk都为2或5
   									System.out.println(String.valueOf((int)a[3])+t[k]+"("+(int)a[2]+t[j]+
   											"("+(int)a[1]+t[i]+(int)a[0]+"))");
   								else
   								System.out.println("("+(int)a[2]+t[j]+"("+(int)a[1]+t[i]+
   										(int)a[0]+"))"+t[k]+(int)a[3]);//k0
   							}
   							else {
   								if(k==2||k==5)
   								System.out.println(String.valueOf((int)a[3])+t[k]+"(("+(int)a[1]+t[i]+
   										(int)a[0]+")"+t[j]+(int)a[2]+")");
   								else System.out.println("(("+(int)a[1]+t[i]+(int)a[0]+")"+
   										t[j]+(int)a[2]+")"+t[k]+(int)a[3]);
   							}
   						}
   						else {
   							if(j==2||j==5) {
   								if(k==2||k==5)
   									System.out.println(String.valueOf((int)a[3])+t[k]+"("+(int)a[2]+t[j]+
   											"("+(int)a[0]+t[i]+(int)a[1]+"))");//i0&&j1&&k1
   								else System.out.println("("+(int)a[2]+t[j]+"("+(int)a[0]+
   										t[i]+(int)a[1]+"))"+t[k]+(int)a[3]);//i0&j1&&k0
   							}
   							else {
   								if(k==2||k==5)
   									System.out.println(String.valueOf((int)a[3])+t[k]+"(("+(int)a[0]+t[i]+
   											(int)a[1]+")"+t[j]+(int)a[2]+")");//i0&&j0&&k1
   								else System.out.println("(("+(int)a[0]+t[i]+(int)a[1]+")"+
   											t[j]+(int)a[2]+")"+t[k]+(int)a[3]);//i0&&j0&&k0
   							}
   						}	
   					} 		
   				}
   			}
   		}
   	}
   	 return null;
}
   static int[]arg=new int[4];//四个数字
   //产生四个随机数并输出
	public static int  Random(int[]arg)
	{
		Random r=new Random();//定义随机变量
		for(int i=0;i<arg.length;i++)
		{
			arg[i]=(int)(Math.abs(r.nextInt())%13+1);//返回数的绝对值
			System.out.print(cards(arg[i])+" ");
		}
		System.out.print("\n");
		return 0;
	}
	//输出卡牌形式数字或者字母
	public static char cards(int p)
	{
		/*判断产生的随机数是否为1,如果为1,则返回字符*/
		if(p==1)
			return 'A';
		else if(p<10)
			//System.out.print(p);
		    return (char)(p+'0');
		else if(p==10)
		{
			System.out.print(Integer.parseInt("10",10));
		    return 10;
		}
		else if(p==11)
			return 'J';
		else if(p==12)
			return 'Q';
		else if(p==13)
			return 'K';	
		else
		return 0;
	}
   public static void main(String[] args) {
	   
		
			int g;//选择标志
			@SuppressWarnings("resource")
			Scanner sc=new Scanner(System.in);
			System.out.println("*****24点*****");
			System.out.println("请输入1生成随机数4个,输入2退出程序");
			g=sc.nextInt();//获取从键盘输入的数字
			//选择0,则退出游戏
			if(g==2)
			{
				System.exit(0);	
			}
			else
			{
				//用do,while循环实现先执行一次,再循环执行的功能。
				do
				{
					    System.out.println("随机生成的四个数");
						Random(arg);//调用随机数生成函数,将生成的数放入数组arg[]中
						            //Random()函数产生4个随机数并调用字母转换函数card()将数字转换为字母输出                                                  					
						System.out.println(getPoint24Answer(new double[]{(double) arg[0], (double)arg[1],(double)arg[2],(double)arg[3]}));
						System.out.println("请选择继续生成还是退出。继续请选1,退出请选2");
						g=sc.nextInt();//获取从键盘输入的数字
				}while(g==1);
			}			
		}
   }

四.运行结果
在这里插入图片描述
五.总结
本次作业在算法上参考了很多网上的人的做法,基本都是穷举法。加上自己的理解完成了基本要求,了解了java中集合这种数据结构,了解了对集合的一些操作,总体感觉代码并不完善,有点复杂,后面可以改进。主要问题还是输出算式这部分有些复杂不直接明了,同时多重循环也不是最好的解决办法,逻辑思维能力,对问题的分析与抽象能力还有待提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值