1. 程式人生 > >java實現24點遊戲

java實現24點遊戲

遊戲規則

從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。

基本要求

  • 隨機生成4個代表撲克牌牌面的數字字母,程式自動列出所有可能算出24的表示式
  • 列出表示式無重複
  • 使用者初始生命值為一給定值(比如3),初始分數為0。隨機生成4個代表撲克牌牌面的數字或字母,由使用者輸入包含這4個數字或字母的運算表示式(可包含括號),如果表示式計算結果為24則代表使用者贏了此局。
  • 使用計時器要求使用者在規定時間內輸入表示式,如果規定時間內運算正確則加分,超時或運算錯誤則進入下一題並減少生命值(不扣分)。
  • 所有成績均可記錄在TopList.txt檔案中。

解表示式基本思路

採用窮舉法列舉每一種存在的可能,接著判斷是否值為24,如果等於24,則將表示式存入Set集合,最終遍歷Set集合即可得到所有表示式。具體思路如下:

  1. 採用隨機數生成4個符合要求的資料,假設四個資料為n1,n2,n3,n4 。
  2. 把資料相互組合可以得到如下組合:n1和n2 ,n1和n3,n1和n4,n2和n3,n2和n4,n3和n4
  3. 將上面的組合進行各種可能的運算例如:n1+n2,n1-n2,n2-n1,n1*n2,n1/n2,n2/n1等等。
  4. 把上面組合計算出來的結果存入進對應的陣列中例如:組合相加的結果存入add陣列,相減的結果存入sub陣列……最終將這些陣列存入一個list集合中,目的是為了方便通過迴圈遍歷出每一種組合。
  5. 通過迴圈去遍歷每一種組合,把這些組合在一起進行相加,相減等運算,記錄結果為24的表示式。在這裡需要注意的是,因為陣列得值為兩個數字的運算結果,所以需要根據當前迴圈變數的值和list集合以及陣列存入資料的順序去把表示式格式化成四個數字組成的表示式,否則表示式只有兩個數字。
  • 需要注意的是:在遍歷集合的過程中,由於集合中存入的陣列的資料為兩個資料組合的形式,所以遍歷是隻需要控制好下標,使的每一個表示式中只有n1,n2,n3,n4這四個資料,而不會出現類似於n1,n2,n1,n3 這種組合的方式。
  • 具體的流程圖入下圖所示:
    在這裡插入圖片描述

玩家運算基本思路

在java中使用Timer和Canender即可實現定時的功能,而判斷表示式是否正確,在java中使用Script引擎呼叫eval方法即可判斷表示式的值是否正確,具體思路如下:

  1. 初始化生命值,和分數
  2. 由系統給出四個數字
  3. 玩家給出答案
  4. 判斷給出的答案中的數字和系統給出的數字是否吻合,如果吻合進入5,否則,生命值減一。
  5. 藉助Timer類的schedule()判斷是否超時,如果沒有超時,進入6,否則,生命值減一。
  6. 藉助script引擎的eval()方法可以判斷表示式是否正確,如果正確,分數加一,否則,生命值減一。
    當生命值大於0時執行2,3,4,5,6操做,否則將當前分數寫入檔案。
  • 流程圖如下圖所示
    在這裡插入圖片描述

編碼

Game類,主要實現由系統隨機生成資料,並計算可能的表示式
為了避免除零異常採用了float型別的陣列進行儲存

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;

/**
 * 
 * Title: Test Description: 1. 採用隨機數生成4個符合要求的資料,假設四個資料為n1,n2,n3,n4 。
 * 2.把資料相互組合可以得到如下組合:n1和n2 ,n1和n3,n1和n4,n2和n3,n2和n4。
 * 3.將上面的組合進行各種可能的運算例如:n1+n2,n1-n2,n2-n1,n1*n2,n1/n2,n2/n1等等。 
 * 4.把上面組合計算出來的結果存入進對應的陣列中例如:組合相加的結果存入add陣列,相減的結果存入sub陣列……最終將這些陣列存入一個list集合中,目的是為了方便通過迴圈遍歷出每一種組合。
 * 5.通過迴圈去遍歷每一種組合,把這些組合在一起進行相加,相減等運算,記錄結果為24的表示式
 * @author jianglei
 */
