import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URL;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;


public class Calculate24 implements ActionListener{	
	JFrame frame=new JFrame();//创建窗口框架
	Dimension screen=frame.getToolkit().getScreenSize();//获取显示器的分辨率
	Container con=frame.getContentPane();//给窗体框架添加容器
	TextField  txtField=new TextField(30);//输入表达式的区域
	JPanel Buttompnl=new JPanel(); //按钮和其他组件的面板
	private int count=43;//初始积分40
	JLabel Title=new JLabel("欢迎使用头脑风暴之心算24点----刘学炜、范碧天、许培涛、陈燕茜同组合作设计");
	JTextArea Count=new JTextArea();//用于显示游戏规则及提示
	MyTimer timeshow=new MyTimer();//显示时间
	JPanel pokerPanel=new JPanel();//显示扑克牌的面板
	JButton btnStart=new JButton("开始游戏/洗牌");//开始游戏和刷牌的按钮
	JButton btnOk=new JButton("确定");//确定按钮
	Label label=new Label("请输入表达式:");//显示输入表达式
    JLabel poker1=new  JLabel();//显示四张扑克牌	
    JLabel poker2=new  JLabel();	
    JLabel poker3=new  JLabel();	
    JLabel poker4=new  JLabel();	
    private Check c=new Check();//引入check类的对象
	Random ran=new Random();//引入随机函数类对象
	private float [] myStatus=new float[4];//四张扑克牌上对应的数字
	private char [] mystatus=new char[4];//四张扑克牌上对应的花色
    private	float[] numbers=new float[4];//输入表达式的四个数字
    private float[] different=new float[4];//调整积分的差别
    private boolean addscore=false;//判断是否加双倍积分
	
	
	Calculate24(){			   	   
		   frame.setTitle("头脑风暴之心算24点");
		   Count.setEditable(false);
		   Count.setLineWrap(true);
		   Count.setWrapStyleWord(true);
		   Count.setSize(600, 85);
		   Count.setBackground(new Color(18,132,57));
           Count.setText("游戏规则:[请玩家仔细阅读]" +
	           		"\n(1)点击开始游戏进行游戏,玩家初始积分是40分,当玩家积分超过100分时,玩家赢,低于0分时,玩家输;" +
	           		"\n(2)游戏开始时,会自动随机生成一定可以通过四则运算得到24的四张扑克牌【J、Q、K、大小鬼记作10】;" +
	           		"\n(3)游戏过程中,玩家可以刷新扑克牌,但每刷新一次都会扣3分;"+
	        		"\n(4)玩家将四张扑克牌,用+、-、*、/及适当的括号组合起来,并把组合的表达式【用英文输入法】填到输入框里面【注意每张纸牌只可以使用一次】;"+
	                "\n(5)单击确定按钮,游戏将会判断你输入的表达式是否符合数学规律,及是否为游戏显示的四张扑克牌的上的数字;"+
	                "\n(6)如果输入合法,将系统将计算玩家所输入的表达式的值,如果正确则得5分,有鬼且正确加10分,错误扣2分;" +
	                "\n(7)若玩家在1分30秒后才算出答案,则得4分,有鬼得8分,错误扣2分;"
	     			   );
		   
           //界面组件的相关设计
            con.add(Title,BorderLayout.NORTH);
		    con.add(Buttompnl,BorderLayout.SOUTH);
		    con.add(pokerPanel,BorderLayout.CENTER);	
		    
		    Buttompnl.add(btnStart);
		    Buttompnl.add(label);
		    Buttompnl.add(txtField);
		    
		    btnStart.setActionCommand("start");
	        btnStart.addActionListener(this);//添加开始按钮监听器
	        btnOk.setActionCommand("ok");
	        btnOk.addActionListener(this); //添加确定按钮监听器	       
	    	pokerPanel.add(poker1);
	    	pokerPanel.add(poker2);
	    	pokerPanel.add(poker3);
	    	pokerPanel.add(poker4);
	    	pokerPanel.add(Count,BorderLayout.SOUTH);
    }
        
    
    
    
    
