-
Notifications
You must be signed in to change notification settings - Fork 1
/
ClientGame.java
170 lines (157 loc) · 4.24 KB
/
ClientGame.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
169
170
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
/**
* Abstract Client-side game to handle common functions such as asking for user input.
*
*/
public abstract class ClientGame {
protected final BufferedReader consoleReader;
protected PrintWriter out;
protected int tries;
private boolean fileInitialized = false;
public ClientGame(String fileName) {
this.consoleReader = new BufferedReader(new InputStreamReader(System.in));
try {
this.out = new PrintWriter(new File(fileName));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
/**
* Initialize resources and start the Client game.
*/
public void run() {
System.out.println("Client-Server Hangman game is starting...");
}
protected void toPlayOrNotToPlay() {
String userInput = null;
while (true) {
System.out.print("Do you want to play? (y/n) ");
try {
userInput = this.consoleReader.readLine();
} catch (IOException ex) {
ex.printStackTrace();
stopGame();
break;
}
userInput = userInput.trim().toLowerCase();
if (userInput == null) {
stopGame();
break;
} else if (userInput.equals("y")) {
if (!this.fileInitialized) {
FileUtils.initFile(this.out);
this.fileInitialized = !this.fileInitialized;
}
writeToServer(Server.GAME_PLAY);
this.tries = 0;
if (!play()) {
break;
}
} else if (userInput.equals("n")) {
stopGame();
break;
} else {
System.out.println("Invalid input.");
}
}
}
/**
* Play a Hangman game interactively.
*
* Show the user the encoded word and ask for letter/digit input as guess.
*
* @return <code>true</code> if the game is won or lost, and <code>false</code> if the server runs out of games or
* an exception occurs
*/
protected abstract boolean play();
/**
* Asks the user to input a guess character.
*
* @param response
* the returned data from the Server which is the encoded word
*/
protected void askForGuess(String response) {
System.out.println("Guess the word: " + response);
while (true) {
System.out.print("Enter a character: ");
try {
String userInput = this.consoleReader.readLine();
if (userInput == null) {
stopGame();
break;
} else {
userInput = userInput.trim().toLowerCase();
if (!userInput.matches("^[A-Za-z0-9]$")) {
System.out.println("Invalid input. Type only one letter or number!");
} else {
writeToServer(userInput);
this.tries++;
break;
}
}
} catch (IOException ex) {
ex.printStackTrace();
stopGame();
break;
}
}
}
/**
* The current Hangman game is over; either won or lost. Then, write the details to a file.
*
* @param response
* the result received from the Server
*
*/
protected void gameWonOrLost(String response) {
String won = response.substring(0, response.indexOf(":"));
String word = response.substring(response.indexOf(":") + 1);
System.out.print("You " + won.toLowerCase() + "! ");
System.out.println("The word was '" + word + "'.\n");
FileUtils.printToFile(this.out, word, (won.equals("WON") ? "Yes" : "No"), this.tries);
}
/**
* The Server has no more Hangman games. Clean up the resources then.
*/
protected void gameOver() {
cleanUp();
System.out.println("Sorry, no more games!");
}
protected void handleFatalException(Exception ex) {
ex.printStackTrace();
System.err.println("A fatal problem occurred. Closing the game now...");
closeConnection();
}
/**
* Write a String message to the Server and flush the output stream to force sending the data.
*
* @param msg
* the data to be sent to the Server in String representation
*/
protected abstract void writeToServer(String msg);
/**
* Cleans up the resources for this Client app.
*/
protected void cleanUp() {
try {
this.consoleReader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* Sends to the Server that the Client no longer wants to play.
*
* And frees up the resources.
*/
protected void stopGame() {
writeToServer(Server.GAME_STOP);
cleanUp();
}
protected abstract void closeConnection();
}