用Java實(shí)現(xiàn)24點(diǎn)游戲
一、常見(jiàn)游戲規(guī)則
從撲克中每次取出4張牌。使用加減乘除,第一個(gè)能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求編程解決24點(diǎn)游戲。
基本要求: 隨機(jī)生成4個(gè)代表?yè)淇伺婆泼娴臄?shù)字字母,程序自動(dòng)列出所有可能算出24的表達(dá)式,用擅長(zhǎng)的語(yǔ)言(C/C++/Java或其他均可)實(shí)現(xiàn)程序解決問(wèn)題。
1.程序風(fēng)格良好(使用自定義注釋模板)
2.列出表達(dá)式無(wú)重復(fù)。
提高要求:用戶初始生命值為一給定值(比如3),初始分?jǐn)?shù)為0。隨機(jī)生成4個(gè)代表?yè)淇伺婆泼娴臄?shù)字或字母,由用戶輸入包含這4個(gè)數(shù)字或字母的運(yùn)算表達(dá)式(可包含括號(hào)),如果表達(dá)式計(jì)算結(jié)果為24則代表用戶贏了此局。
1. 程序風(fēng)格良好(使用自定義注釋模板)
2.使用計(jì)時(shí)器要求用戶在規(guī)定時(shí)間內(nèi)輸入表達(dá)式,如果規(guī)定時(shí)間內(nèi)運(yùn)算正確則加分,超時(shí)或運(yùn)算錯(cuò)誤則進(jìn)入下一題并減少生命值(不扣分)。
3.所有成績(jī)均可記錄在TopList.txt文件中。
二、算法分析
用戶需要提前輸入4個(gè)數(shù),作為湊成24點(diǎn)的基數(shù),構(gòu)成arr數(shù)組,從而求解目標(biāo)數(shù)T=24。
在數(shù)arr中,首先取兩個(gè)數(shù)與操作符集合進(jìn)行組合,分別得到一組表達(dá)式,對(duì)于新得到的每個(gè)表達(dá)式,都可以和原集合中剩下的元素,組合成新的集合組,將每次得到的表達(dá)式,都用"()"包住,以保證計(jì)算先后順序。
對(duì)集合中所有元素進(jìn)行兩兩組合,并與剩余元素形成新的集合。由此,我們得到了一組元素為k-1個(gè)的集合組
對(duì)新集合組中的每一個(gè)集合,重復(fù)以上1-3步,可得到一組包含k-2個(gè)元素的集合組...以此類推,最后會(huì)得到一組集合,其中每個(gè)集合都只包含一個(gè)元素,這個(gè)就是我們合成的最終表達(dá)式.對(duì)第四步得到的表達(dá)式集合進(jìn)行求解,判斷其是否等于目標(biāo)數(shù)24,將符合條件的過(guò)濾出來(lái),即得到所有滿足條件的表達(dá)式。
三、概要設(shè)計(jì)
主函數(shù)程序流程圖
四、代碼
package Game; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Random; public class Compute { //定義隨機(jī)產(chǎn)生的四個(gè)數(shù) static int number[] = new int[4]; //轉(zhuǎn)換后的num1,num2,num3,num4 static int m[]=new int [4]; static String n[] = new String[4]; //用來(lái)判斷是否有解 static boolean flag = false; //存放操作符 static char[] operator = { '+', '-', '*', '/' }; private static Object key; public static void main(String[] args){ Random rand = new Random(); System.out.println("下列給出四個(gè)數(shù)字,使用+,-,*,/進(jìn)行計(jì)算使最后計(jì)算結(jié)果為24"); for(int i=0;i<4;i++){ number[i]=rand.nextInt(13)+1;//隨機(jī)生成四個(gè)int型數(shù) if(number[i]==1){ System.out.println("A");//如果隨機(jī)生成的數(shù)為1,則顯示為撲克牌牌面中的A } else if(number[i]==11){ System.out.println("J");//如果隨機(jī)生成的數(shù)為11,則顯示為撲克牌牌面中的J } else if(number[i]==12){ System.out.println("Q");//如果隨機(jī)生成的數(shù)為12,則顯示為撲克牌牌面中的Q } else if(number[i]==13){ System.out.println("K");//如果隨機(jī)生成的數(shù)為13,則顯示為撲克牌牌面中的K } else System.out.println(number[i]); } System.out.println("可能的結(jié)果有:"); calculate(); } //給定2個(gè)數(shù)和指定操作符的計(jì)算 public static int calcute(int count1, int count2, char operator) { if (operator == '+') { return count1 + count2; } else if (operator == '-') { return count1 - count2; } else if (operator == '*') { return count1 * count2; } else if ((operator == '/' )&& (count2 != 0) && (count1%count2==0)) { return count1 / count2; } else { return -1; } } //計(jì)算生成24的函數(shù) public static void calculate(){ Map<Integer, Integer> map = new HashMap<Integer, Integer>(); //存放數(shù)字,用來(lái)判斷輸入的4個(gè)數(shù)字中有幾個(gè)重復(fù)的,和重復(fù)的情況 for (int i = 0; i < number.length; i++) { if(map.get(number[i]) == null){ map.put(number[i], 1); } else { map.put(number[i], map.get(number[i]) + 1); } } if(map.size() == 1){ //如果只有一種數(shù)字,此時(shí)只有一種排列組合,如5,5,5,5 calculation(number[0], number[1],number[2],number[3]); } else if(map.size()==2){ //如果只有2種數(shù)字,有2種情況,如1,1,2,2和1,1,1,2 int index = 0;//用于數(shù)據(jù)處理 int state = 0;//判斷是哪種情況 for (Integer key : map.keySet()) { if(map.get(key) == 1){ //如果是有1個(gè)數(shù)字和其他3個(gè)都不同,將number變?yōu)?number[0]=number[1]=number[2], //將不同的那個(gè)放到number[3],方便計(jì)算 number[3] = key; state = 1; } else if(map.get(key)==2){ //如果是兩兩相同的情況,將number變?yōu)閚umber[0]=number[1],number[2]=number[3]的情況 number[index++]=key; number[index++]=key; } else{ number[index++]=key; } } //列出2種情況的所有排列組合,并分別計(jì)算 if(state == 1){ calculation(number[3],number[1],number[1],number[1]); calculation(number[1],number[3],number[1],number[1]); calculation(number[1],number[1],number[3],number[1]); calculation(number[1],number[1],number[1],number[3]); } if(state==0){ calculation(number[1],number[1],number[3],number[3]); calculation(number[1],number[3],number[1],number[3]); calculation(number[1],number[3],number[3],number[1]); calculation(number[3],number[3],number[1],number[1]); calculation(number[3],number[1],number[3],number[1]); calculation(number[3],number[1],number[1],number[3]); } } else if(map.size()==3){ //有3種數(shù)字的情況 int index = 0; for (Integer key : map.keySet()) { if(map.get(key) == 2){ //將相同的2個(gè)數(shù)字放到number[2]=number[3] number[2] = key; number[3] = key; } else { number[index++] = key; } } //排列組合,所有情況 calculation(number[0],number[1],number[3],number[3]); calculation(number[0],number[3],number[1],number[3]); calculation(number[0],number[3],number[3],number[1]); calculation(number[1],number[0],number[3],number[3]); calculation(number[1],number[3],number[0],number[3]); calculation(number[1],number[3],number[3],number[0]); calculation(number[3],number[3],number[0],number[1]); calculation(number[3],number[3],number[1],number[0]); calculation(number[3],number[1],number[3],number[0]); calculation(number[3],number[0],number[3],number[1]); calculation(number[3],number[0],number[1],number[3]); calculation(number[3],number[1],number[0],number[3]); } else if(map.size() == 4){ //4個(gè)數(shù)都不同的情況 calculation(number[0],number[1],number[2],number[3]); calculation(number[0],number[1],number[3],number[2]); calculation(number[0],number[2],number[1],number[3]); calculation(number[0],number[2],number[3],number[1]); calculation(number[0],number[3],number[1],number[2]); calculation(number[0],number[3],number[2],number[1]); calculation(number[1],number[0],number[2],number[3]); calculation(number[1],number[0],number[3],number[2]); calculation(number[1],number[2],number[3],number[0]); calculation(number[1],number[2],number[0],number[3]); calculation(number[1],number[3],number[0],number[2]); calculation(number[1],number[3],number[2],number[0]); calculation(number[2],number[0],number[1],number[3]); calculation(number[2],number[0],number[3],number[1]); calculation(number[2],number[1],number[0],number[3]); calculation(number[2],number[1],number[3],number[0]); calculation(number[2],number[3],number[0],number[1]); calculation(number[2],number[3],number[1],number[0]); calculation(number[3],number[0],number[1],number[2]); calculation(number[3],number[0],number[2],number[1]); calculation(number[3],number[1],number[0],number[2]); calculation(number[3],number[1],number[2],number[0]); calculation(number[3],number[2],number[0],number[1]); calculation(number[3],number[2],number[1],number[0]); } if(flag==false) System.out.println("這四張牌面數(shù)字無(wú)法經(jīng)過(guò)運(yùn)算得到24!"); } public static void calculation(int num1, int num2, int num3, int num4){ for (int i = 0; i < 4; i++){ //第1次計(jì)算,先從四個(gè)數(shù)中任意選擇兩個(gè)進(jìn)行計(jì)算 char operator1 = operator[i]; int firstResult = calcute(num1, num2, operator1);//先選第一,和第二個(gè)數(shù)進(jìn)行計(jì)算 int midResult = calcute(num2, num3, operator1);//先選第二和第三兩個(gè)數(shù)進(jìn)行計(jì)算 int tailResult = calcute(num3,num4, operator1);//先選第三和第四倆個(gè)數(shù)進(jìn)行計(jì)算 for (int j = 0; j < 4; j++){ //第2次計(jì)算,從上次計(jì)算的結(jié)果繼續(xù)執(zhí)行,這次從三個(gè)數(shù)中選擇兩個(gè)進(jìn)行計(jì)算 char operator2 = operator[j]; int firstMidResult = calcute(firstResult, num3, operator2); int firstTailResult = calcute(num3,num4,operator2); int midFirstResult = calcute(num1, midResult, operator2); int midTailResult= calcute(midResult,num4,operator2); int tailMidResult = calcute(num2, tailResult, operator2); for (int k = 0; k < 4; k++){ //第3次計(jì)算,也是最后1次計(jì)算,計(jì)算兩個(gè)數(shù)的結(jié)果,如果是24則輸出表達(dá)式 char operator3 = operator[k]; //在以上的計(jì)算中num1,num2,num3,num4都是整型數(shù)值,但若要輸出為帶有A,J,Q,K的表達(dá)式,則要將這四個(gè)數(shù)都變?yōu)镾tring類型,下同 if(calcute(firstMidResult, num4, operator3) == 24){ m[0]=num1; m[1]=num2; m[2]=num3; m[3]=num4; for(int p=0;p<4;p++){ if(m[p]==1){ n[p]="A";} if(m[p]==2){ n[p]="2";} if(m[p]==3){ n[p]="3";} if(m[p]==4){ n[p]="4";} if(m[p]==5){ n[p]="5";} if(m[p]==6){ n[p]="6";} if(m[p]==7){ n[p]="7";} if(m[p]==8){ n[p]="8";} if(m[p]==9){ n[p]="9";} if(m[p]==10){ n[p]="10";} if(m[p]==11){ n[p]="J";} if(m[p]==12){ n[p]="Q";} if(m[p]==13){ n[p]="k";} } System.out.println("((" + n[0] + operator1 + n[1] + ")" + operator2 + n[2] + ")" + operator3 + n[3]); flag = true;//若有表達(dá)式輸出,則將說(shuō)明有解,下同 } if(calcute(firstResult, firstTailResult, operator3) == 24){ System.out.println("(" + n[0] + operator1 + n[1] + ")" + operator3 + "(" + n[2] + operator2 + n[3] + ")"); flag = true; } if(calcute(midFirstResult, num4, operator3) == 24){ m[0]=num1; m[1]=num2; m[2]=num3; m[3]=num4; for(int p=0;p<4;p++){ if(m[p]==1){ n[p]="A";} if(m[p]==2){ n[p]="2";} if(m[p]==3){ n[p]="3";} if(m[p]==4){ n[p]="4";} if(m[p]==5){ n[p]="5";} if(m[p]==6){ n[p]="6";} if(m[p]==7){ n[p]="7";} if(m[p]==8){ n[p]="8";} if(m[p]==9){ n[p]="9";} if(m[p]==10){ n[p]="10";} if(m[p]==11){ n[p]="J";} if(m[p]==12){ n[p]="Q";} if(m[p]==13){ n[p]="k";} } System.out.println("(" + n[0] + operator2 + "(" + n[1] + operator1 + n[2] + "))" + operator3 + n[3]); flag = true; } if(calcute(num1,midTailResult, operator3) == 24){ m[0]=num1; m[1]=num2; m[2]=num3; m[3]=num4; for(int p=0;p<4;p++){ if(m[p]==1){ n[p]="A";} if(m[p]==2){ n[p]="2";} if(m[p]==3){ n[p]="3";} if(m[p]==4){ n[p]="4";} if(m[p]==5){ n[p]="5";} if(m[p]==6){ n[p]="6";} if(m[p]==7){ n[p]="7";} if(m[p]==8){ n[p]="8";} if(m[p]==9){ n[p]="9";} if(m[p]==10){ n[p]="10";} if(m[p]==11){ n[p]="J";} if(m[p]==12){ n[p]="Q";} if(m[p]==13){ n[p]="k";} } System.out.println(" " + n[0] + operator3 + "((" + n[1] + operator1 + n[2] + ")" + operator2 + n[3] + ")"); flag = true; } if(calcute(num1,tailMidResult,operator3) == 24){ m[0]=num1; m[1]=num2; m[2]=num3; m[3]=num4; for(int p=0;p<4;p++){ if(m[p]==1){ n[p]="A";} if(m[p]==2){ n[p]="2";} if(m[p]==3){ n[p]="3";} if(m[p]==4){ n[p]="4";} if(m[p]==5){ n[p]="5";} if(m[p]==6){ n[p]="6";} if(m[p]==7){ n[p]="7";} if(m[p]==8){ n[p]="8";} if(m[p]==9){ n[p]="9";} if(m[p]==10){ n[p]="10";} if(m[p]==11){ n[p]="J";} if(m[p]==12){ n[p]="Q";} if(m[p]==13){ n[p]="k";} } System.out.println(" " + n[0] + operator3 + "(" + n[1] + operator2 + "(" + n[2] + operator1 + n[3] + "))"); flag = true; } } } } } }
五、測(cè)試
測(cè)試用例:2 8 10 4
測(cè)試結(jié)果:
可以看到,程序成功的生成了對(duì)應(yīng)測(cè)試用例的結(jié)果,結(jié)果是正確的。
測(cè)試無(wú)法組成24點(diǎn)的數(shù)據(jù):7 13 1 6
經(jīng)過(guò)多次運(yùn)行, 7,13,1,6這四個(gè)數(shù)據(jù),無(wú)法組成24點(diǎn),程序輸出No answer運(yùn)行正確。
到此這篇關(guān)于用Java實(shí)現(xiàn)24點(diǎn)游戲的文章就介紹到這了,更多相關(guān)Java24點(diǎn)游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java實(shí)現(xiàn)哈希表的基本功能
- Java實(shí)現(xiàn)FTP文件上傳
- 教你用Java實(shí)現(xiàn)RSA非對(duì)稱加密算法
- java實(shí)現(xiàn)樹(shù)形菜單對(duì)象
- Java實(shí)現(xiàn)多線程中的靜態(tài)代理模式
- 我用java實(shí)現(xiàn)了王者榮耀的皮膚和英雄技能
- java實(shí)現(xiàn)Linux(centos) 中docker容器下命令交互的代碼(配置向?qū)В?/a>
- java實(shí)現(xiàn)表單必填參數(shù)驗(yàn)證的方法
- Java實(shí)現(xiàn)NIO聊天室的示例代碼(群聊+私聊)
- Java實(shí)現(xiàn)簡(jiǎn)單的掃雷圖
- 圖文詳解JAVA實(shí)現(xiàn)快速排序
- 教你怎么使用Java實(shí)現(xiàn)WebSocket
- Java實(shí)現(xiàn)雪花算法的原理
- 教你怎么用Java實(shí)現(xiàn)給圖片打上水印
- 教你怎么用java實(shí)現(xiàn)客戶端與服務(wù)器一問(wèn)一答
- Java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)IO版本
- Java實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
- Java數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)跳表
相關(guān)文章
Spring+SpringMVC配置事務(wù)管理無(wú)效原因及解決辦法詳解
這篇文章主要介紹了Spring+SpringMVC配置事務(wù)管理無(wú)效原因及解決辦法詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下2017-12-12java調(diào)用Oracle存儲(chǔ)過(guò)程的方法實(shí)例
這篇文章介紹了java調(diào)用Oracle存儲(chǔ)過(guò)程的方法實(shí)例,有需要的朋友可以參考一下2013-09-09spring/springboot整合curator遇到的坑及解決
這篇文章主要介紹了spring/springboot整合curator遇到的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05java+vue實(shí)現(xiàn)添加單選題、多選題到題庫(kù)功能
這篇文章主要為大家詳細(xì)介紹了java+vue實(shí)現(xiàn)添加單選題、多選題到題庫(kù)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04springboot+vue2+elementui實(shí)現(xiàn)時(shí)間段查詢方法
這篇文章主要介紹了springboot+vue2+elementui實(shí)現(xiàn)時(shí)間段查詢方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-05-05一次Spring無(wú)法啟動(dòng)的問(wèn)題排查實(shí)戰(zhàn)之字節(jié)碼篇
最近學(xué)習(xí)了spring相關(guān)知識(shí),公司項(xiàng)目也用到了spring,下面這篇文章主要給大家介紹了一次Spring無(wú)法啟動(dòng)的問(wèn)題排查實(shí)戰(zhàn)之字節(jié)碼篇的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04