    //监听器设计
    public void actionPerformed(ActionEvent e) {
		//按下开始按钮
    	Count.setFont(new Font("Dialog",Font.PLAIN,20));  
   	
		if(e.getActionCommand().equals("start")){
			timeshow.usedTime=0;//时间归零
			timeshow.timer.start();	//开始计时		
			Buttompnl.add(btnOk);
			Buttompnl.add(timeshow.usedTimeLabel);
			timeshow.timeText.setText("0分0秒");
			Buttompnl.add(timeshow.timeText);
			count-=3;//刷牌扣3分
			Count.setText("\n\n您目前的积分是:"+count+
					"\n上一道题的系统答案是:"+c.outputs);
			try{for(int i=0;i<4;i++){
				myStatus[i]=(float) ((int)(ran.nextFloat()*14+1));//随机产生四张牌
				mystatus[i]=(char) ('A'+(int)(ran.nextFloat()*4));//随机产生花色
				if(myStatus[i]>10f){//对J、Q、K、鬼作10处理
				different[i]=myStatus[i]-10f;
				myStatus[i]-=different[i];
				}
				else
				 different[i]=0f;
				if(i==3&&!c.check(myStatus))//检验所产生的纸牌是否能够算出24
				i=2;	
			}
			
				if(count<0){//查看刷牌后剩余的积分是否小于0
					timeshow.timer.stop();//停止计时
					timeshow.usedTime=0;//重新时间归零
					for(int i=0;i<4;i++){//返回初始界面
						myStatus[i]=0f;
					    mystatus[i]='A';
					}
						NewPanel(myStatus,mystatus);
						Buttompnl.remove(btnOk);
						txtField.setText("");
						Count.setFont(new Font("Dialog",Font.PLAIN,12));
						Count.setText("游戏规则:[请玩家仔细阅读]" +
				           		"\n(1)点击开始游戏进行游戏,玩家初始积分是40分,当玩家积分超过100分时,玩家赢,低于0分时,玩家输;" +
				           		"\n(2)游戏开始时,会自动随机生成一定可以通过四则运算得到24的四张扑克牌【J、Q、K、大小鬼记作10】;" +
				           		"\n(3)游戏过程中,玩家可以刷新扑克牌,但每刷新一次都会扣3分;"+
				        		"\n(4)玩家将四张扑克牌,用+、-、*、/及适当的括号组合起来,并把组合的表达式【用英文输入法】填到输入框里面【注意每张纸牌只可以使用一次】;"+
				                "\n(5)单击确定按钮,游戏将会判断你输入的表达式是否符合数学规律,及是否为游戏显示的四张扑克牌的上的数字;"+
				                "\n(6)如果输入合法,将系统将计算玩家所输入的表达式的值,如果正确则得5分,有鬼且正确加10分,错误扣2分;" +
				                "\n(7)若玩家在1分30秒后才算出答案,则得4分,有鬼得8分,错误扣2分;"
				     			   );
						count=43;//初始积分40
						new MasgDlg(this,"对不起,挑战失败!重新游戏请按【确定】,退出游戏请按【退出】");
					 
					}
				else{
				for(int i=0;i<4;i++)
					myStatus[i]+=different[i];
			NewPanel(myStatus,mystatus);//显示生成的四张扑克牌
			for(int i=0;i<4;i++){
			   myStatus[i]-=different[i];
			   if(different[i]==4)//双倍加分条件,遇鬼
				 addscore=true;
			 }
			}
		 }catch(Exception e1){
			 
		 }
		}
		//按下确定按钮
		else if (e.getActionCommand().equals("ok")){
			try{float result=calculateString(txtField.getText().trim());			
				if(result==-1f){//输入不合法,或者没有输入正确的数字
					txtField.requestFocus();
					new MsgDlg("您输入的表达式不合法或你使用的数字不是扑克牌上的数字,请重新输入!",this);				
				}else if(result!=24f){//输入合法,但计算结果不是24
					timeshow.usedTime-=8%60;//减去输入时间
					count-=2;	//错误扣2分			
					if(count<0){	//判断积分是否小于0
						timeshow.timer.stop();
						timeshow.usedTime=0;
						timeshow.timeText.setText("0分0秒");
						for(int i=0;i<4;i++){//返回初始界面
							myStatus[i]=0f;
						    mystatus[i]='A';
						}
							NewPanel(myStatus,mystatus);
							Buttompnl.remove(btnOk);
							txtField.setText("");
							Count.setFont(new Font("Dialog",Font.PLAIN,12));
							Count.setText("游戏规则:[请玩家仔细阅读]" +
					           		"\n(1)点击开始游戏进行游戏,玩家初始积分是40分,当玩家积分超过100分时,玩家赢,低于0分时,玩家输;" +
					           		"\n(2)游戏开始时,会自动随机生成一定可以通过四则运算得到24的四张扑克牌【J、Q、K、大小鬼记作10】;" +
					           		"\n(3)游戏过程中,玩家可以刷新扑克牌,但每刷新一次都会扣3分;"+
					        		"\n(4)玩家将四张扑克牌,用+、-、*、/及适当的括号组合起来,并把组合的表达式【用英文输入法】填到输入框里面【注意每张纸牌只可以使用一次】;"+
					                "\n(5)单击确定按钮,游戏将会判断你输入的表达式是否符合数学规律,及是否为游戏显示的四张扑克牌的上的数字;"+
					                "\n(6)如果输入合法,将系统将计算玩家所输入的表达式的值,如果正确则得5分,有鬼且正确加10分,错误扣2分;" +
					                "\n(7)若玩家在1分30秒才算出答案,则得4分,有鬼得8分,错误扣2分;"
					     			   );
							count=43;
							new MasgDlg(this,"对不起,挑战失败!重新游戏请按【确定】,退出游戏请按【退出】");
					}
					else//输出用户所输入的表达式的值
					{
						Count.setText("\n您目前的积分是:"+count+"\n对不起,您输入的表达式的值是"+result+",扣除2分,请重新输入!");
					}
					
				}else if(result==24f){//输入正确,得到24
					timeshow.usedTime-=8%60;//减去输入时间
					if(addscore){//遇鬼,双倍积分
						addscore=false;
						if(timeshow.usedTime>90){//遇鬼,超时加分方法
							count+=8;					    
							Count.setText("\n您目前的积分是:"+count+"\n恭喜你,你的输入正确!但超出1分30秒,获得8分奖励,请做下一道题"+
									"\n上一道题的系统答案是:"+c.outputs);
						}
						else{//遇鬼,正常加分方法
							 count+=10;		
							 Count.setText("\n您目前的积分是:"+count+"\n恭喜你,你的输入正确!获得10分奖励,请做下一道题" +
							 		"\n上一道题的系统答案是:"+c.outputs);
						  }
					    
					}
					else{//普通加分
						if(timeshow.usedTime/60>=2){//超时,普通加分
							count+=4;					    
							Count.setText("\n您目前的积分是:"+count+"\n恭喜你,你的输入正确!但超出1分30秒,获得4分奖励,请做下一道题"+
									"\n上一道题的系统答案是:"+c.outputs);
						}
						else{//普通加分
							 count+=5;
							 Count.setText("\n您目前的积分是:"+count+"\n恭喜你,你的输入正确!获得5分奖励,请做下一道题"+
									 "\n上一道题的系统答案是:"+c.outputs);
							}
					    
					  }
					timeshow.usedTime = 0;   
					txtField.setText("");
					txtField.requestFocus();
					if(count>=100){
						timeshow.timer.stop();
						timeshow.usedTime=0;
						timeshow.timeText.setText("0分0秒");										
						for(int i=0;i<4;i++){
							myStatus[i]=0f;
							mystatus[i]='A';
						}
							NewPanel(myStatus,mystatus);
							Buttompnl.remove(btnOk);
							txtField.setText("");
							Count.setFont(new Font("Dialog",Font.PLAIN,12));
							Count.setText("游戏规则:[请玩家仔细阅读]" +
					           		"\n(1)点击开始游戏进行游戏,玩家初始积分是40分,当玩家积分超过100分时,玩家赢,低于0分时,玩家输;" +
					           		"\n(2)游戏开始时,会自动随机生成一定可以通过四则运算得到24的四张扑克牌【J、Q、K、大小鬼记作10】;" +
					           		"\n(3)游戏过程中,玩家可以刷新扑克牌,但每刷新一次都会扣3分;"+
					        		"\n(4)玩家将四张扑克牌,用+、-、*、/及适当的括号组合起来,并把组合的表达式【用英文输入法】填到输入框里面【注意每张纸牌只可以使用一次】;"+
					                "\n(5)单击确定按钮,游戏将会判断你输入的表达式是否符合数学规律,及是否为游戏显示的四张扑克牌的上的数字;"+
					                "\n(6)如果输入合法,将系统将计算玩家所输入的表达式的值,如果正确则得5分,有鬼且正确加10分,错误扣2分;" +
					                "\n(7)若玩家在1分30秒后才算出答案,则得4分,有鬼得8分,错误扣2分;"
					     			   );
							count=43;
							 new MasgDlg(this,"恭喜您,挑战成功!重新游戏请按【确定】,退出游戏请按【退出】");
					}
					else{
						for(int i=0;i<4;i++){
							myStatus[i]=(float) ((int)(ran.nextFloat()*14+1));
							mystatus[i]=(char) ('A'+(int)(ran.nextFloat()*4));
							if(myStatus[i]>10f){
							different[i]=myStatus[i]-10f;
							myStatus[i]-=different[i];
							}
							else
							 different[i]=0f;
							if(i==3&&!c.check(myStatus))
								i=2;						
						 }	
						for(int i=0;i<4;i++)
							myStatus[i]+=different[i];
						NewPanel(myStatus,mystatus);
						for(int i=0;i<4;i++){
						  myStatus[i]-=different[i];
						  if(different[i]==4)
								 addscore=true;
						}
					}
				}
			}catch(Exception e1){
			  e1.printStackTrace();	
			}
		}
	}

	
    
    
    
