24点游戏

题目:24点游戏是经典的纸牌益智游戏。
常见游戏规则:
从扑克中每次取出4张牌。使用加减乘除,第一个能得出24者为赢。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏。
基本要求: 随机生成4个代表扑克牌牌面的数字字母,程序自动列出所有可能算出24的表达式,用擅长的语言(C/C++/Java或其他均可)实现程序解决问题。
1.程序风格良好(使用自定义注释模板)
2.列出表达式无重复。
提高要求:用户初始生命值为一给定值(比如3),初始分数为0。随机生成4个代表扑克牌牌面的数字或字母,由用户输入包含这4个数字或字母的运算表达式(可包含括号),如果表达式计算结果为24则代表用户赢了此局。
1.程序风格良好(使用自定义注释模板)
2.使用计时器要求用户在规定时间内输入表达式,如果规定时间内运算正确则加分,超时或运算错误则进入下一题并减少生命值(不扣分)。
3.所有成绩均可记录在TopList.txt文件中。
一、算法设计
基本要求:在程序中随机生成4个1—13的随机数,用他们所代表的纸牌字符显示,然后用递归的方法找出4个数的所有排列,将每一组排列与4种运算符号的3个位置的所有排列组合的结合进行四则运算,得到结果为24就输出一组组合。
提高要求:在程序中随机生成4个1—13的随机数,用他们所代表的纸牌字符显示,输入四则运算,使用字符串转化成中缀表达式,再将中缀表达式转化成后缀表达式,对后缀表达式进行计算,输入过程的计时器可以用获取系统时间,标记输入开始和结束时间,对结果和输入时间进行判断,将成绩保存,循环以上过程,根据生命值判断结束。
二、算法设计
基本要求

class Cardcreate{
	static String[] card={
		"A","2","3","4","5","6","7","8","9","10","J","Q","K"
	};
	static char[] m= {'+','-','*','/'};
	static int[] num=new int[4];	//随机数数组
	static int count=0;		//保存解法的个数
	static int flag=0;		//保存随机数排列的组数
	void create() {			//获取4个随机数
		for(int i=0;i<4;i++) {
			num[i]=(int)(1+Math.random()*(13-1+1));
			System.out.print(card[num[i]-1]+" ");
		}
	}
	public void sq(int k) { //对随机数进行递归全排列
		if (k == num.length) {
			flag++;
			printResult();		//得到一组数的排列输出	
		}		
		for (int i = k; i < num.length; i++) { 
			{
				int temp = num[k]; 
				num[k] = num[i];
				num[i] = temp;
			}
			
			sq(k + 1);
			{
				int temp = num[k];
				num[k] = num[i];
				num[i] = temp;
			}
		}
		
}
	void printResult(){
	     char[] oper=new char[3];
	     int i,j,k;         
	     for(i=0;i<4;i++)	//对4种运算符的3个位置排列
	     for(j=0;j<4;j++)
	     for(k=0;k<4;k++){
	         oper[0]=m[i];	
	         oper[1]=m[j];
	         oper[2]=m[k];
	         
	         if(getResult(oper))
				 count++;		//正确就计数一次
	     }
	     if(flag==24){
	    	 if(count!=0){
	    		 System.out.println("共"+count+"种解法");
	    	 }
	    	 else{
	          System.out.println("该情况无解\n");
	    	 }
	     }
	 }
	 boolean getResult(char oper[]) {
		int a=num[0];
		int b=num[1];
		int c=num[2];
		int d=num[3];
		double t;
		   //穷举运算次序
	    //1.((A*B)*C)*D
	    t=0;
	    t=getValue(a,b,oper[0]);
	    t=getValue(t,c,oper[1]);
	    t=getValue(t,d,oper[2]);	    
	    if(Math.abs(t-24)<0.0001){
	      printAnswer(1,oper);
	        return true;
	    }
	    
	    //2.(A*(B*C))*D
	    t=0;
	    t=getValue(b,c,oper[1]);
	    t=getValue(a,t,oper[0]);
	    t=getValue(t,d,oper[2]);    
	    if(Math.abs(t-24)<0.0001){
	       printAnswer(2,oper);
	        return true;
	    }
	    
	    //3.(A*B)*(C*D)
	    t=0;
	    t=getValue(getValue(a,b,oper[0]),getValue(c,d,oper[2]),oper[1]);	    
	    if(Math.abs(t-24)<0.0001) {
	        printAnswer(3,oper);
	        return true;
	    }
	    
	    //4.A*(B*(C*D))
	    t=0;
	    t=getValue(c,d,oper[2]);
	    t=getValue(b,t,oper[1]);
	    t=getValue(a,t,oper[0]);
	    
	    if(Math.abs(t-24)<0.0001){
	         printAnswer(4,oper);
	        return true;
	    }
	    
	    //5.A*((B*C)*D) 
	    t=0;
	     t=getValue(b,c,oper[1]);
	    t=getValue(t,d,oper[2]);
	    t=getValue(a,t,oper[0]);	    
	    if(Math.abs(t-24)<0.0001){
	         printAnswer(5,oper);
	        return true;
	    }		
		return false;		
		
	}
	double getValue(double num1, double num2, char o) {
		 double result = 0;
	     
	     switch(o){
	         case '+':
	         result=num1+num2;
	         break;
	        case '-':
				result=num1-num2;
	         break;
	        case '*':
	         result=num1*num2;
	         break;
	        case '/':
	         result=num1/num2;
	         break;
	        default :
	            break;
	     }
	     
	     return result;
	
	}
	void printAnswer(int flag,char oper[]){
	     String a=card[num[0]-1];
	     String b=card[num[1]-1];
	     String c=card[num[2]-1];
	     String d=card[num[3]-1];     
	     switch(flag)
	     {
	         //1.((A*B)*C)*D
	         case 1:
	        	 System.out.println("(("+a+oper[0]+b+")"+oper[1]+c+")"+oper[2]+d);
	             break;
	         //2.(A*(B*C))*D
	         case 2:
	        	 System.out.println("("+a+oper[0]+"("+b+oper[1]+c+"))"+oper[2]+d);
	             break;
	         //3.(A*B)*(C*D)
	         case 3:
	        	 System.out.println("("+a+oper[0]+b+")"+oper[1]+"("+c+oper[2]+d+")");
	             break;
	         //4.A*(B*(C*D))
	         case 4:
	        	 System.out.println(a+oper[0]+"("+b+oper[1]+"("+c+oper[2]+d+"))");
	             break;
	         //5.A*((B*C)*D) 
	         case 5:
	        	 System.out.println(a+oper[0]+"(("+b+oper[1]+c+")"+oper[2]+d+")");
	             break;
	         default:
	             break;
	     } 
	 }
}


