Java实现 扑克24点游戏src

来源:互联网 发布:emacs python 编辑:程序博客网 时间:2024/04/30 10:50

一、无括号版:

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);}    }//calculatepublic 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;//返回无穷大}//判断是否等于24public 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) dif(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)) dif(equals(cal(cal(f[0],temp,op[i]),f[3],op[k]))){                         // a     +   (   b    +      c    ))   dSystem.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();}}






原创粉丝点击