游戲規(guī)則
創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設、高性價比慈利網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式慈利網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設找我們,業(yè)務覆蓋慈利地區(qū)。費用合理售后完善,10年實體公司更值得信賴。
從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求編程解決24點游戲。
基本要求
解表達式基本思路
采用窮舉法列舉每一種存在的可能,接著判斷是否值為24,如果等于24,則將表達式存入Set集合,最終遍歷Set集合即可得到所有表達式。具體思路如下:
1.采用隨機數(shù)生成4個符合要求的數(shù)據(jù),假設四個數(shù)據(jù)為n1,n2,n3,n4 。
2.把數(shù)據(jù)相互組合可以得到如下組合: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.把上面組合計算出來的結(jié)果存入進對應的數(shù)組中例如:組合相加的結(jié)果存入add數(shù)組,相減的結(jié)果存入sub數(shù)組……最終將這些數(shù)組存入一個list集合中,目的是為了方便通過循環(huán)遍歷出每一種組合。
5.通過循環(huán)去遍歷每一種組合,把這些組合在一起進行相加,相減等運算,記錄結(jié)果為24的表達式。在這里需要注意的是,因為數(shù)組得值為兩個數(shù)字的運算結(jié)果,所以需要根據(jù)當前循環(huán)變量的值和list集合以及數(shù)組存入數(shù)據(jù)的順序去把表達式格式化成四個數(shù)字組成的表達式,否則表達式只有兩個數(shù)字。

玩家運算基本思路
在java中使用Timer和Canender即可實現(xiàn)定時的功能,而判斷表達式是否正確,在java中使用Script引擎調(diào)用eval方法即可判斷表達式的值是否正確,具體思路如下:
1.初始化生命值,和分數(shù)
2.由系統(tǒng)給出四個數(shù)字
3.玩家給出答案
4.判斷給出的答案中的數(shù)字和系統(tǒng)給出的數(shù)字是否吻合,如果吻合進入5,否則,生命值減一。
5.借助Timer類的schedule()判斷是否超時,如果沒有超時,進入6,否則,生命值減一。
6.借助script引擎的eval()方法可以判斷表達式是否正確,如果正確,分數(shù)加一,否則,生命值減一。
當生命值大于0時執(zhí)行2,3,4,5,6操做,否則將當前分數(shù)寫入文件。
流程圖如下圖所示