public class Game {
	static Set<String> set = new HashSet<String>();// 使用Set儲存算式表示式可以避免有重複的結果
	float[] data = new float[4];// 存放資料的集合
	float[] add = new float[6];// 存放組合相加的結果的集合
	float[] sub1 = new float[6];// 存放相減的結果(兩個數相減的結果存在兩種可能)
	float[] sub2 = new float[6];// 存放相減的結果
	float[] mul = new float[6];// 存放相乘
	float[] div1 = new float[6];// 存放相除(兩個數相除的結果存在兩種可能)
	float[] div2 = new float[6];// 存放相除
	List<float[]> list = new ArrayList<float[]>();// 存放組合結果運算的集合

	/**
	 * 
	 * Title: combine
	 * </p>
	 * Description: 該方法用來獲取每兩個數字的組合組合, 用1代表第一個數字,2代表第二個數字....共有六種組合方式,分別如下:
	 * 1和2,1和3,1和 4,2和 3,2和 4,3和 4 在上面的組合中,每一種組合都對應著 加減乘除 這四種運算
	 * 將上述的組合的每種計算結果存入上面宣告的集合
	 */
	public void conbine(float n1, float n2, float n3, float n4) {
		add[0] = n1 + n2;
		add[1] = n1 + n3;
		add[2] = n1 + n4;
		add[3] = n2 + n3;
		add[4] = n2 + n4;
		add[5] = n3 + n4;

		sub1[0] = n1 - n2;
		sub1[1] = n1 - n3;
		sub1[2] = n1 - n4;
		sub1[3] = n2 - n3;
		sub1[4] = n2 - n4;
		sub1[5] = n3 - n4;
		sub1[5] = n3 + n4;

		sub2[0] = n2 - n1;
		sub2[1] = n3 - n1;
		sub2[2] = n4 - n1;
		sub2[3] = n3 - n2;
		sub2[4] = n4 - n2;
		sub2[5] = n4 - n3;

		mul[0] = n2 * n1;
		mul[1] = n3 * n1;
		mul[2] = n4 * n1;
		mul[3] = n3 * n2;
		mul[4] = n4 * n2;
		mul[5] = n4 * n3;

		div1[0] = n1 / n2;
		div1[1] = n1 / n3;
		div1[2] = n1 / n4;
		div1[3] = n2 / n3;
		div1[4] = n2 / n4;
		div1[5] = n3 / n4;

		div2[0] = n2 / n1;
		div2[1] = n3 / n1;
		div2[2] = n4 / n1;
		div2[3] = n3 / n2;
		div2[4] = n4 / n2;
		div2[5] = n4 / n3;

		list.add(add);// 把各種組合加入到list集合中,方便通過迴圈來遍歷每一種組合方式
		list.add(sub1);
		list.add(sub2);
		list.add(mul);
		list.add(div1);
		list.add(div2);
	}