public class Card {
	public static void main(String[] args) {
		System.out.println("24点游戏");				
		System.out.println("随机生成纸牌:");
		Cardcreate c=new Cardcreate();
		c.create();
		System.out.println("\n结果:");
		c.sq(0);
	}
}

提高要求

import java.io.*;
import java.util.*;  
 class LT {  
	 String[] card={
			"A","2","3","4","5","6","7","8","9","10","J","Q","K"
	};
    char[] op = {'+','-','*','/','(',')'};  
    String[] strOp = {"+","-","*","/","(",")"};
    int[] num=new int[4];
    int count=0;
    int strength=3;
    int score=0;
    /**
     * 生成随机纸牌
     */
    void create() {
		for(int i=0;i<4;i++) {
			num[i]=(int)(1+Math.random()*(13-1+1));
			System.out.print(card[num[i]-1]+" ");
		}
	}
   
   
    boolean isNum(char c){  
        if(c>='0'&&c<='9'){  
            return true;  
        }  
         return false;
    }  
    //符号判断重载
    boolean isOp(char c){ 
        for(int i=0;i<op.length;i++){  
            if(op[i]==c){  
                return true;  
            }  
        }  
        return false;  
    }  
    boolean isOp(String s){  
        for(int i=0;i<strOp.length;i++){  
            if(strOp[i].equals(s)){  
                return true;  
            }  
        }  
        return false;  
    }  
    /** 
     * 处理输入的计算式 
     * @param str 
     * @return 
     */  
    List<String> work(String str){  
        List<String> list = new ArrayList<String>();  
        char c;  
        StringBuilder sb = new StringBuilder();  
        for(int i=0;i<str.length();i++){  
            c = str.charAt(i);  
            if(isNum(c)){  
                sb.append(c);                 
            }  
            if(c=='A') {
            	list.add("1");
            }else if(c=='J'){
            	list.add("11");
            }else if(c=='Q') {
            	list.add("12");
            }else if(c=='K') {
            	list.add("13");
            }
            if(isOp(c)){  
                if(sb.toString().length()>0){  
                    list.add(sb.toString());  
                    sb.delete(0, sb.toString().length());  
                }  
                list.add(c+"");  
            }  
        }  
        if(sb.toString().length()>0){  
            list.add(sb.toString());  
            sb.delete(0, sb.toString().length());  
        }  
        return list;  
    }  
    void printList(List<String> list){  
        for(String o:list){  
            System.out.print(o+" ");  
        }  
    }  
    /** 
     * 中缀表达式转化为后缀表达式 
     * 1,遇到数字输出 
     * 2,遇到高优先级的全部出栈 
     * 3,最后全部出栈 
     */  
    List<String> InfixToPostfix(List<String> list){  
        List<String> Postfixlist = new ArrayList<String>();//存放后缀表达式  
        Stack<String> stack = new Stack<String>();//暂存操作符  
        //stack.push('#');  
        for(int i=0;i<list.size();i++){  
              
            String s = list.get(i);  
            if(s.equals("(")){  
                stack.push(s);  
            }else if(s.equals("*")||s.equals("/")){  
                stack.push(s);  
            }else if(s.equals("+")||s.equals("-")){  
                if(!stack.empty()){  
                    while(!(stack.peek().equals("("))){  
                        Postfixlist.add(stack.pop());  
                        if(stack.empty()){  
                            break;  
                        }  
                    }  
                    stack.push(s);  
                }else{  
                    stack.push(s);  
                }  
            }else if(s.equals(")")){  
                while(!(stack.peek().equals("("))){  
                    Postfixlist.add(stack.pop());  
                }  
                stack.pop();  
            }else{  
                Postfixlist.add(s);  
            }  
            if(i==list.size()-1){  
                while(!stack.empty()){  
                    Postfixlist.add(stack.pop());  
                }  
            }  
        }  
        return Postfixlist;  
    }  
    /** 
     * 后缀表达式计算 
     */  
   int doCal(List<String> list){  
        Stack<Integer> stack = new Stack<Integer>();  
        for(int i=0;i<list.size();i++){  
            String s = list.get(i);  
            int t=0;  
            if(!isOp(s)){  
                t = Integer.parseInt(s);  
                stack.push(t);  
            }else{  
                if(s.equals("+")){  
                    int a1 = stack.pop();  
                    int a2 = stack.pop();  
                    int v = a2+a1;  
                    stack.push(v);  
                }else if(s.equals("-")){  
                    int a1 = stack.pop();  
                    int a2 = stack.pop();  
                    int v = a2-a1;  
                    stack.push(v);  
                }else if(s.equals("*")){  
                    int a1 = stack.pop();  
                    int a2 = stack.pop();  
                    int v = a2*a1;  
                    stack.push(v);  
                }else if(s.equals("/")){  
                    int a1 = stack.pop();  
                    int a2 = stack.pop();  
                    int v = a2/a1;  
                    stack.push(v);  
                }  
            }  
        }  
        return stack.pop();  
    }  
/**
 * 保存局数,体力,分数
 */

 void save()  {
	 FileWriter result;
	try {
		 result = new FileWriter("TopList.txt",true);
		result.write("\r\n"+count+" "+strength+" "+score);
		result.close();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}	
	
 }
}
public class Play {
    public static void main(String[] args) {  
        LT lt = new LT();
		System.out.println("24点游戏");
		System.out.println("每局限时90秒");	
		boolean flag=false;
		long startTime,endTime,usedTime;
		while(!flag) {
		System.out.println("---------------");
		System.out.println("第"+ ++lt.count +"局");	
		System.out.println("用户生命值为"+lt.strength);
		System.out.println("分数为"+lt.score);
		System.out.println("随机生成纸牌:");
		lt.create();
		startTime =  System.currentTimeMillis();//标记开始输入时间
		System.out.println("\n请输入你的计算");
		Scanner s=new Scanner(System.in);		 
        String str = s.next();  
         endTime=  System.currentTimeMillis();//标记结束输入时间
        usedTime = (endTime-startTime)/1000;//用(结束时间-开始时间)/1000,得到秒级时间
        
        System.out.println("用时为:"+usedTime+"秒"); 
        List<String> list = lt.work(str);  //将字符串转为中缀表达式
        List<String> list2 = lt.InfixToPostfix(list);//中缀表达式转后缀表达式
        int result=lt.doCal(list2);		//后缀表达式计算结果
        System.out.println("计算结果为:"+result); 
        if(usedTime<=90){
        	if(24==result) {
        	System.out.println("成功了");
        	lt.score++;
        	}else { 
        	System.out.println("计算错误");
        	lt.strength--;
        	}
        }else {
        	System.out.println("超时了");
        	lt.strength--;
        }
        lt.save();
        if(lt.strength==0) {
        	flag=true;
        	System.out.println("游戏结束");
        }			
	}  	
    }
}

三、总结
这次的作业的基本要求采用了穷举法解决,但我没办法解决数据的完全不重复,虽然在显示的时候加上不同的括号位置,但按照正常的运算要求来说,次序和位置的不同也会是重复的,不过也只有这样才能列出所有的解决方法。
而提高要求利用的主要是栈的思想进行运算,Java有专为解决栈问题的方法,在这里运用了以前学到的中缀表达式和后缀表达式,也算是再次复习一遍,当然这次的计算也可以用中缀表达式直接求解来简化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值