1. 程式人生 > >java 撲克牌 24點小遊戲

java 撲克牌 24點小遊戲

要求:使用者初始生命值為一給定值(比如3),初始分數為0。隨機生成4個代表撲克牌牌面的數字或字母,由使用者輸入包含這4個數字或字母的運算表示式(可

1. 程式風格良好(使用自定義註釋模板)

         2.使用計時器要求使用者在規定時間內輸入表示式,如果規定時間內運算正確則加分,超時或運算錯誤則進入下一題並減少生命值(不扣分)。

         3.所有成績均可記錄在TopList.txt檔案中。

包含括號),如果表示式計算結果為24則代表使用者贏了此局。


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

/*撲克中每次取出4張牌。使用加減乘除,(其中,J代表11,Q代表12,K代表13,A代表1),
 * 按照要求程式設計解決24點遊戲。
*	基本要求: 隨機生成4個代表撲克牌牌面的數字字母,
*	程式自動列出所有可能算出24的表示式,用擅長的語言(C/C++/Java或其他均可)實現程式解決問題。
*24 點遊戲 玩家有三條命 每4張牌有1分鐘時間 來寫出算式 或者寫Null代表無法得出 A-1 J-11 Q-12 K-14*/

/*
*@author kxd
*此程式核心演算法,採用ArrayList來做容器  遞迴 math類  做計算
 * 由於核心演算法會很頻繁的使用遞迴所以本人邏輯思維被搞得有點亂
 * 程式中有一小亮點 靜態getRandomNumber函式  是本人吧Random 函式整合 編寫成了一個很方便可隨意改變生成範圍的函式
 * 
 * */
 
public class Demo1 {
	
	private String  deal (){//發牌函式
		String cards=null;
		for(int i=0;i<3;i++) {
			int card =getRandomNumber(1,13);//呼叫getRandomNumber函式
			if(i==0) {
				if(card==1) {
					cards ="A ";	
				}if(card==11) {
					cards ="J ";
					
				}if(card==12) {
					cards ="Q ";
					
				}if(card==13) {
					cards ="K ";
				}if(card>=2&card<=10) {
					cards=Integer.toString(card)+" ";
				}
			}
			if(i==3) {//最後
			
			if(card==1) {
				cards = cards+"A";	
			}if(card==11) {
				cards = cards+"J";
				
			}if(card==12) {
				cards = cards+"Q";
				
			}if(card==13) {
				cards = cards+"K";
			}if(card>=2&card<=10) {
				cards=cards+Integer.toString(card);
			}
			
			}
			
			else {
				if(card==1) {
					cards = cards+"A ";	
				}if(card==11) {
					cards = cards+"J ";
					
				}if(card==12) {
					cards = cards+"Q ";
					
				}if(card==13) {
					cards = cards+"K ";
				}if(card>=2&card<=10) {
					cards=cards+Integer.toString(card)+" ";
				}
			}	
		}
		System.out.println(cards);
		return cards ;
	}
	public static int getRandomNumber(int start,int end) {//獲取隨機數函式
		
		return (int)(Math.random()*(end-start+1)+start);//數學得學好 ,程式沒煩惱
	}
//轉換牌為數字
	private double transform(String s){
		if(s.equals("A")){
		return 1;
		}
		if(s.equals("J")){
		return 11;
		}
		if(s.equals("Q")){
		return 12;
		}
		if(s.equals("K")){
		return 13;
		}
		int n=Integer.parseInt(s);
		if(n<2||n>10){
		return -1;
		}
		return n;
}

	
	public static String res=null;
	
	public String Point24(String cards) {//讀取卡牌  函式
		if(cards==null||cards.contains("joker")||cards.contains("JOKER")){
			return "ERROR";
		}
		String[] c=cards.split(" ");
		if(c.length!=4){
			return "ERROR";
		}
		ArrayList<Double> d=new ArrayList<Double>();
		ArrayList<String> s=new ArrayList<String>();
		
		for(int i=0;i<4;i++){
			double td=transform(c[i]);
			if(td==-1){
				return "ERROR";
			}
			d.add(td);
			s.add(c[i]);
		}
		res=null;		//清空資料
		recursion(d,s);
		if(res==null){
			return "Null";
		}
		return res;
	}
	