    private float calculateString(String str) {
	// 判断玩家输入的表达式的合法性				
					
					int LBracketNum=0;//记录左括号个数
					int RBracketNum=0;//记录右括号个数
					int LBracketPla = 0;//记录左括号位置和   
					int RBracketPla = 0;//记录右括号位置和 
					int []LeftBracket=new int[10];//存放左括号的位置
				    int []RightBracket=new int[10];//存放左括号的位置
				    String tempStr,myString="";//临时字符,数字字符
				    int numberNo=0,operatorNo=0;//数字个数,运算符个数
				    String[]operators=new String[4];//保存运算符
				    for(int i=0;i<4;i++){
						operators[i]="";//运算符数组初始化
					}
				for(int i=0;i<str.length();i++){
					tempStr=str.substring(i,i+1);//对玩家输入的字符串逐个检验
					if(isNumber(tempStr)){//判断是否数字
						myString+=tempStr;
						
					}else if(isOperator(tempStr)){//判断是否运算符
						if(numberNo>=4||operatorNo>=3)
							return -1f;
						try{
							numbers[numberNo]=(float) Integer.parseInt(myString);//对输入的字符串中的数字,转换成浮点型
						}catch(Exception e){					
						}
						myString="";
						numberNo++;//记录数字的个数
						operators[operatorNo]=tempStr;
						operatorNo++;//记录运算符的个数
						}else if(isBracket(tempStr)){//判断是否括号
						continue;		//Do Nothing,跳出本次循环
					    }
					  else 
						  return -1f;				
				}
				 if(myString.length()!=0&&numberNo==3){
					   try{
						   numbers[numberNo]=Float.parseFloat(myString);
					   }catch(Exception e){	
						   return -1f;
					   }
				 }	
		
			    numberNo=0;operatorNo=0;myString="";
				for(int i=0;i<str.length();i++){
					tempStr=str.substring(i,i+1);
					
					if(isNumber(tempStr)){
						myString+=tempStr;
						
							if(numbers[numberNo]==Float.parseFloat(myString)){//判断数字是否一样,若一样则记录个数				
							  numberNo++;
							 
						}
						continue;
					}
				    else if(isOperator(tempStr)){
						operatorNo++;
						myString="";
						continue;
					}
				  else if(isBracket(tempStr)){
					   myString="";
					  
					 if(tempStr.equals("(")){//记录左括号个数
					LBracketNum ++;
					
					LeftBracket[LBracketNum-1]=numberNo+operatorNo+1;//记录每个左括号的位置    
					LBracketPla +=numberNo+operatorNo;	//记录所有左括号的位置和	
				
					}
					else {//用同样的方法处理右括号
					RBracketNum ++;
					
					RightBracket[RBracketNum-1]=numberNo+operatorNo+1; 
					RBracketPla +=numberNo+operatorNo;
					
					}
				  }		
				}				
				
				
				if(LBracketNum==RBracketNum&&LBracketNum==0)//判断是否没有左右括号
				{
					;//Do Nothing
				}
				else if(LBracketNum!=RBracketNum||LBracketPla>=RBracketPla){//括号使用错误(不匹配)
				    return -1f;
				  }
				
				for(int i1=0;i1<LeftBracket.length&&LeftBracket[i1]!=0;i1++){		
					 
					if(LeftBracket[i1]%2==0||LeftBracket[i1]==7){//括号使用错误(左括号位置不正确)
						return -1f;
					}
				}
				for(int i1=0;i1<RightBracket.length&&LeftBracket[i1]!=0;i1++){
					 if(RightBracket[i1]%2!=0||RightBracket[i1]==2){//括号使用错误(右括号位置不正确)
						return -1f;
					}
				}	
    if(!isRightNum())//判断用户输入的数字是否为扑克牌上的数字
		return -1f;						
  
    //计算用户输入的表达式的值	
	else		
		{
		float result=c.string_float(str);
	    return result;
	     }
       
 }	

	
	
	
	private boolean isBracket(String str) {//判断是否为括号的方法
		if(str.equals("(")||str.equals(")")){
			return true;
		}else
		return false;
	}
	
	
	
	
	private boolean isNumber(String str) {//判断是否为数字的方法
		if(str.equals("0")||str.equals("1")||str.equals("2")||str.equals("3")
		||str.equals("4")||str.equals("5")||str.equals("6")||str.equals("7")
		||str.equals("8")||str.equals("9")){
			return true;
		}
		else	
		return false;
	}
	
	
	
