游戲規則:[請玩家仔細閱讀]
(1)點擊開始游戲進行游戲,玩家初始積分是40分,當玩家積分超過100分時,玩家贏,低於0分時,玩家輸;
(2)游戲開始時,會自動隨機生成一定可以通過四則運算得到24的四張撲克牌【J、Q、K、大小鬼記作10】;
(3)游戲過程中,玩家可以刷新撲克牌,但每刷新一次都會扣3分;
(4)玩家將四張撲克牌,用+、-、*、/及適當的括號組合起來,並把組合的表達式【用英文輸入法】填到輸入框裡面【注意每張紙牌只可以使用一次】;
(5)單擊確定按鈕,游戲將會判斷你輸入的表達式是否符合數學規律,及是否為游戲顯示的四張撲克牌的上的數字;
(6)如果輸入合法,將系統將計算玩家所輸入的表達式的值,如果正確則得5分,有鬼且正確加10分,錯誤扣2分;
(7)若玩家在1分30秒後才算出答案,則得4分,有鬼得8分,錯誤扣2分;
Java代碼片段:
- 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);
- }
- }