[Java]猜數字遊戲文字版

Menu_Method.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * 猜數字文字版!GuessNumber
 * 這是文字版的猜數字遊戲,有分以下幾種玩法模式。
 * 1.電腦出題使用者猜
 * 2.使用者出題電腦猜
 * 3.電腦互猜(教學及測試用)
 * 4.電腦助猜
 * 5.人機大戰
 */
package guessNumberPackage; //猜數字套件
 
import java.util.Scanner; //讀取工具
 
/**
 * 含有程式進入點main()的主要類別(Main Class)
 * @see StringClass
 * @author 幻嵐
 */
public class GuessNumber {
 
    /**
     * 程式進入點
     * @param args 若有輸入一筆字串資料就直接拿來作為使用者名稱
     * @see Menu_Method
     */
    public static void main(String[] args) {
	welcomeMessage();  //顯示歡迎訊息
 
	/*
	 * 判斷是否有輸入args,若有則跳過讓使用者輸入名稱的步驟,直接作為使用者名稱
	 */
	if (args.length == 1) { //若args有一筆資料
	    StringClass.userName = args[0];
	} else {
	    setUserName();
	}
	System.out.printf(StringClass.SHOW_USER_WELCOME, StringClass.userName);
 
	/*
	 * 顯示清單。程式進入點結束任務了
	 */
	Menu.show();
    }
 
    /**
     * 設定使用者名稱。(若args沒有輸入則不會被執行)
     */
    private static void setUserName() {
	Scanner sc = new Scanner(System.in);
 
	System.out.print(StringClass.SHOW_TYPE_USER_NAME);
	String userName = sc.nextLine();
	while (userName.equals("") || userName.charAt(0) == ' ') { //如果沒有輸入
	    System.out.print(StringClass.SHOW_TYPE_USER_NAME_ERROR);
	    userName = sc.nextLine();
	}
	StringClass.userName = userName;
    }
 
    /**
     * 顯示歡迎訊息
     */
    private static void welcomeMessage() {
	System.out.print(StringClass.SHOW_WELCOME);
    }
}

Player.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
* 存放字串的類別(方便之後修改)
*/
package guessNumberPackage;
 