	public void getData() {
		Random r = new Random();
		// 獲取1——13的的數字的集合
		data[0] = r.nextInt(12) + 1;
		data[1] = r.nextInt(12) + 1;
		data[2] = r.nextInt(12) + 1;
		data[3] = r.nextInt(12) + 1;
		System.out.print("四個數字為:");
		for (float f : data)
			switch ((int) f) {// 將11,12,13,1變成J,Q,K,A
			case 1:
				System.out.print("A" + " ");
				break;
			case 11:
				System.out.print("J" + " ");
				break;
			case 12:
				System.out.print("O" + " ");
				break;
			case 13:
				System.out.print("K" + " ");
				break;
			default:
				System.out.print((int) f + " ");
				break;
			}
		System.out.println();
		boolean flag = false;// 通過該變數去判斷是否存在表示式
		conbine(data[0], data[1], data[2], data[3]);
		for (int a = 0; a < 3; a++) {// 有種組合方式,分別遍歷每一種組合方法
			for (int b = 0; b < 6; b++) {// 窮舉每一個組合和他們之間的運算
				for (int c = 0; c < 6; c++) {// 判斷每一種組合的每一種運算結果是否等於24
					if ((list.get(b)[a] + list.get(c)[5 - a]) == 24) {
						DataFormat.judge(a, b, c, data, "+", set);
						flag = true;
					}
					// 減法
					if ((list.get(b)[a] - list.get(c)[5 - a]) == 24) {
						DataFormat.judge(a, b, c, data, "-", set);
					}
					if ((list.get(b)[5 - a] - list.get(c)[a]) == 24) {
						DataFormat.judge(a, b, c, data, "-", set);
						flag = true;
					}
					// 乘法
					if ((list.get(b)[a] * list.get(c)[5 - a]) == 24) {
						DataFormat.judge(a, b, c, data, "*", set);
						flag = true;
					}
					// 除法
					if ((list.get(b)[a] / list.get(c)[5 - a]) == 24) {
						DataFormat.judge(a, b, c, data, "/", set);
						flag = true;
					}
					if ((list.get(b)[5 - a] / list.get(c)[a]) == 24) {
						DataFormat.judge(a, b, c, data, "/", set);
						flag = true;
					}
				}
			}
		}
		if (!flag)
			System.out.println("沒有表示式滿足條件");
	}

AutoGame類主要實現由系統給定數值,使用者輸入表示式來根據結過進行計分,並將分數寫入檔案

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class AutoGame {
	static boolean flag = true;//該變數標識是否超時
	static int life = 3;//初始化生命值
	static int score=0;//初始化分數

	/**
	 *開始遊戲的方法,該方法通過當前生命值判斷是否結束 
	 */
	public void start() throws IOException {
		Calendar date = Calendar.getInstance();//例項化Calendar物件
		while(life>0) {//當生命值大於0才會進行
			flag=true;//初始化分數標記
			date.setTime(new Date());
			date.add(Calendar.SECOND, 20);//設定限定時間
			Timer timer = new Timer();
			//當達到限定時間將會執行run()方法,即把全域性變數flag變為false
			timer.schedule(new RemindTask(), date.getTime());
			int answer = answer();
			switch(answer) {
			case -1:
				System.out.println("表示式錯誤!!    當前生命值為"+life+" 分數為:"+score);
				break;
			case -2:
				System.out.println("輸入超時!!    當前生命值為"+life+" 分數為:"+score);
				break;
			case -3:
				System.out.println("結果錯誤!!    當前生命值為"+life+" 分數為:"+score);
				break;
			case 1:	
				System.out.println("正確,得到1分獎勵!!    當前生命值為"+life+" 分數為:"+score);
				break;
			}
			System.out.println("----------");
		}
		System.out.println("遊戲結束……分數為: "+score);//迴圈結束也就是生命值為0,列印遊戲結束
		saveScore(score);//將玩家當前分數存入檔案
		return;
	}
/**
 * 
 * Title: getData</p>  
 * Description:給定任意的資料   
 * @return
 */
	private float[] getData() {
		float[] data = new float[4];
		Random r = new Random();//隨機生成四個資料存入陣列中
		data[0] = r.nextInt(12) + 1;
		data[1] = r.nextInt(12) + 1;
		data[2] = r.nextInt(12) + 1;
		data[3] = r.nextInt(12) + 1;
		System.out.print("四個數字為:");
		for (float f : data)
			switch ((int) f) {
			case 1:
				System.out.print("A" + " ");
				break;
			case 11:
				System.out.print("J" + " ");
				break;
			case 12:
				System.out.print("O" + " ");
				break;
			case 13:
				System.out.print("K" + " ");
				break;
			default:
				System.out.print((int) f + " ");
				break;
			}
		System.out.println("請開始作答,時間20秒");
		return data;
	}

	/**
	 * 
	 * Title: answer</p>  
	 * Description:根據使用者輸入返回false或true
	 * 1.輸入不含給定值,返回FALSE
	 * 2.輸入超時,返回false
	 * 3.輸入表示式的值不為24,返回false
	 * 否則,返回true   
	 * @return -1代表輸入的表示式與系統給出的數字不吻合
	 * @return -2代表使用者計算結果超時
	 * @return -3代表結果錯誤
	 * @return 1代表使用者計算正確
	 */
	public int answer() {
		Scanner sc = new Scanner(System.in);
		float[] data = getData();//獲取給定的資料
		//獲取script引擎,呼叫eval()方法來判斷表示式是否正確
		ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
		ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("nashorn");
		String exper = sc.next();
		try {
			String res = String.valueOf(scriptEngine.eval(exper));
			for (int i = 0; i < data.length; i++)
				if (!exper.contains(data[i] + "")) {//輸入的表示式不含給定的值
					life--;
					return -1;
				}
			if(!flag) {//判斷超時
				life--;
				return -2;
			}
			if (res.equals("24")) {//回答正確並且沒有超時
				score++;//分數加一
				return 1;
			}
			life--;
		} catch (ScriptException e) {
			System.out.println("表示式輸入不合法");
		}
		return -3;

	}
	/**
	 * Title: saveScore</p>  
	 * Description:   該方法表示將玩家當前分數存入TopList.txt檔案
	 * @param score 需要存入的分數
	 * @throws IOException
	 */
	public static void saveScore(int score) throws IOException {
		FileOutputStream fos = new FileOutputStream("e:/TopList.txt");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		bos.write((score+"").getBytes());//把分數寫入檔案
		bos.close();
		
	}
	public static void main(String[] args) throws IOException {
		saveScore(1);
	}
}
/**
 * 
* Title: RemindTask
* Description:該TimerTask並且重寫run()可以實現在指定的定時時間執行run方法的內容
* @author jianglei  
 */
class RemindTask extends TimerTask {

