-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGameController.java
261 lines (220 loc) · 11.5 KB
/
GameController.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
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
import java.util.*;
import java.util.ArrayList;
public class GameController {
/* GameController handles moves made by the player and handles the game board
* GameController also handles meeples and the gameloop by which the game is played through
* */
private GuiAdapter guiAdapter;
private static final char startingTileChar = 'S'; //Only used for local game
static final int NUM_PLAYERS = 2;
static final int NUM_TIGERS = 7;
private GameBoard board;
private PlayerController[] players = new PlayerController[NUM_PLAYERS];
private ArrayList<Tile> gameTileReference; // Don't modify this one after constructor. Can be indexed in to with tile.ID.
private ArrayList<Tile> gameTiles;
private int currentPlayer = 0;
private ScoreController scoreController;
public GameController(int row, int col){
board = new GameBoard(row, col);
players[0] = new ComputerPlayerController(board);
players[1] = new HumanPlayerController(board); // Humans don't waste processor power
this.gameTileReference = retrieveGameTiles();
scoreController = new ScoreController(gameTileReference, board);
}
GameController(int row, int col, ArrayList<Tile> tiles){
board = new GameBoard(row, col);
players[0] = new ComputerPlayerController(board);
players[1] = new HumanPlayerController(board); // Humans don't waste processor power
this.gameTileReference = tiles;
scoreController = new ScoreController(gameTileReference, board);
}
GameController(int numHumanPlayers){
this.gameTiles = retrieveGameTiles();
this.gameTileReference = retrieveGameTiles();
board = new GameBoard(gameTiles.size(), gameTiles.size());
guiAdapter= new GuiAdapter(gameTiles.size());
for (int numCreated = 0; numCreated < NUM_PLAYERS; numCreated++){
if (numCreated < numHumanPlayers){
players[numCreated] = new HumanPlayerController(guiAdapter);
}
else {
players[numCreated] = new ComputerPlayerController(guiAdapter, board);
}
}
scoreController = new ScoreController(gameTileReference, board);
Tile startingTile = prepareTiles();
Location boardDimensions = board.getBoardDimensions();
board.placeTile(startingTile, new Location( boardDimensions.Row / 2, boardDimensions.Col / 2 ), 0);
guiAdapter.placeFirstTile(boardDimensions.Row / 2,boardDimensions.Col /2 , String.format("%s", startingTile.tileType));
for (PlayerController playerController : players) {
playerController.processConfirmedMove(new Tile(startingTile), new MoveInformation(new Location(boardDimensions.Row / 2, boardDimensions.Col / 2), 0, -1), currentPlayer);
}
}
//draw the next tile from the array of shuffled tiles
private Tile drawTile(){
Tile nextTile;
do {
nextTile = gameTiles.get(gameTiles.size() - 1);
gameTiles.remove(gameTiles.size() - 1);
} while (!board.isPossibleToPlaceTileSomewhere(nextTile));
return nextTile;
}
//the game loop for the logic of the game
int gameLoop(){
Tile currentTile;
boolean spectating = false;
while(!gameTiles.isEmpty()){
currentTile = drawTile();
handleMove(currentTile);
if (spectating){
System.out.print("Press enter to continue.");
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
}
}
//Scores jungles and other features that have not been completed at the end of the game
endOfGameScoring();
//Prints the score in console
System.out.println("END GAME SCORE");
System.out.println(scoreController.player1Score);
System.out.println(scoreController.player2Score);
//Updates the GUI with the scores
guiAdapter.updateScores(scoreController.player1Score, scoreController.player2Score);
return 0;
}
//Scores jungles and other features that have not been completed at the end of the game
private void endOfGameScoring(){
for(int playerIndex = 0; playerIndex < board.playerTigers.length; playerIndex++){
for (int tigerIndex = 0; tigerIndex < board.playerTigers[playerIndex].length; tigerIndex++){
if (board.playerTigers[playerIndex][tigerIndex].status == TigerStatusEnum.onDen){
scoreController.scoreIncompleteDen(board.playerTigers[playerIndex][tigerIndex].location);
}
else if (board.playerTigers[playerIndex][tigerIndex].status == TigerStatusEnum.onLake){
Location tigerLocation = board.playerTigers[playerIndex][tigerIndex].location;
Tile tigerTile = board.board[tigerLocation.Row][tigerLocation.Col];
for (Edge edge : tigerTile.edges){
for (Node node: edge.nodes){
if (node.tiger != null && node.tiger.equals(board.playerTigers[playerIndex][tigerIndex])){
scoreController.scoreIncompleteLake(node);
break;
}
}
}
}
else if (board.playerTigers[playerIndex][tigerIndex].status == TigerStatusEnum.onTrail){
Location tigerLocation = board.playerTigers[playerIndex][tigerIndex].location;
Tile tigerTile = board.board[tigerLocation.Row][tigerLocation.Col];
for (Edge edge : tigerTile.edges){
for (Node node: edge.nodes){
if (node.tiger != null && node.tiger.equals(board.playerTigers[playerIndex][tigerIndex])){
scoreController.scoreJungle(node);
break;
}
}
}
}
else if (board.playerTigers[playerIndex][tigerIndex].status == TigerStatusEnum.onJungle){
Location tigerLocation = board.playerTigers[playerIndex][tigerIndex].location;
Tile tigerTile = board.board[tigerLocation.Row][tigerLocation.Col];
for (Edge edge : tigerTile.edges){
for (Node node: edge.nodes){
if (node.tiger != null && node.tiger.equals(board.playerTigers[playerIndex][tigerIndex])){
scoreController.scoreJungle(node);
break;
}
}
}
}
}
}
}
//Places the starting tile on the board for a game over the network
void processNetworkStart(Tile startingTile, MoveInformation startMoveInfo){
board.placeTile(startingTile, startMoveInfo.tileLocation, startMoveInfo.tileRotation);
players[0].processConfirmedMove(startMoveInfo);
}
//Processes the move that a player sent over the network
MoveInformation processNetworkedPlayerMove(Tile tileForPlayer){
return players[0].processPlayerMove(tileForPlayer);
}
//Places any new tiles or tigers that were placed in the move and confirmed by the server
//This keeps the local game board updated
void processConfirmedNetworkedMove(Tile tileForPlayer, MoveInformation playerMoveInfo, int currentPlayer){
board.placeTile(tileForPlayer, playerMoveInfo.tileLocation, playerMoveInfo.tileRotation);
if (playerMoveInfo.tigerLocation != -1) {
board.placeTiger(tileForPlayer, playerMoveInfo.tileLocation, playerMoveInfo.tigerLocation, currentPlayer);
}
ArrayList<Tiger> tigersToReturn = scoreController.processConfirmedMove(tileForPlayer, playerMoveInfo, currentPlayer, false);
for (PlayerController playerController : players){
playerController.processConfirmedMove(new Tile(tileForPlayer), playerMoveInfo, currentPlayer);
}
for (Tiger tiger : tigersToReturn){
board.freeTiger(tiger.owner, tiger.ID);
scoreController.processFreedTiger(tiger.owner, tiger.ID);
for (PlayerController playerController : players){
playerController.processFreedTiger(tiger.owner, tiger.ID);
}
}
board.printBoard();
}
//Waits for input from the player in the local game to make a move
private void handleMove(Tile tileForPlayer){
MoveInformation playerMoveInfo;
boolean firstAttempt = true;
do {
if (!firstAttempt) System.out.println("Invalid move.");
playerMoveInfo = players[currentPlayer].processPlayerMove(tileForPlayer);
firstAttempt = false;
} while (!board.verifyTilePlacement(tileForPlayer, playerMoveInfo.tileLocation, playerMoveInfo.tileRotation));
board.placeTile(tileForPlayer, playerMoveInfo.tileLocation, playerMoveInfo.tileRotation);
if (board.verifyTigerPlacement(tileForPlayer, playerMoveInfo.tigerLocation, currentPlayer) ) {
board.placeTiger(tileForPlayer, playerMoveInfo.tileLocation, playerMoveInfo.tigerLocation, currentPlayer);
}
else{
playerMoveInfo.tigerLocation = -1;
//Just throw away bad tiger placements so score ctrlr and players don't get false signal
}
ArrayList<Tiger> tigersToReturn = scoreController.processConfirmedMove(tileForPlayer, playerMoveInfo, currentPlayer, false);
for (PlayerController playerController : players){
playerController.processConfirmedMove(new Tile(tileForPlayer), playerMoveInfo, currentPlayer);
}
guiAdapter.proccessConfirmedMove(tileForPlayer, playerMoveInfo, currentPlayer);
for (Tiger tiger : tigersToReturn){
board.freeTiger(tiger.owner, tiger.ID);
scoreController.processFreedTiger(tiger.owner, tiger.ID);
for (PlayerController playerController : players){
playerController.processFreedTiger(tiger.owner, tiger.ID);
}
}
switchPlayerControl();
}
//Switches the control of the player
private void switchPlayerControl(){
currentPlayer = (currentPlayer + 1) % NUM_PLAYERS;
}
//Shuffles all of the tiles in the original array and puts into new array
private Tile prepareTiles(){ //Returns instance of starting tile
Tile startingTile = null;
for (int index = 0; index < gameTiles.size(); index++){
if (gameTiles.get(index).tileType == startingTileChar){
Collections.swap(gameTiles, index, gameTiles.size()-1);
startingTile = gameTiles.get(gameTiles.size()-1);
gameTiles.remove(gameTiles.size()-1);
break;
}
}
Collections.shuffle(gameTiles, new Random(System.currentTimeMillis()));
if (startingTile == null) {
System.out.println("Starting tile not found in the imported deck.");
}
return startingTile;
}
private ArrayList<Tile> retrieveGameTiles(){
Tile.resetTileIdentify();
String filePath = "tileset.txt";
return new TileRetriever(filePath).tiles;
}
Location getBoardCenter(){
return new Location(board.board.length / 2, board.board[0].length / 2);
}
}