/**
* 字串常數集
* @author 幻嵐
*/
public class StringClass {
 
/**
* 儲存玩家名稱(此類別唯一的變數)
*/
public static String userName = "玩家"; //變數
/**
* 提示輸入使用者名稱
*/
public static final String SHOW_TYPE_USER_NAME = "請先輸入您的大名:";
/**
* 提示輸入的使用者名稱有誤
*/
public static final String SHOW_TYPE_USER_NAME_ERROR = "未輸入大名,請重新輸入:";
/**
* 歡迎玩猜數字遊戲的訊息
*/
public static final String SHOW_WELCOME = "nt歡迎來玩猜數字遊戲nn";
/**
* 歡迎使用者的訊息
*/
public static final String SHOW_USER_WELCOME = "%s 您好!n"; //printf
/**
* 主選單的頂端
*/
public static final String SHOW_MENU_TOP = "********************主選單********************n";
/**
* 主選單項目的顯示格式
*/
public static final String SHOW_MENU_TYPE = "t%d.%sn"; //printf
/**
* 主選單中的項目
*/
public static final String SHOW_MENU_ITEMS[] = {"由電腦出題讓使用者猜", "由使用者出題讓電腦猜", "電腦互猜(教學及測試用)", "電腦助猜", "人機大戰", "猜數字玩法說明", "離開選單"};
/**
* 主選單的底端
*/
public static final String SHOW_MENU_END = "*********************************************n";
/**
* 提示輸入主選單的項目值
*/
public static final String SHOW_TYPE_MENU_ITEM = "請輸入您要的功能[1-" + SHOW_MENU_ITEMS.length + "]:";
/**
* 提示輸入的主選單項目值有誤
*/
public static final String SHOW_TYPE_MENU_ITEM_ERROR = "輸入有誤,請重新輸入[1-" + SHOW_MENU_ITEMS.length + "]:";
/**
* 是否關閉程式的訊息
*/
public static final String SHOW_EXIT_MENU = "離開選單等於關閉程式,您確定嗎?[Y/N]:";
/**
* 取消關閉程式的訊息
*/
public static final String SHOW_WELCOME_BACK = "歡迎回來!";
/**
* 關閉程式的訊息
*/
public static final String SHOW_EXIT = "掰掰 %s ,歡迎下次再來挑戰!n"; //printf
/**
* Y或N輸入錯誤的訊息
*/
public static final String SHOW_EXIT_ERROR = "輸入有誤,請重新輸入[Y/N]:";
/**
* 電腦名稱
*/
public static final String[] COMPUTER_NAMES = {"「狂獅」鐵戰", "「血手」杜殺", "「不男不女」屠嬌嬌", "「笑裡藏刀」哈哈兒", "「不吃人頭」李大嘴", "「惡賭鬼」軒轅三光", "「迷死人不賠命」蕭咪咪", "「半人半鬼」陰九幽", "「損人不利己」白開心", "「電腦不難」幻嵐", "「電腦不難」幻冽", "「電腦很難」幻難"};
/**
* 猜題次數少
*/
public static final String SHOW_GUESS_TIMES_BEST[] = {"太厲害了!您只猜了%d次!", "塞郎!居然只猜了%d次!", "好賽啊!居然猜%d次就猜出來了!", "神手啊!猜%d次就猜出來了!", "您只猜了%d次!"}; //printf
/**
* 猜題次數中
*/
public static final String SHOW_GUESS_TIMES_GOOD[] = {"厲害!您猜了%d次。", "高手!您猜了%d次。", "強人,只猜了%d次。", "神,您只猜了%d次。", "您猜了%d次!"}; //printf
/**
* 猜題次數多
*/
public static final String SHOW_GUESS_TIMES_BAD[] = {"好遜喔!您猜了%d次!", "真是不好意思,我太高估您了!您居然猜了%d次!", "爛死了,不會玩猜數字喔?您知道您猜了%d次嗎?", "您是第一次玩猜數字嗎?您猜了%d次!", "您猜了%d次,還要再多練習喔!"}; //printf
/**
* 玩家名稱:
*/
public static final String SHOW_TALK_NAME = "%s:"; //printf
/**
* 玩家名稱:說話語句
*/
public static final String SHOW_TALK_NAME_SENTENCE = "%s:%sn";
/**
* 電腦出題者剛出現時的語句
*/
public static final String[] COMPUTER_ASKER_APPEAR = {"就由我來當您的對手吧!", "先等等,讓我出個題目。", "唔?開始了嗎?", "換我上場了嗎?", "有客人上門了?", "該我上場了嗎?", "您好。", "安安。", "安安,您好。", "安。", "又有不自量力的人來了。", "您看起來很弱。", "您看起來很強。"};
/**
* 使用者出題者剛出現時的語句
*/
public static final String[] USER_ASKER_APPEAR = {"來猜猜看我心裡所想的數字吧!不過要等等,讓我先出個題目。", "Let's battle! 等我出題。", "由我先攻!", "我以考倒電腦為樂。", "電腦不足為懼。"};
/**
* 電腦出題者出完題目的語句
*/
public static final String SHOW_COMPUTER_FINISH_PROBLEM = "%s 已經出好題目了。n"; //printf
/**
* 出題者出完題目的語句
*/
public static final String[] START_GUESS = {"您可以開始猜了!", "好,開始猜吧!", "說出您要猜的數字吧!", "請猜出一組四個不重複的數字。", "有了!您絕對猜不到!", "開始瞎猜吧!", "我好了,您開始猜吧!", "快猜吧!", "可以開始猜了。"};
/**
* 使用者亂輸入提示造成電腦判斷失敗的語句
*/
public static final String[] COMPUTER_GUESS_FAIL = {"別以為我不知道你在唬我!這回合就這樣結束吧!", "您的提示有錯啦!這回合就這樣結束吧!", "X的!別唬爛啦!這回合就這樣結束吧!", "您的提示有錯,讓我猜不下去,這回合就這樣結束吧!", "您亂提示,我想結束這個回合。", "我看您是來亂的,我想結束這個回合。", "您圖謀不軌啦!", "猜不出來,您是亂給提示吧?"};
/**
* 電腦玩家的掰掰語句
*/
public static final String[] COMPUTER_BYE = {"掰掰!", "88", "86", "下次再來。", "886", "881", "再見啦!", "再會啦!", "有緣再見。"};
/**
* 使用者玩家的掰掰語句
*/
public static final String[] USER_BYE = {"我不玩了,掰掰依!", "先閃啦,掰掰!", "我先下了,掰掰!", "不想玩了,掰掰。"};
/**
* 輸入格式有誤的語句
*/
public static final String[] COMPUTER_HINT_TYPE_ERROR = {"其實這個並不好笑。", "您在說什麼?", "蛤?", "蝦米?", "飯可以亂吃,話不可以亂說。", "聽不懂。", "再說一次。", "別跟我開玩笑。", "有沒有新花樣?", "這招玩過了喔!", "您的愚蠢輸入已經上傳至網路上。", "您快上新聞了。", "拜託認真點。", "我好想睡覺...zzZ", "旁邊看你玩的人快要發瘋了", "這樣好笑嗎?你開心就好(無奈)", "不知道怎麼輸入不會去看說明嗎?文盲喔?", "不會玩就來這招?", "我懷疑您沒逛過電腦不難。", "天快下紅雨了..", "歡迎光臨電腦不難!https://it-easy.tw", "呆子。", "笨蛋。", "白癡。", "唧哩呱啦。"};
/**
* 電腦猜題者猜題的語句
*/
public static final String[] COMPUTER_GUESS = {"我猜%s。", "我猜...%s。", "%s?沒頭緒,隨便猜。", "一定是%s啦!哈哈哈!亂猜的。", "不會是%s吧?", "難道是%s?", "%s。", "不知道,%s嗎?", "1234...?不對,我猜%s好了。", "5678...?不對,我猜%s好了。", "0123...?不對,我猜%s好了。", "2345...?不對,我猜%s好了。", "3456...?不對,我猜%s好了。", "4567...?不對,我猜%s好了。", "幸運女神來眷顧我吧!我猜%s!!", "%s?真難猜。", "毫無頭緒,我就猜%s吧!", "幸運之神來眷顧我吧!我猜%s!!", "%s嗎?", "%s。就決定是你了!", "我聽到神的旨意了,祂說%s。"}; //printf
/**
* 電腦猜題者猜題幫助使用者的語句
*/
public static final String[] COMPUTER_HELP_GUESS = {"您可以猜%s,有%2.0f%的猜中機率。", "猜%s吧!有%2.0f%的猜中機率。", "我會猜%s,有%2.0f%的猜中機率", "猜%s,%2.0f%的機率會中。", "如果是我我會猜%s,因為有%2.2f%的機率會中。", "猜%s吧,精確算了一下,有%2.5f%的機率會中。"};//printf
/**
* 使用者向電腦求助幫忙猜數字的語句
*/
public static final String[] USER_SERVICE = {"誰能幫我猜數字...", "有請電腦幫我猜數字!", "拜託幫我猜數字!", "可以幫我猜數字嗎?", "你馬幫幫忙,幫我猜數字。", "為了猜數字而苦惱...","猜~猜~幫我猜數子!"};
/**
* 提示哪兩個玩家在猜題
*/
public static final String COMPUTERS_VS = "%s VS %sn";
/**
* 提示回合
*/
public static final String SHOW_COMPUTERS_START = "第%d回合由 %s 出題。n";
/**
* 遊戲結束訊息
*/
public static final String SHOW_GAME_EXIT = "n遊戲已結束,要繼續嗎?[Y/N]:";
/**
* 玩家出題訊息
*/
public static final String SHOW_MAKE_QUESTION = "玩家請先在心中出題,想好後按下Enter繼續... ";
/**
* 玩家回答提示訊息
*/
public static final String SHOW_SERVICE_HELP = "這個模式玩家只要針對電腦給的數字進行XAYB的回答就行了。按下Enter繼續... ";
/**
* Enter鍵訊息
*/
public static final String SHOW_TYPE_ENTER = "(按下Enter繼續...) ";
/**
* 人機大戰結果訊息
*/
public static final String SHOW_CONTEST_WINNER = "本局由 %s 取得勝利!只猜了%d次!";
}