編碼
Game類,主要實現(xiàn)由系統(tǒng)隨機生成數(shù)據(jù),并計算可能的表達式
為了避免除零異常采用了float類型的數(shù)組進行存儲
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. 采用隨機數(shù)生成4個符合要求的數(shù)據(jù),假設四個數(shù)據(jù)為n1,n2,n3,n4 。
* 2.把數(shù)據(jù)相互組合可以得到如下組合:n1和n2 ,n1和n3,n1和n4,n2和n3,n2和n4。
* 3.將上面的組合進行各種可能的運算例如:n1+n2,n1-n2,n2-n1,n1*n2,n1/n2,n2/n1等等。
* 4.把上面組合計算出來的結(jié)果存入進對應的數(shù)組中例如:組合相加的結(jié)果存入add數(shù)組,相減的結(jié)果存入sub數(shù)組……最終將這些數(shù)組存入一個list集合中,目的是為了方便通過循環(huán)遍歷出每一種組合。
* 5.通過循環(huán)去遍歷每一種組合,把這些組合在一起進行相加,相減等運算,記錄結(jié)果為24的表達式
* @author jianglei
*/
public class Game {
static Set<String> set = new HashSet<String>();// 使用Set存儲算式表達式可以避免有重復的結(jié)果
float[] data = new float[4];// 存放數(shù)據(jù)的集合
float[] add = new float[6];// 存放組合相加的結(jié)果的集合
float[] sub1 = new float[6];// 存放相減的結(jié)果(兩個數(shù)相減的結(jié)果存在兩種可能)
float[] sub2 = new float[6];// 存放相減的結(jié)果
float[] mul = new float[6];// 存放相乘
float[] div1 = new float[6];// 存放相除(兩個數(shù)相除的結(jié)果存在兩種可能)
float[] div2 = new float[6];// 存放相除
List<float[]> list = new ArrayList<float[]>();// 存放組合結(jié)果運算的集合
/**
*
* Title: combine
* </p>
* Description: 該方法用來獲取每兩個數(shù)字的組合組合, 用1代表第一個數(shù)字,2代表第二個數(shù)字....共有六種組合方式,分別如下:
* 1和2,1和3,1和 4,2和 3,2和 4,3和 4 在上面的組合中,每一種組合都對應著 加減乘除 這四種運算
* 將上述的組合的每種計算結(jié)果存入上面聲明的集合
*/
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集合中,方便通過循環(huán)來遍歷每一種組合方式
list.add(sub1);
list.add(sub2);
list.add(mul);
list.add(div1);
list.add(div2);
}
public void getData() {
Random r = new Random();
// 獲取1——13的的數(shù)字的集合
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("四個數(shù)字為:");
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++) {// 判斷每一種組合的每一種運算結(jié)果是否等于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類主要實現(xiàn)由系統(tǒng)給定數(shù)值,用戶輸入表達式來根據(jù)結(jié)過進行計分,并將分數(shù)寫入文件
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;//初始化分數(shù)
/**
*開始游戲的方法,該方法通過當前生命值判斷是否結(jié)束
*/
public void start() throws IOException {
Calendar date = Calendar.getInstance();//實例化Calendar對象
while(life>0) {//當生命值大于0才會進行
flag=true;//初始化分數(shù)標記
date.setTime(new Date());
date.add(Calendar.SECOND, 20);//設置限定時間
Timer timer = new Timer();
//當達到限定時間將會執(zhí)行run()方法,即把全局變量flag變?yōu)閒alse
timer.schedule(new RemindTask(), date.getTime());
int answer = answer();
switch(answer) {
case -1:
System.out.println("表達式錯誤!! 當前生命值為"+life+" 分數(shù)為:"+score);
break;
case -2:
System.out.println("輸入超時!! 當前生命值為"+life+" 分數(shù)為:"+score);
break;
case -3:
System.out.println("結(jié)果錯誤!! 當前生命值為"+life+" 分數(shù)為:"+score);
break;
case 1:
System.out.println("正確,得到1分獎勵!! 當前生命值為"+life+" 分數(shù)為:"+score);
break;
}
System.out.println("----------");
}
System.out.println("游戲結(jié)束……分數(shù)為: "+score);//循環(huán)結(jié)束也就是生命值為0,打印游戲結(jié)束
saveScore(score);//將玩家當前分數(shù)存入文件
return;
}
/**
*
* Title: getData</p>
* Description:給定任意的數(shù)據(jù)
* @return
*/
private float[] getData() {
float[] data = new float[4];
Random r = new Random();//隨機生成四個數(shù)據(jù)存入數(shù)組中
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("四個數(shù)字為:");
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:根據(jù)用戶輸入返回false或true
* 1.輸入不含給定值,返回FALSE
* 2.輸入超時,返回false
* 3.輸入表達式的值不為24,返回false
* 否則,返回true
* @return -1代表輸入的表達式與系統(tǒng)給出的數(shù)字不吻合
* @return -2代表用戶計算結(jié)果超時
* @return -3代表結(jié)果錯誤
* @return 1代表用戶計算正確
*/
public int answer() {
Scanner sc = new Scanner(System.in);
float[] data = getData();//獲取給定的數(shù)據(jù)
//獲取script引擎,調(diào)用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++;//分數(shù)加一
return 1;
}
life--;
} catch (ScriptException e) {
System.out.println("表達式輸入不合法");
}
return -3;
}
/**
* Title: saveScore</p>
* Description: 該方法表示將玩家當前分數(shù)存入TopList.txt文件
* @param score 需要存入的分數(shù)
* @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());//把分數(shù)寫入文件
bos.close();
}
public static void main(String[] args) throws IOException {
saveScore(1);
}
}
/**
*
* Title: RemindTask
* Description:該TimerTask并且重寫run()可以實現(xiàn)在指定的定時時間執(zhí)行run方法的內(nèi)容
* @author jianglei
*/
class RemindTask extends TimerTask {
@Override
public void run() {
AutoGame.flag = false;//當超時會把全局變量flag變?yōu)閒alse
}
}DataFormat類根據(jù)a b c是三個循環(huán)變量將兩個組合數(shù)字的運算格式化成四個數(shù)字的表達式
由于代碼比較長,在這里只留一種情況的,其余的情況與它類似
import java.util.Set;
/**
*
* Title: GetFoamat
* Description: 該類通過在循環(huán)中的a b c的值判斷出當前所參與運算的值與參加運算的符號,假設四個值為n0,n1,n2,n3
* 形參 a、b、c為循環(huán)變量,形參n數(shù)組為參與運算的四個數(shù)字,形參op表示當前進行的運算類型,形參set為存儲結(jié)果的容器
*/
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.隨機生成數(shù)判斷");
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("輸入錯誤");
}
}
}運行結(jié)果



以下用戶輸入表達式的運行結(jié)果
測試過程中在該情況下的測試數(shù)據(jù)是由自己給出的為1 1 12 12這四個數(shù)字

分數(shù)存入文件

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
當前名稱:java實現(xiàn)24點游戲
網(wǎng)站URL:http://chinadenli.net/article46/iidghg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、定制開發(fā)、服務器托管、、標簽優(yōu)化、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)