Java实现 扑克24点游戏src

一、无括号版:

1.首先我们需要随机抽取四张牌,

2.然后在其中添加+ - * /  .

3.然后就是对表达式求值,看结果是否等于24.

  如何实现随机抽取牌,并且要保证不会抽到重复的牌?
       首先,我们可以回想一下生活中的24游戏过程,(首先洗牌,幺牌,然后从顶上拿出连续的四张).
哎!那么我们不是可以先随机交换模拟洗牌,然后从顶上拿出连续四张就可以了吗!哈哈
实现细节:(牌编号从[0,51],其中[0-12] [13,25] [26,38] [39,51]分别表示四种花色的牌。)这样保证了不会抽到两张完全一样的牌。

package sunquan;

import java.util.Scanner;
public class T24PiontGame {

	private int [] f=new int [4];//存储四个数字
	private char[] op=new char [4];//存储3个运算符
	//1.洗牌程序和随机取牌程序
	public void shuffle()
    {
		int allCard[] = new int[52];//下标从一开始
		String[] card = {"A", "2", "3", "4", "5", "6", "7", "8", "9","10", "J", "Q", "K" };
	    String[] suits={"黑桃","红心","梅花","方块"};
	    
		for(int i=0;i<allCard.length;i++)
			allCard[i]=i;
		for(int i=0;i<allCard.length;i++)//随机交换
		{
			int index= (int)(Math.random()*allCard.length);
			int temp=allCard[i];
			allCard[i]=allCard[index];
			allCard[index]=temp;
		}
		
		System.out.println("正在洗牌.....");
		for(int i=0;i<4;i++)//取最顶上四张
		{
			String suit=suits[allCard[i]/13];
			String poke=card[allCard[i]%13];
			f[i]=allCard[i]%13+1;
			System.out.println("取到的牌为:"+suit+"  "+poke);
		}
    }
	//3.判断多项式能否构成24点
	public  Boolean judge24Point()
	{
		double []stack =new double[4];//数组模拟 栈
		char[]s   = new char [4];
		int topsign=-1;
		int topnum=-1;
		stack[++topnum]=f[0];
		for(int i=1;i<4;i++)
		{
			switch(op[i-1])
			{
			  case '*':
				  stack[topnum]=stack[topnum]*f[i];
					break;
			  case '/':
				  stack[topnum]=stack[topnum]/f[i];
					break;
			  default:
				  stack[++topnum]=f[i];
				  s[++topsign]=op[i-1];
				  break;
			}
		}
		for(int i=0;i<topnum;i++)
		{
			if(s[i]=='+')
				stack[i+1]=stack[i]+stack[i+1];
			else if(s[i]=='-')
				stack[i+1]=stack[i]-stack[i+1];
		}
		return  (Math.abs(stack[topnum]-24.0)<1e-5)?true:false;
	}
	//2.生成多项式
	public Boolean solve()
	{ 
		char [] sign={'+','-','*','/'};
		Boolean flag=false;
		for(int i=0;i<4;i++)
			for(int j=0;j<4;j++)
				for(int k=0;k<4;k++)
				{  op[0]=sign[i];op[1]=sign[j];op[2]=sign[k];
					if(judge24Point())
					{
					    if(flag==false)System.out.println("The solution:");
					    System.out.println(""+f[0]+op[0]+f[1]+op[1]+f[2]+op[2]+f[3]+"==24");
						  flag=true;
					}
				}
					
		return flag;
	}
	public static void main(String arg[]) {
		
		T24PiontGame t=new T24PiontGame();
		Scanner in=new Scanner(System.in);
		while(true)
		{
			System.out.println("press 1: 洗牌\n"+"press 0: exit");
			if(in.nextInt()==0)break;
			t.shuffle();//洗牌,然后取顶上四张牌
			if(t.solve()!=true)//判断四张牌能否构成24点
				System.out.println("没有找到解,请重新洗牌!");
		}
		in.close();
	}
}

运行结果:


二、添加括号版:

添加括号就改变了运算顺序,那么我们直接从运算顺序着手:
  分析可知:a b c d 总共进行了三次运算;因为每次是对相邻的两个数运算,那么总的情况种数总共才6种:
1 ((a b) c) d 
2 (a b) (c d) 
3 (a (b c)) d 
4  a ((b c) d) 
5  a (b (c d)) 
6 (a b) (c d)
发现第6种情况和情况2重复,那么我们只需要做5次判断即可。
此时,问题得解,是不是发现很多问题看似复杂,换个角度思考分析,发现情况并不复杂,那么聪明的你去用代码实现一下吧!