ComputerPlayer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
* 常用的方法
*/
package guessNumberPackage;
 
import java.util.Scanner;
 
/**
* 常用的方法,獨立出一個類別來存放
* @author 幻嵐
*/
public class Tools {
 
/**
* 延遲
* @param time 輸入延遲時間(單位:毫秒)
*/
public static void delay(int time) {
try {
Thread.sleep(time); //延遲
} catch (Exception e) {
}
}
 
/**
* 只能輸入Y或N,其餘免談,會要求重新輸入
* @return 輸入Y傳回true,輸入N傳回false
* @see StringClass
*/
public static boolean typeYorN() {
Scanner sc = new Scanner(System.in);
String inputEnd = sc.nextLine(); //儲存使用者輸入的資料
while (inputEnd.length() != 1 || (inputEnd.toUpperCase().charAt(0) != 'Y' && inputEnd.toUpperCase().charAt(0) != 'N')) { //如果輸入有誤
System.out.print(StringClass.SHOW_EXIT_ERROR);
inputEnd = sc.nextLine();
}
if (inputEnd.toUpperCase().charAt(0) == 'Y') {
return true;
} else {
return false;
}
}
 
/**
* 用亂數的方式隨機取得字串陣列的項目
* @param array 傳入字串陣列
* @return 傳回隨機取得的字串項目
*/
public static String getStringArrayRandom(String[] array) {
return array[(int) (Math.random() * array.length)];
}
}