	//遞迴,陣列中取出兩個數計算後結果放回陣列
	private void recursion(ArrayList<Double> d,ArrayList<String> s){
		int n=d.size();
		if(n==1){
			if(Math.abs(d.get(0)-24.0)<=0.000000001){	//防止有分數而產生誤差
				res=s.get(0);		//若陣列只有一個數,且為24,則將算式字串賦值給類靜態變數
//				System.out.println(res);
			}
			return;
		}
		
		for(int i=0;i<n;i++){
			for(int j=i+1;j<n;j++){
				ArrayList<Double> dd=new ArrayList<Double>();//用於遞迴的新陣列
				ArrayList<String> ss=new ArrayList<String>();//用於存放算式的新陣列
				//任意取出兩個數的不同組合情況
				for(int r=0;r<n;r++){
					if(r!=i&&r!=j){
						dd.add(d.get(r));
						ss.add(s.get(r));
					}
				}
				dd.add(d.get(i)+d.get(j));//加入取出的兩數計算結果 a+b
				ss.add("("+s.get(i)+"+"+s.get(j)+")");//記錄兩數計算的算式				
				recursion(dd, ss);//遞迴
				if(res!=null){	//若靜態變數已有值,則返回
					return;
				}
				
				dd.remove(dd.size()-1);//移除上次新增的兩數計算結果
				ss.remove(ss.size()-1);
				dd.add(d.get(i)-d.get(j));//a-b
				ss.add("("+s.get(i)+"-"+s.get(j)+")");				
				recursion(dd, ss);
				if(res!=null){
					return;
				}
				
				dd.remove(dd.size()-1);
				ss.remove(ss.size()-1);
				dd.add(d.get(i)*d.get(j));//a*b
				ss.add(s.get(i)+"*"+s.get(j));				
				recursion(dd, ss);
				if(res!=null){
					return;
				}
				
				dd.remove(dd.size()-1);
				ss.remove(ss.size()-1);
				dd.add(d.get(i)/d.get(j));//a/b
				ss.add(s.get(i)+"/"+s.get(j));				
				recursion(dd, ss);
				if(res!=null){
					return;
				}
				
				dd.remove(dd.size()-1);
				ss.remove(ss.size()-1);
				dd.add(d.get(j)-d.get(i));//b-a
				ss.add("("+s.get(j)+"-"+s.get(i)+")");				
				recursion(dd, ss);
				if(res!=null){
					return;
				}
				
				dd.remove(dd.size()-1);
				ss.remove(ss.size()-1);
				dd.add(d.get(j)/d.get(i));//b/a
				ss.add(s.get(j)+"/"+s.get(i));				
				recursion(dd, ss);	
				if(res!=null){
					return;
				}
			}
		}
		
		
	}

	public static void setFile (String s) throws IOException { //檔案寫入函式
        byte[] bs = s.getBytes();//定義位元組陣列用來當作緩衝區
          

        FileOutputStream fos=new FileOutputStream("E:\\eclipes 英文版工作空間\\程式設計作業\\bin\\作業4撲克牌\\TopList.txt");

        try {	
        	fos.write(bs);
        } catch (IOException e) {
	// TODO Auto-generated catch block
        	e.printStackTrace();
        }//從緩衝區位元組陣列中以位元組流形式取出
        	fos.close();//關閉讀取流


        	File file=new File("E:\\eclipes 英文版工作空間\\程式設計作業\\bin\\作業4撲克牌\\TopList.txt");//建立檔案物件
        	if(file.exists()){//if語句的條件,呼叫exists方法判斷檔案是否存在
        		// System.out.println("檔案成功讀入到指定路徑下");//若檔案存在,則輸出檔案存在
        	}
        	else{//否則
        		System.out.println("輸出檔案不存在");//輸出檔案不存在
        	}


	}	
	
	
	public static void main(String[] args) throws IOException {
		System.out.println("24 點遊戲 玩家有三條命 每4張牌有1分鐘時間 來寫出算式 或者寫Null代表無法得出 A-1 J-11 Q-12 K-14");
		System.out.println("例如:7 7 3 9 ");
		System.out.println("The method to make 24 points is: 3*(9-7/7)");
		int count =3;  int score=0;
		
		boolean bl=true;
		  while (bl) {
			if(count>0) {
			long startTime = System.currentTimeMillis();    //獲取開始時間
		System.out.println(" 發牌如下:");
		Demo1 c = new Demo1();
		 String cards=c.deal();//發牌
		
		System.out.print("The method to make 24 points is: ");
		 Scanner s= new  Scanner(System.in);
		 String str = s.nextLine();
		 long endTime = System.currentTimeMillis();  
		 if(endTime-startTime>=60*1000) {
			 System.out.println("Too Late! ");
			 count--;
			 System.out.println("還有生命值"+count);
			 continue;
		 }
		if ( str.equals(c.Point24(cards))) {
			System.out.println("正確 真skr小機靈鬼!");
			 System.out.println("還有生命值"+count);
			 score++;
			 continue;
		}else {
			System.out.println("錯誤 繼續加油!");
			count--;
			 System.out.println("還有生命值"+count);
			 continue;
			
		}
		 
		
		 }else {
			 bl=false;
		 }
		 }
		  System.out.println("本次成績 :"+score);
		  String sc= Integer.toString(score);
		  setFile (sc);
		  
		System.out.println("Game Over!");
	}
}

執行結果:

 

開啟檔案: