Java實現(xiàn)24點小游戲
本文實例為大家分享了Java實現(xiàn)24點小游戲的具體代碼,供大家參考,具體內(nèi)容如下
程序設(shè)計要求:
24點游戲是經(jīng)典的紙牌益智游戲。
常見游戲規(guī)則:
從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求編程解決24點游戲。
基本要求: 隨機生成4個代表撲克牌牌面的數(shù)字字母,程序自動列出所有可能算出24的表達式,用擅長的語言(C/C++/Java或其他均可)實現(xiàn)程序解決問題。
1.程序風格良好(使用自定義注釋模板)
2.列出表達式無重復(fù)。
算法設(shè)計思路:
算法采用了窮舉的方法,對所有數(shù)字和操作符進行組合,從而找到所有的情況。
剛開始將四個數(shù)進行分組排序。
算法中我采用了將四個數(shù)分為1種的,兩種的(在兩種中又分為兩種數(shù)的個數(shù)分別為1和3的,個數(shù)分別為2和2的),三種的和四種的,將所有情況排序排了出來。
每次只運算2個數(shù),然后將結(jié)果拿去進行下一次運算。剛開始有4個數(shù),拿出兩個數(shù)進行第一次運算,運算后得出三個數(shù),然后在這三個數(shù)中再拿出兩個進行第二次運算,運算后就有兩個數(shù)了,第三次運算就是將這兩個數(shù)進行計算,得出最后值,判斷最后這個值是否為24,若為24,則輸出表達式,若不是,則輸出提示消息。
現(xiàn)在在這4個數(shù)確定位置的情況下,再來改變操作符,即每次2個數(shù)進行運算的時候,有4種情況。在下一次計算的時候同樣有4種情況,最后一次計算(第3次)同理。這樣就找到了所有解的情況。
算法流程圖為:

下面是代碼:
package Game;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class Compute {
//定義隨機產(chǎn)生的四個數(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];
//用來判斷是否有解
static boolean flag = false;
//存放操作符
static char[] operator = { '+', '-', '*', '/' };
private static Object key;
public static void main(String[] args){
Random rand = new Random();
System.out.println("下列給出四個數(shù)字,使用+,-,*,/進行計算使最后計算結(jié)果為24");
for(int i=0;i<4;i++){
number[i]=rand.nextInt(13)+1;//隨機生成四個int型數(shù)
if(number[i]==1){
System.out.println("A");//如果隨機生成的數(shù)為1,則顯示為撲克牌牌面中的A
}
else if(number[i]==11){
System.out.println("J");//如果隨機生成的數(shù)為11,則顯示為撲克牌牌面中的J
}
else if(number[i]==12){
System.out.println("Q");//如果隨機生成的數(shù)為12,則顯示為撲克牌牌面中的Q
}
else if(number[i]==13){
System.out.println("K");//如果隨機生成的數(shù)為13,則顯示為撲克牌牌面中的K
}
else
System.out.println(number[i]);
}
System.out.println("可能的結(jié)果有:");
calculate();
}
//給定2個數(shù)和指定操作符的計算
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;
}
}
//計算生成24的函數(shù)
public static void calculate(){
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
//存放數(shù)字,用來判斷輸入的4個數(shù)字中有幾個重復(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ù)字,此時只有一種排列組合,如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個數(shù)字和其他3個都不同,將number變?yōu)?number[0]=number[1]=number[2],
//將不同的那個放到number[3],方便計算
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種情況的所有排列組合,并分別計算
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個數(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個數(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ù)字無法經(jīng)過運算得到24!");
}
public static void calculation(int num1, int num2, int num3, int num4){
for (int i = 0; i < 4; i++){
//第1次計算,先從四個數(shù)中任意選擇兩個進行計算
char operator1 = operator[i];
int firstResult = calcute(num1, num2, operator1);//先選第一,和第二個數(shù)進行計算
int midResult = calcute(num2, num3, operator1);//先選第二和第三兩個數(shù)進行計算
int tailResult = calcute(num3,num4, operator1);//先選第三和第四倆個數(shù)進行計算
for (int j = 0; j < 4; j++){
//第2次計算,從上次計算的結(jié)果繼續(xù)執(zhí)行,這次從三個數(shù)中選擇兩個進行計算
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次計算,也是最后1次計算,計算兩個數(shù)的結(jié)果,如果是24則輸出表達式
char operator3 = operator[k];
//在以上的計算中num1,num2,num3,num4都是整型數(shù)值,但若要輸出為帶有A,J,Q,K的表達式,則要將這四個數(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;//若有表達式輸出,則將說明有解,下同
}
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;
}
}
}
}
}
}
運行及測試截圖:


以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot之redis cache TTL選項的使用
這篇文章主要介紹了springboot之redis cache TTL選項的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
idea中打開項目時import project和open區(qū)別詳解
本文主要介紹了idea中打開項目時import project和open區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2023-06-06
windows系統(tǒng)使用mvn命令打包并指定jdk路徑方式
這篇文章主要介紹了windows系統(tǒng)使用mvn命令打包并指定jdk路徑方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
SpringBoot-RestTemplate如何實現(xiàn)調(diào)用第三方API
這篇文章主要介紹了SpringBoot-RestTemplate實現(xiàn)調(diào)用第三方API的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
Java實現(xiàn)字符串轉(zhuǎn)換成可執(zhí)行代碼的方法
今天小編就為大家分享一篇Java實現(xiàn)字符串轉(zhuǎn)換成可執(zhí)行代碼的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
詳解mybatis多對一關(guān)聯(lián)查詢的方式
這篇文章主要給大家介紹了關(guān)于mybatis多對一關(guān)聯(lián)查詢的相關(guān)資料,文中將關(guān)聯(lián)方式以及配置方式介紹的很詳細,需要的朋友可以參考下2021-06-06
SpringBoot2 整合Ehcache組件,輕量級緩存管理的原理解析
這篇文章主要介紹了SpringBoot2 整合Ehcache組件,輕量級緩存管理,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
springboot整合日志處理Logback的實現(xiàn)示例
Logback是由log4j創(chuàng)始人設(shè)計的又一個開源日志組件,本文主要介紹了springboot整合日志處理Logback,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2024-01-01