UserPlayer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
* 程式功能選單
*/
package guessNumberPackage;
 
import java.util.Scanner;
 
/**
* 清單
* @see StringClass
* @see Menu_Method
* @author 幻嵐
*/
public class Menu {
 
/**
* 顯示選單
*/
public static void show() {
System.out.print(StringClass.SHOW_MENU_TOP);
for (int i = 0; i < StringClass.SHOW_MENU_ITEMS.length; i++) {
System.out.printf(StringClass.SHOW_MENU_TYPE, i + 1, StringClass.SHOW_MENU_ITEMS[i]);
}
System.out.print(StringClass.SHOW_MENU_END);
typeData(); //由使用者輸入資料
}
 
/**
* 由使用者輸入資料(清單上面的號碼)
*/
private static void typeData() {
Scanner sc = new Scanner(System.in);
System.out.print(StringClass.SHOW_TYPE_MENU_ITEM);
String inputString = sc.nextLine(); //儲存使用者輸入的資料
while (inputString.length() != 1 || inputString.charAt(0) < '1' || inputString.charAt(0) > StringClass.SHOW_MENU_ITEMS.length + 48) { //如果輸入有誤
System.out.print(StringClass.SHOW_TYPE_MENU_ITEM_ERROR);
inputString = sc.nextLine();
}
Menu_Method.methods(inputString.charAt(0) - 48); //呼叫Menu選單的方法,傳入引數為選單的選項值
}
}

Talk.java

1
2
3
4
5
6
7
8
9
10
11
12
/*
* enum Talk
*/
package guessNumberPackage;
 
/**
* 辨識語句用的Talk特徵
* @author 幻嵐
*/
public enum Talk {
START,FINISH,GUESS,GUESS_FAIL,BYE,HINT,RESPOND,HELP_GUESS;
}

Stage.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* 猜數字兩位玩家的舞台
*/
package guessNumberPackage;
 
/**
* 舞台。為遊戲主體。
* @see StringClass
* @see ComputerPlayer
* @see UserPlayer
* @see Tools
* @see Player
* @see Talk
* @author 幻嵐
*/
public class Stage {
 
/**
* 人機大戰使用的舞台。兩位Player交叉猜對方的數字與互相回答提示。
* @param user 使用者玩家
* @param com 電腦玩家
* @return 傳回true則重新執行此方法;傳回false則回到選單(Menu)
* @see Menu
* @see Menu_Method
*/
public static boolean contest(Player user, Player com) {
Player Winner = null; //勝利者
System.out.printf(StringClass.COMPUTERS_VS, user.getName(), com.getName());
com.talk(Talk.START); //開始
Tools.delay(1500); //延遲1.5秒
com.talk(Talk.FINISH); //完成出題
user.talk(Talk.FINISH); //完成出題
com.talk(Talk.GUESS); //開始猜
do {
user.respondQuestion(com); //玩家回答問題
com.replyHint(user); //電腦回答提示
if (com.getLastHint().equals("4A0B")) {
Winner = user;
break;
}
com.respondQuestion(user); //電腦回答問題
user.replyHint(com); //玩家回答提示
if (user.getLastHint().equals("4A0B")) {
Winner = com;
break;
}
com.thinkHint(user.getLastHint()); //電腦思考提示
} while (com.getGuessPercent() != 0);
 
if (com.getGuessPercent() == 0) { //如果結果有誤
com.talk(Talk.GUESS_FAIL);
} else { //如果無誤,輸出勝負和所猜次數
System.out.printf(StringClass.SHOW_CONTEST_WINNER, Winner.getName(), Winner.getGuessTimes());
}
 
Tools.delay(2000); //延遲兩秒
return exit(user, com); //結束程式
}
 
/**
* 一般猜數字的舞台。Asker為出題者;Respondent為猜題者。
* @param Asker 出題者
* @param Respondent 猜題者
* @return 傳回true則重新執行此方法;傳回false則回到選單(Menu)
* @see Menu
* @see Menu_Method
*/
public static boolean play(Player Asker, Player Respondent) { //若為true則重複執行;false則跳出
Asker.talk(Talk.START); //開始
Tools.delay(1500); //延遲1.5秒
Asker.talk(Talk.FINISH); //完成出題
Tools.delay(1000); //延遲一秒
Asker.talk(Talk.GUESS); //開始猜
do {
Respondent.respondQuestion(Asker); //回答問題
Asker.replyHint(Respondent); //回答提示
Respondent.thinkHint(Asker.getLastHint());
} while (Asker.getLastHint().equals("4A0B") == false && Respondent.getGuessPercent() != 0);
if (Respondent.getGuessPercent() == 0) { //如果結果有誤
Respondent.talk(Talk.GUESS_FAIL);
} else { //如果無誤,輸出次數
Asker.talk(Respondent.getGuessTimes());
}
Tools.delay(2000); //延遲兩秒
 
return exit(Asker, Respondent); //結束程式
}
 
/**
* 關閉舞台。在使用者玩家優先說掰掰的條件下,讓兩位玩家互相說掰掰。
* @param player1 玩家1
* @param player2 玩家2
* @return 傳回true或false到play()或contest()方法
*/
private static boolean exit(Player player1, Player player2) {
System.out.print(StringClass.SHOW_GAME_EXIT);
if (Tools.typeYorN()) { //若輸入y
return true; //傳回true。
} else { //若輸入n
Player a, b;
/*
* 判斷玩家。由使用者玩家優先輸出。
*/
if (player1 instanceof UserPlayer) {
a = player1;
b = player2;
} else {
a = player2;
b = player1;
}
a.talk(Talk.BYE);
Tools.delay(1000); //延遲一秒
b.talk(Talk.BYE);
Tools.delay(1000); //延遲一秒
return false; //傳回false,跳出menu的迴圈
}
}
}

