-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBoardGame.java
More file actions
244 lines (200 loc) · 8.42 KB
/
Copy pathBoardGame.java
File metadata and controls
244 lines (200 loc) · 8.42 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
/*
Description:
BoardGame abstract class extends Game and implements TurnBased, representing a turn-based board game.
It manages game mechanics such as board state, turns, user input, and game history storage
common to all board games.
Fields:
- FILENAME: Class level constant filename for exporting game history.
- scanner: Constant scanner object for user input.
- board: The game board.
- turnNumber: Tracks the current turn number.
- gameNumber: Tracks the game number across multiple sessions.
Constructors:
- BoardGame(String name): Initializes a board game with default board size.
- BoardGame(int rows, int columns, String name): Initializes a board game with a custom board size.
- BoardGame(int rows, int columns, String name, String gameID): initializes all of the above plus the game id field.
Abstract Method Implementations:
- exitGame(): Saves game history to a file before exiting.
- isValidMove(int row, int column): Checks if a move is valid.
- getTurnNumber(): Gets the current turn number.
- getCurrentTeam(): Gets the current team based off of the current turn.
- incrementTurnNumber: Increments the current turn number.
- resetTurnNumber: Resets the turn number.
Important Methods:
- getIsBoardFull(): used to check if the board is full of pieces
- reset(String gameType): Saves game history, resets the board, and prepares for a new game.
- getTeamFromUserInput(int number, String name): Gets team input from the user.
- isUserDone(): Checks if the user wants to continue playing.
- getNextPlayerInputCell(Team team, Player player): Gets the player's move input.
*/
import java.util.Scanner;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public abstract class BoardGame extends Game implements TurnBased {
// constant filename to export game history data
private static final String FILENAME = "data.txt";
private final Scanner scanner;
private Board board;
private int turnNumber;
private int gameNumber;
// CONSTRUCTORS
public BoardGame(String name) {
super(name);
this.board = new Board();
this.turnNumber = 0;
this.scanner = new Scanner(System.in);
this.gameNumber = 1;
}
public BoardGame(int rows, int columns, String name) {
super(name);
this.board = new Board(rows, columns);
this.turnNumber = 0;
this.scanner = new Scanner(System.in);
this.gameNumber = 1;
}
public BoardGame(int rows, int columns, String name, String gameID) {
super(name, gameID);
this.board = new Board(rows, columns);
this.turnNumber = 0;
this.scanner = new Scanner(System.in);
this.gameNumber = 1;
}
// GETTER METHODS
public Board getBoard() {
return this.board;
}
public int getTurnNumber() {
return this.turnNumber;
}
public Team getCurrentTeam() {
Team[] teams = this.getTeams();
return teams[this.turnNumber % teams.length];
}
public Scanner getScanner() {
return this.scanner;
}
public boolean getIsBoardFull() {
// check if there are any empty cells left on the board
for (Cell[] row : this.board.getBoard()) {
for (Cell cell : row) {
if (cell.getValue() == null) return false;
}
}
return true;
}
public int getGameNumber() {
return this.gameNumber;
}
// SETTER METHODS
public void incrementTurnNumber() {
this.turnNumber += 1;
}
public void setBoard(Board board) {
this.board = board;
}
public void resetTurnNumber() {
this.turnNumber = 0;
}
public void incrementGameNumber() {
this.gameNumber++;
}
public void reset(String gameType) {
this.addGameHistory(new BoardGameHistory(this.getWinner(), this.board, this.turnNumber + 1, this.gameNumber));
this.board = new Board(board.getRows(), board.getColumns(), gameType);
this.resetTurnNumber();
this.incrementGameNumber();
this.setWinner(null);
}
// COMMON METHODS FOR ALL GAME SUBCLASSES
// USER INPUT METHODS
private Team getTeamFromUserInput(int number, String name) {
System.out.print("Enter comma seperated list of players on team " + name + " (leave blank for default player):\t");
String input;
while (true) {
try {
input = this.scanner.nextLine().trim();
if (input.length() == 0) return new Team(new Player(), number, name);
String[] names = input.split(",");
for (int i = 0; i < names.length; i++) names[i] = names[i].trim();
Player[] players = new Player[names.length];
for (int i = 0; i < names.length; i++) players[i] = new Player(names[i]);
return new Team(players, number, name);
} catch (Exception e) {
System.out.print("Enter comma seperated list of players on team " + name + " (leave blank for default player):\t");
}
}
}
public void setTeamsFromUserInput(String team0Name, String team1Name) {
Team[] teams = new Team[2]; // 2 teams
teams[0] = this.getTeamFromUserInput(0, team0Name);
teams[1] = this.getTeamFromUserInput(1, team1Name);
this.setTeams(teams);
}
public boolean isUserDone() {
System.out.print("Would you like to play again (y/n):\t");
String resp;
while (true) {
resp = this.scanner.next();
if (resp.equalsIgnoreCase("y")) {
return false;
} else if (resp.equalsIgnoreCase("n")) {
// display the win counts for all players on all teams before quitting
for (Team team : this.getTeams()) {
team.displayPlayerWinCounts();
}
return true;
} else {
System.out.print("Invalid input. Please enter y/n:\t");
}
}
}
public Cell getNextPlayerInputCell(Team team, Player player) {
System.out.print("[TEAM " + team.getName() + "] " + player.getName() + " enter your move (row,col):\t");
int row, column;
String input;
while (true) {
try {
input = this.scanner.next();
String[] parts = input.split(",");
if (parts.length != 2) throw new IllegalArgumentException();
row = Integer.parseInt(parts[0].trim());
column = Integer.parseInt(parts[1].trim());
if (!this.isValidMove(row, column)) throw new IllegalArgumentException();
break;
} catch (Exception e) {
System.out.print("Invalid move. Please enter a valid move (row,col):\t");
}
}
return this.board.getCell(row, column);
}
// VALIDATION METHOD TO CHECK IF THE MOVE IS VALID
public boolean isValidMove(int row, int column) {
return row >= 0 && row < this.board.getRows() &&
column >= 0 && column < this.board.getColumns() &&
this.board.isBoardCellEmpty(row, column);
}
// EXIT ROUTINE FOR BOARD GAMES: save the list of game histories to a seperate file
public void exitGame() {
String input;
System.out.print("Would you like to save your game histories to " + FILENAME + " (y/n):\t");
while (true) {
input = this.scanner.next();
if (input.equalsIgnoreCase("n")) return; // immediately return if user does not want data.txt file
else if (input.equalsIgnoreCase("y")) break;
else System.out.print("Invalid input. Enter y or n:\t");
}
try {
File file = new File(FILENAME);
file.createNewFile();
FileWriter writer = new FileWriter(file, false); // overwrite enabled
String data = "";
for (GameHistory history : this.getGameHistory()) data += history.toString() + "\n";
writer.write(data);
writer.close();
System.out.println("Saved game history data in " + FILENAME);
} catch (IOException e) {
System.out.println("Error writing game history data to " + FILENAME);
}
}
}