测试结果:

 对比两个测试结果:发现没有括号,会漏掉很多可行解。

package sunquan;

import java.util.Scanner;
public class T24PiontGame {

	private int [] f=new int [4];//{12,6,8,4};//
	private char [] op=new char [4];
	//1.洗牌程序和随机取牌程序
	public void shuffle()
    {
		int allCard[] = new int[52];//下标从一开始
		String[] card = {"A", "2", "3", "4", "5", "6", "7", "8", "9","10", "J", "Q", "K" };
	    String[] suits={"黑桃","红心","梅花","方块"};
	    
		for(int i=0;i<allCard.length;i++)
			allCard[i]=i;
		for(int i=0;i<allCard.length;i++)//随机交换
		{
			int index= (int)(Math.random()*allCard.length);
			int temp=allCard[i];
			allCard[i]=allCard[index];
			allCard[index]=temp;
		}
		System.out.println("正在洗牌.....");
		for(int i=0;i<4;i++)//取最顶上四张
		{
			String suit=suits[allCard[i]/13];
			String poke=card[allCard[i]%13];
			f[i]=allCard[i]%13+1;
			System.out.println("取到的牌为:"+suit+"  "+poke);
		}
    }
	//calculate
	public double cal(double a,double b,char c)
	{
		  if(c=='+') return a+b;
		  if(c=='-') return a-b;
		  if(c=='*') return a*b;
		  if(Math.abs(b)>1e-3) return a/b;
		  else return 1<<30;//返回无穷大
	}
	//判断是否等于24
	public Boolean equals(double ans)
	{
		return  Math.abs(ans-24.0)<1e-3;
	}
	//3、判断并输出结果
	public Boolean judge()
	{
		Boolean flag=false;
		int i=0,j=1,k=2;
		double temp=cal(f[0],f[1],op[i]);
		//1 ((a b) c) d
		if(equals(cal(cal(temp,f[2],op[j]),f[3],op[k])) )
		{
			System.out.println("(("+f[0]+op[i]+f[1]+")"+op[j]+f[2]+")"+op[k]+f[3]+"==24");flag=true;
		}
		//2 (a b) (c d)
		if(equals(cal(temp,cal(f[2],f[3],op[k]),op[j])) )
		{
			System.out.println("("+f[0]+op[i]+f[1]+")"+op[j]+"("+f[2]+op[k]+f[3]+")==24");flag=true;
		}
		temp=cal(f[1],f[2],op[j]);
		//3 (a (b c)) d
		if(equals(cal(cal(f[0],temp,op[i]),f[3],op[k])))
		{                         // a     +   (   b    +      c    ))   d
			System.out.println("("+f[0]+op[i]+"("+f[1]+op[j]+f[2]+"))"+op[k]+f[3]+"==24");flag=true;
		}
		//4  a ((b c) d)
		if(equals(cal(f[0], cal(temp,f[3],op[k]) ,op[i])))
		{                        
			System.out.println(""+f[0]+op[i]+"(("+f[1]+op[j]+f[2]+")"+op[k]+f[3]+")==24");flag=true;
		}
		//5  a (b (c d))
		temp=cal(f[2],f[3],op[k]);
		if(equals(cal(f[0], cal(f[1],temp,op[j]) ,op[i])))
		{                        
			System.out.println(""+f[0]+op[i]+"("+f[1]+op[j]+"("+f[2]+op[k]+f[3]+"))==24");flag=true;
		}
		return flag;
	}
	//2.生成多项式
	public Boolean solve()
	{ 
		char [] sign={'+','-','*','/'};
		Boolean flag=false;
		for(int i=0;i<4;i++)
			for(int j=0;j<4;j++)
				for(int k=0;k<4;k++)
				{   op[0]=sign[i];op[1]=sign[j];op[2]=sign[k];
					if(judge()) flag=true;
				}		
		return flag;
	}
	public static void main(String arg[]) {
		
		T24PiontGame t=new T24PiontGame();
		Scanner in=new Scanner(System.in);
		while(true)
		{
			System.out.println("press 1: 洗牌\n"+"press 0: exit");
			if(in.nextInt()==0)break;
			t.shuffle();//洗牌,然后取顶上四张牌
			if(t.solve()!=true)//判断四张牌能否构成24点
				System.out.println("没有找到解,请重新洗牌!");
		}
		in.close();
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值