Explain.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/*
* 猜數玩法說明
*/
package guessNumberPackage;
import java.util.Scanner;
 
/**
* 猜數字玩法說明
* @author 幻嵐
*/
public class Explain {
 
/**
* 顯示玩法說明
*/
public static void show(){
 
System.out.println("  猜數字可以算是一種益智類小遊戲,一般兩個人玩。遊戲規則也很簡單,但可以考驗人的耐心和細心。");
type_Enter();
System.out.println("  規則就是玩家兩人中某方(以下以甲方代稱)先在心裡想出一組由四個皆不同的數所組成的四位數字(例如:1234、5678、0653),且每位數的數字範圍都在0到9。而另一方(以下以乙方代稱)則要猜出甲方心裡所想的數字。甲方需以XAYB(例如1A2B)的形式提示乙方猜的答案。XA中的X表示數值正確且位置也正確的數字數量;YB中的Y表示數值正確但位置不正確的數字數量。例如:假設甲方心中的數字為1357,而乙方所猜的數為1234,則甲方要回答提示1A1B給乙方,因為甲方的1與乙方的1位置正確,但甲方的3與乙方的3位置不正確。下面舉個完整的例子↓");
type_Enter();
System.out.println("假設乙要猜甲的數字,以下是他們的對話內容:");
System.out.println("乙:1234");
System.out.println("甲:0A0B(此時我們可以確定這個4位數字絕對不會是1、2、3、4所組成。)");
System.out.println("乙:5678(因此繼續猜5678)");
System.out.println("甲:0A3B");
System.out.println("乙:7865");
System.out.println("甲:3A0B");
System.out.println("乙:7860");
System.out.println("甲:4A0B");
System.out.println("直到甲方說出4A0B才算乙方真的猜中甲方的數字!");
type_Enter();
System.out.println("怎麼樣?聽起來很難,可是玩久了之後很快就能上手了!");
type_Enter();
System.out.println("如果您已經很熟悉猜數字的規則,可以試試看更難的玩法↓");
type_Enter();
System.out.println("甲方和乙方同時在心裡想一組數字,接著兩方互猜,最先猜出對方心中數字的就是勝利的一方!");
type_Enter();
System.out.println("本猜數字遊戲程式提供了單方面「電腦出題讓使用者猜」、「使用者出題讓電腦猜」和雙方面「使用者和電腦互猜」(也就是選單中的人機大戰)的遊戲模式,另外也有電腦助猜功能。如果您覺得這個遊戲不錯,歡迎造訪我們的網站—電腦不難!");
type_Enter();
System.out.println("https://it-easy.tw/");
type_Enter();
}
 
/**
* 按下Enter繼續閱讀
* @see StringClass
*/
private static void type_Enter(){
Scanner sc=new Scanner(System.in);
System.out.printf(StringClass.SHOW_TYPE_ENTER);
sc.nextLine();
System.out.println(); //換行
}
}
文章分類:Java|標籤:,

迴響已關閉