	@Override
	public void run() {
		AutoGame.flag = false;//當超時會把全域性變數flag變為false
	}

}

DataFormat類根據a b c是三個迴圈變數將兩個組合數字的運算格式化成四個數字的表示式
由於程式碼比較長,在這裡只留一種情況的,其餘的情況與它類似

import java.util.Set;
/**
 * 
* Title: GetFoamat
* Description:   該類通過在迴圈中的a b c的值判斷出當前所參與運算的值與參加運算的符號,假設四個值為n0,n1,n2,n3
* 形參 a、b、c為迴圈變數,形參n陣列為參與運算的四個數字,形參op表示當前進行的運算型別,形參set為儲存結果的容器

 */
public class DataFormat {
	public static void  judge(int a,int b,int c,float[]n,String op,Set<String> set) {
		StringBuilder sb = new StringBuilder();
		if(a==0) {//n0和n1 與n2和n3之間的運算
			if(b==0) {//n0+n1
				if(c==0) {//n2+n3
					sb.append("(").append(n[0]).append("+").append(n[1]).append(")").append(op).append("(").append(n[2]).append("+").append(n[3]).append(")").append("=24");
				}if(c==1) {//n2-n3
					sb.append("(").append(n[0]).append("+").append(n[1]).append(")").append(op).append("(").append(n[2]).append("-").append(n[3]).append(")").append("=24");
				}if(c==2) {//n3-n2
					sb.append("(").append(n[0]).append("+").append(n[1]).append(")").append(op).append("(").append(n[3]).append("-").append(n[2]).append(")").append("=24");
				}if(c==3) {// n2*n3
					sb.append("(").append(n[0]).append("+").append(n[1]).append(")").append(op).append("(").append(n[2]).append("*").append(n[3]).append(")").append("=24");
				}if(c==4) {// n2/n3
					sb.append("(").append(n[0]).append("+").append(n[1]).append(")").append(op).append("(").append(n[2]).append("/").append(n[3]).append(")").append("=24");
				}if(c==5) {// n3/n2
					sb.append("(").append(n[0]).append("+").append(n[1]).append(")").append(op).append("(").append(n[3]).append("/").append(n[2]).append(")").append("=24");
				}
				//將運算表示式存入容器
				set.add(sb.toString());
				//將sb清空
				sb = new StringBuilder();
			}if(b==1) {//n0-n1
			//由於這種程式碼篇幅比較長,在這裡省略了,思路和上面的一致
			}

測試

import java.io.IOException;
import java.util.Scanner;

public class Test {
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		Game t = new Game();
		System.out.println("----------");
		System.out.println("1.隨機生成數判斷");
		System.out.println("2.使用者輸入運算式");
		System.out.println("請選擇");
		char op = sc.next().charAt(0);
		switch (op) {
		case '1':
			t.getData();
			for (String str : t.set) {
				System.out.println(str.replaceAll(".0", ""));
			}
			break;
		case '2':
			AutoGame a = new AutoGame();
			a.start();
			break;
		default:
			System.out.println("輸入錯誤");
		}
	}
}

執行結果

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
以下使用者輸入表示式的執行結果
測試過程中在該情況下的測試資料是由自己給出的為1 1 12 12這四個數字
在這裡插入圖片描述
分數存入檔案
在這裡插入圖片描述

相關推薦

Java實現24遊戲

24點遊戲 程式設計要求: 24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則: 從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。 基本要求: 隨機生成4個代表撲克

java實現24遊戲

遊戲規則 從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。 基本要求 隨機生成4個代表撲克牌牌面的數字字母,程式自動列出所有可能算出24的表示式 列出表示式無

Java利用遞迴演算法實現24遊戲

24點遊戲 經典的紙牌益智遊戲,常見遊戲規則:         從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。         基本要求: 隨機生成4個代表撲克牌牌面

從鍵盤輸入4個0-13之間的正整數實現24遊戲並寫入檔案中

程式碼如下: include<stdio.h> include <stdlib.h> include <time.h> FILE * fp; void main() { void play(); //宣告函式 fp=fopen

Python+pyqt5實現24遊戲

描述:一副牌中A、J、Q、K可以當成是1、11、12、13。任意抽取4張牌,用加、減、乘、除(可加括號)把牌面上的數算成24。每張牌對應的數字必須用一次且只能用一次。在規定時間內輸入算式,輸入正確加十分,輸入錯誤生命值減一,點選確定提交併進入下一題,點選清空可清

24遊戲java實現

這是本人2年前業餘時間寫的application版本的24點遊戲的簡單實現。共享出來,希望能起到拋磚引玉的作用,一起探討24點的實現。 1、計算方式的改變——引入分數計算概念 求24點涉及到除法,所以必須轉變直接計算的思路。經過一段時間的摸索,本人發現可以採用分數計算。任何

24遊戲是經典的紙牌益智遊戲 java 程式 原始碼 測試結果

24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則: 從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。 基本要求: 隨機生成4個代表撲克牌牌面的數字字母,程式自動列

(Python)簡易24遊戲實現步驟

題目說明: 24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則:從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1), 隨機生成4個代表撲克牌牌面的數字字母,程式自動列出所有可能算出24的表示式。 解題思想:

24遊戲的回溯實現

這個程式實現了24點遊戲,但是最後的輸出有問題,好多重複的計算方法,比如,5+1+2和5+3就是兩個不同的答案 程式碼如下,#include <iostream> #include <string> #include <vector> #i

C#實現的算24遊戲的算法的代碼

number putc .text true gen als 算法 ack char s 下面資料是關於C#實現的算24點遊戲的算法的內容,希望能對碼農們有所用處。 using System; using System.Collections.Generic; using

C語言實現簡單24遊戲

     參考了很多網上的程式,簡單實現了基本功能 程式原始碼: //##賀雪 軟工1502班 1508010208 #include<stdio.h> #include<time.h> #include<stdlib.h> in

程式設計之美上24遊戲實現

#include<set> #include<stdio.h> using namespace std; set<int> f(int i); void game24(int Array[]); bool Check(set<int

24遊戲Java

題目:24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則: 從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。 基本要求: 隨機生成4個代表撲克牌牌面的數字字母,程式

java 撲克牌 24遊戲

要求:使用者初始生命值為一給定值(比如3),初始分數為0。隨機生成4個代表撲克牌牌面的數字或字母,由使用者輸入包含這4個數字或字母的運算表示式(可 1. 程式風格良好(使用自定義註釋模板)          2.使用計時器要求使用者在規定時間內輸入表示式,如果規定時間內運

python+pyqt5實現24遊戲

clas 抽取 結束 shu caption pytho cfa load http 本文實例為大家分享了python實現24點遊戲的具體代碼,供大家參考,具體內容如下 描述:一副牌中A、J、Q、K可以當成是1、11、12、13。任意抽取4張牌,用加、減、乘、除(可加括號

java 實現猜數字遊戲 隨機給定一個數字,猜大小直到正確

個數字 blog spa 猜數字 style ring imp code ont package com.swift; import java.util.Random; import java.util.Scanner; public class GuessBigSm

C語言實現24程序

項目 四則運算 return 輸出 存儲 數據 value class 教材 一、簡介 本程序的思想和算法來自於C語言教材後的實訓項目,程序通過用戶輸入四個整數計算出能夠通過加減乘除得到數字24的所有表達式,程序的設計有別於一般

[文件和原始碼分享] 基於JAVA實現的迷宮遊戲

程式開始執行時顯示一個迷宮地圖,迷宮中央有一隻老鼠,迷宮的右下方有一個糧倉。遊戲的任務是使用鍵盤上的方向鍵操縱老鼠在規定的時間內走到糧倉處。 老鼠形象可辨認,可用鍵盤操縱老鼠上下左右移動;迷宮的牆足夠結實,老鼠不能穿牆而過正確檢測結果,若老鼠在規定時間內走到糧倉處,提示成功,否則提示失敗;新增編輯迷宮功能,

24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則: 從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲

24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則: 從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。 基本要求: 隨機生成4個代表撲克牌牌面的數字字母,程式自動列

java實現kfc餐系統

1.基本需求 1.正常餐品結算和找零。 2.基本套餐結算和找零。 3.使用優惠劵購買餐品結算和找零。 4.可在一定時間段參與店內活動(自行設計或參考官網資訊)。 5.模擬列印小票的功能(寫到檔案中)。 6.html.jsp實現視覺化介面。 7.實現會員儲值卡功能