-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGameLogic.java
More file actions
280 lines (268 loc) · 10.8 KB
/
GameLogic.java
File metadata and controls
280 lines (268 loc) · 10.8 KB
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
import java.io.IOException;
import java.util.ArrayList; // using array lists
import java.util.Random; // randomly spawning the player and the bot on the map
/**
* Class contains the game's logic
*/
class GameLogic {
private Player player;
private BotPlayer bot;
private int turn = 0; // counter to decide whose turn it is
private Map map; // game map
private ArrayList<char[]> navigationMap; // the game map which will be used in the game logic for computation
private boolean gameEnded = false;
private int goldToWin;
private ChatClient chatPlayer; // the user who plays the game
/**
* Constructor which initializes the game's logic on a specified map for a specified user
* @param map Map object representing the DoD map
* @param chatPlayer ChatClient object which represents the user who plays the game
*/
public GameLogic(Map map, ChatClient chatPlayer){
this.map = map;
this.chatPlayer = chatPlayer;
this.goldToWin = map.getGold();
this.navigationMap = map.getMap();
}
/**
* Randomly spawn a Player object on the map.
* @param player Player object representing either the human player or the bot
*/
private void generateRandomCoordinates(Player player){
Random random = new Random();
int row = random.nextInt(map.getRows());
int column = random.nextInt(map.getColumns());
// depending on whether it is the human player or the bot, spawn them differently
// keep trying to randomly spawn them until the Player object is placed on a valid tile
if(player == this.player){
while(navigationMap.get(row)[column] != '.' && navigationMap.get(row)[column] != 'E'){
row = random.nextInt(map.getRows());
column = random.nextInt(map.getColumns());
}
}
else{
while(navigationMap.get(row)[column] == 'P' || navigationMap.get(row)[column] == '#'){
row = random.nextInt(map.getRows());
column = random.nextInt(map.getColumns());
}
}
// update the player's fields accordingly
player.setCurrentTile(navigationMap.get(row)[column]);
player.setColumn(column);
player.setRow(row);
}
/**
* Processes the command given by one of the Players.
* @param command the command
* @param player Player who gave the command
*/
private void processCommand(String command, Player player){
// checking if it is a move command first
if(command.equals("move e") || command.equals("move w") ||
command.equals("move s") || command.equals("move n")){
MOVE(command.replace("move ", ""), player);
return;
}
// checking for the other commands
switch (command) {
case "hello": HELLO(); return;
case "gold": GOLD(); return;
case "look": LOOK(player);return;
case "pickup": PICKUP();return;
case "quit": QUIT();return;
default:
// Command is not valid and the turn is wasted.
System.out.println("Unrecognized command.\nFAIL.");
}
}
/**
* Look method. Analyzes the 5*5 grid surrounding the player.
* If it is the human player, it displays it.
* Else, the bot calls the updateMemoryMap() method to make use
* of the grid for its next decision.
* @param player Player object which can be either a human player or a bot
*/
private void LOOK(Player player){
boolean playerFound = false; // checking to see if the player is in sight
ArrayList<char[]> visibleMap = new ArrayList<>(); // the 5*5 grid which will be passed to the bot if needed
int visibleRowIndex;
int row = player.getRow();
int column = player.getColumn();
// Player is always in the centre
for(int rowIndex = row - 2; rowIndex <= row + 2; rowIndex++){
// create arrays of characters for each row, and add them to the array list
char[] visibleRow = new char[100];
visibleRowIndex = 0;
for(int columnIndex = column - 2; columnIndex <= column + 2; columnIndex++){
// Visible area outside the map
if(rowIndex < 0 || columnIndex < 0 ||
rowIndex >= map.getRows() || columnIndex >= map.getColumns()){
// checking which player called this method
if(player == this.player){
System.out.print('#');
}
else{
visibleRow[visibleRowIndex] = '#';
visibleRowIndex++;
}
}
// Visible area inside the map
else {
if(player == this.player){
System.out.print(navigationMap.get(rowIndex)[columnIndex]);
}
else{
// if we found the player, update the value of the boolean variable and let the bot know
if(navigationMap.get(rowIndex)[columnIndex] == 'P'){
this.bot.setPlayerFound(rowIndex + 2 - row, columnIndex + 2 - column);
playerFound = true;
}
visibleRow[visibleRowIndex] = navigationMap.get(rowIndex)[columnIndex];
visibleRowIndex++;
}
}
}
if(player == this.player){
System.out.println();
}
if(player == this.bot){
visibleMap.add(visibleRow);
}
}
// if bot called method, pass the information further
if(player != this.player){
bot.updateMemoryMap(visibleMap);
}
// if bot called method and the player was not found, let the bot know
if(!playerFound && player == this.bot){
this.bot.lostPlayer();
}
}
/**
* Method which moves the player who calls it
* @param direction direction in which the player wants to go
* @param player Player object which can be either thr human or the bot
*/
private void MOVE(String direction, Player player){
int row = player.getRow();
int column = player.getColumn();
// Updating the coordinates based on the direction
switch (direction){
case "e": column += 1; break;
case "w": column -= 1; break;
case "n": row -= 1; break;
case "s": row += 1; break;
}
// Checking that the position is valid
char characterFromMap = navigationMap.get(row)[column];
// bot caught the player
if((characterFromMap == 'P' && player == this.bot) || (characterFromMap == 'B' && player == this.player)){
this.player.setCurrentTile('B');
this.bot.setCurrentTile('P');
gameEnded = true;
return;
}
if(characterFromMap != '#'){
// assign the map 'P' or 'B' character the tile character on which the player was sitting before
navigationMap.get(player.getRow())[player.getColumn()] = player.getCurrentTile();
player.setCurrentTile(navigationMap.get(row)[column]); // get the new tile character
player.setRow(row);
player.setColumn(column);
//update the map with either 'P' or 'B' characters
if(player == this.player){
navigationMap.get(row)[column] = 'P';
}
else {
navigationMap.get(row)[column] = 'B';
}
// print message to let the player know if it succeeded or not
if(player == this.player){
System.out.println("SUCCESS");
}
}
else {
if(player == this.player){
System.out.println("FAIL");
}
}
}
/**
* Displays the gold required to win.
*/
private void HELLO(){
System.out.println("Gold to win: " + goldToWin);
}
/**
* Display's the gold currently owned by the player
*/
private void GOLD(){
System.out.println("Gold owned: " + player.getCurrentGold());
}
/**
* Attempts to pickup gold from the dungeon.
*/
private void PICKUP(){
if(player.getCurrentTile() == 'G'){
player.addGold();
/*
* it is important to update the tile character on which
* the player is sitting to '.' so we don't get an infinite gold bug
*/
player.setCurrentTile('.');
System.out.print("SUCCESS. ");
}
else{
System.out.print("FAIL. ");
}
// display the gold owned
GOLD();
}
/**
* End the game
*/
private void QUIT(){
gameEnded = true;
}
/**
* Execute the flow of the game:
* Initialize and spawn the player and the bot.
* Based on the turn, process each player's commands until the game has ended.
*/
public void play(){
// creating a list of the players and using the turn variable as index
ArrayList<Player> players = new ArrayList<>();
player = new Player();
bot = new BotPlayer();
players.add(player);
players.add(bot);
generateRandomCoordinates(player);
navigationMap.get(player.getRow())[player.getColumn()] = 'P'; // update the map tile
generateRandomCoordinates(bot);
navigationMap.get(bot.getRow())[bot.getColumn()] = 'B'; // update the map tile
String command = "";
while (!gameEnded){
// get all input commands to lower case
if(players.get(turn) == player){
try {
// commands are received by accessing the user's input stream from the keyboard
command = chatPlayer.getUserIn().readLine().toLowerCase();
} catch (IOException e){
e.printStackTrace();
}
}
else{
command = bot.makeDecision().toLowerCase();
}
processCommand(command, players.get(turn));
turn++;
turn %= 2;
}
// check if the player won or lost
if(player.getCurrentTile() == 'E' && player.getCurrentGold() >= goldToWin && bot.getCurrentTile() != 'P'){
System.out.println("WIN");
}
else {
System.out.println("LOSE");
}
}
}