	private boolean isOperator(String str) {//判断是否为运算符的方法
		if(str.equals("+")||str.equals("-")||str.equals("*")||str.equals("/")){
			return true;
		}
	else
		return false;
	}
	
	 
	
	
	
	private boolean isRightNum(){//判断表达式的数字就是扑克牌上的数字
	float tempStatus[]=new float[4];
	for(int i=0;i<4;i++){
		tempStatus[i]=myStatus[i];
	}
	for(int i=0;i<4;i++){
		int j=0;
	    boolean existed=false;
		while(j<4&&!existed){
			if(tempStatus[j]==numbers[i]){
				tempStatus[j]=-1f;
				existed=true;
			}
			j++;
		}
		if(!existed)
			return false;
    }
	return true;
  }
    
  
    
    
    
	private void NewPanel(float[] a,char[] Tempb){//扑克牌面板
	pokerPanel.setLayout(new FlowLayout());
	 int []Tempa=new int[4];	
	for(int i=0;i<4;i++){			   
		Tempa[i]=(int)a[i];
	System.out.print(Tempa[i]+""+Tempb[i]+" ");
	}
	System.out.println();
	
	//装载图片
	URL url1=getClass().getResource(Tempa[0]+""+Tempb[0]+".jpg");	
	URL url2=getClass().getResource(Tempa[1]+""+Tempb[1]+".jpg");
	URL url3=getClass().getResource(Tempa[2]+""+Tempb[2]+".jpg");
	URL url4=getClass().getResource(Tempa[3]+""+Tempb[3]+".jpg");
	
	poker1.setIcon(new ImageIcon(url1));
	poker2.setIcon(new ImageIcon(url2));
	poker3.setIcon(new ImageIcon(url3));
	poker4.setIcon(new ImageIcon(url4));
	
	poker1.setBackground(new Color(18,152,57));
	poker2.setBackground(new Color(18,152,57));
	poker3.setBackground(new Color(18,152,57));
	poker4.setBackground(new Color(18,152,57));
	
	frame.setSize(650, 480);
	pokerPanel.setBackground(new Color(18,132,57));
	Buttompnl.setBackground(new Color(18,132,57));
	
	frame.setLocation((screen.width-frame.getSize().width)/2, (screen.height-frame.getSize().height)/2);
	frame.setVisible(true);
	frame.setResizable(false);
	frame.addWindowListener(new WindowAdapter(){//设置窗口关闭监听器
          public void windowClosing(WindowEvent e){
           System.exit(0);
            }
      });
  }	
	

	
	
	public static void main(String[] args){//程序入口,主函数调用
		Calculate24 Start=new Calculate24();//实例化为对象
		float []a=new float[4];
		char []b=new char [4];
		for(int i=0;i<4;i++)
		b[i]='A';
		Start.NewPanel(a,b);
	}
}
最近下载更多
xingxing1234  LV10 2023年3月22日
floweyws  LV6 2022年6月3日
leslie123456  LV4 2018年7月9日
lw19900921  LV25 2018年7月5日
wyx065747  LV67 2017年12月10日
半路出家  LV2 2014年11月13日
hello  LV7 2014年6月17日
骑着猪猪去逛街  LV32 2014年1月7日
最代码官方  LV168 2012年10月31日
yihui1229  LV13 2012年10月31日
最近浏览更多
Dominick  LV14 4月28日
xingxing1234  LV10 2023年3月22日
微信网友_6191697646571520  LV6 2022年11月24日
SZEPEZS  LV8 2022年6月10日
floweyws  LV6 2022年6月3日
liuqiang1314520 2020年10月16日
暂无贡献等级
675104182  LV14 2020年9月22日
hxb2000  LV1 2020年6月5日
a1677596408  LV23 2020年5月16日
lllpppwww  LV5 2020年4月1日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友