Java利用遞迴演算法實現24點遊戲
24點遊戲
經典的紙牌益智遊戲,常見遊戲規則:
從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。
基本要求: 隨機生成4個代表撲克牌牌面的數字字母,程式自動列出所有可能算出24的表示式,用擅長的語言(C/C++/Java或其他均可)實現程式解決問題。
1.程式風格良好(使用自定義註釋模板)
2.列出表示式無重複。
提高要求:使用者初始生命值為一給定值(比如3),初始分數為0。隨機生成4個代表撲克牌牌面的數字或字母,由使用者輸入包含這4個數字或字母的運算表示式(可包含括號),如果表示式計算結果為24則代表使用者贏了此局。
1. 程式風格良好(使用自定義註釋模板)
2.使用計時器要求使用者在規定時間內輸入表示式,如果規定時間內運算正確則加分,超時或運算錯誤則進入下一題並減少生命值(不扣分)。
3.所有成績均可記錄在TopList.txt檔案中。
一. 演算法思路
輸入四個數n1,n2,n3,n4,求解目標數T=24,以及一組計算操作符"+" "-" "*" "/" ,求所有由該組數字及操作符組成的多項式表示式集合,其值等於目標數T ,即T = 24。 演算法思路如下: 1.在集合{n1,n2,n3,n4}中,首先取兩個數字,如n1,n2,與操作符集合進行組合,分別得到一組表示式:n1*n2,n1+n2,n1-n2,n1/n2,n2-n1,n2/n1.(其中由於"-"和"/"操作符,左右互換會導致計算結果不同,所以
package TwentyfourGame;
import java.util.ArrayList;
import java.util.Scanner;
public class TfGame {
public static void main(String[] args) {
//輸入提示
System.out.println("—————————歡迎進入24點遊戲———————————");
System.out.println("請隨機輸入四個1-13之間的整數(以空格隔開):");
ArrayList<Integer> list = inputNum(); //呼叫輸入函式
tfCal(list, new ArrayList<String>()); //計算24點方法, 實參list為輸入的資料, new ArrayList<String>()用來 表示計算過程
System.out.println("——————————————end———————————————");
}
//輸入方法,將輸入的四個數存入陣列佇列list中,並返回
private static ArrayList<Integer> inputNum() {
ArrayList<Integer> alist = new ArrayList<Integer>(); //ArrayList<Integer>表示只能接收整型資料
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 4; i++) { //將四個數新增到陣列佇列中
alist.add(scanner.nextInt());
}
return alist; //返回值為陣列佇列中的四個數
}
//計算24點遊戲的方法
public static boolean tfCal(ArrayList<Integer> list, ArrayList<String> str) {
int length = list.size();
if (length > 1) {
/**利用雙重迴圈取出兩個數的計算所有情況
* 若list的長度為4,那麼第一個數的下標和第二個數的下標分別為
* 0 1
* 1 2
* 2 3
*/
for (int i = 0; i < length - 1; i++) {
for (int j = i + 1; j < length; j++) {
//加法運算
int b = list.remove(j); //移除list中的下標為j的元素,並將此數賦值給b
int a = list.remove(i); //同上,將值賦給a
list.add(0, a + b); //將兩數的計算結果新增到原佇列
str.add(a + "+" + b + "=" + (a + b));//此處是儲存計算的過程
tfCal(list, str); //遞迴調動
//下面四句話是為了還原list佇列,特別強調進棧和出棧的順序
list.remove(0);
list.add(i, a);
list.add(j, b);
str.remove(str.size() - 1);
//減運算(a-b),原理與上面加法計算相同
b = list.remove(j);
a = list.remove(i);
list.add(0, a - b);
str.add(a + "-" + b + "=" + (a - b));
tfCal(list, str);
list.remove(0);
list.add(i, a);
list.add(j, b);
str.remove(str.size() - 1);
//減運算(b-a)
b = list.remove(j);
a = list.remove(i);
list.add(0, b - a);
str.add(b + "-" + a + "=" + (b - a));
tfCal(list, str);
list.remove(0);
list.add(i, a);
list.add(j, b);
str.remove(str.size() - 1);
//乘運算
b = list.remove(j);
a = list.remove(i);
list.add(0, a * b);
str.add(a + "*" + b + "=" + (a * b));
tfCal(list, str);
list.remove(0);
list.add(i, a);
list.add(j, b);
str.remove(str.size() - 1);
//除運算(a/b)
b = list.remove(j);
a = list.remove(i);
if (b != 0 && a % b == 0) {
list.add(0, a / b);
str.add(a + "/" + b + "=" + (a / b));
tfCal(list, str);
list.remove(0);
list.add(i, a);
list.add(j, b);
str.remove(str.size() - 1);
} else {
list.add(i, a);
list.add(j, b);
}
//除運算(b/a)
b = list.remove(j);
a = list.remove(i);
if (a != 0 && b % a == 0) {
list.add(0, b / a);
str.add(b + "/" + a + "=" + (b / a));
tfCal(list, str);
list.remove(0);
list.add(i, a);
list.add(j, b);
str.remove(str.size() - 1);
} else {
list.add(i, a);
list.add(j, b);
}
}
}
} else {
if (str.get(str.size() - 1).endsWith("=24")) { //endsWith()方法用於測試字串是否以指定字尾結束
for (String temp : str) {
System.out.print(temp + " ");
}
System.out.println();
}
}
}
}
二.執行結果
三.學習心得
自己的演算法學習有待提高,需要不斷鍛鍊邏輯思維能力。