PageRenderTime 65ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/PlayerManager.java

https://gitlab.com/bryansun/TicTacToe
Java | 412 lines | 249 code | 62 blank | 101 comment | 36 complexity | 891016b58ddb33d8ea0a00f56baa07d4 MD5 | raw file
  1. /*
  2. * Author: Shuyi Sun
  3. * Student ID: 731209
  4. * Date: 27th May, 2016
  5. * Comment: Project C, TicTacToe game solution in COMP90041
  6. * Description: this class contains all the Player instances
  7. * that will be recorded and methods to manipulate
  8. * the players.
  9. */
  10. import java.io.FileInputStream;
  11. import java.io.FileNotFoundException;
  12. import java.io.FileOutputStream;
  13. import java.io.PrintWriter;
  14. import java.util.Arrays;
  15. import java.util.Scanner;
  16. import java.util.StringTokenizer;
  17. class PlayerManager{
  18. //the constant to store the file name
  19. public static final String DATA_FILE = "players.dat";
  20. //the String value of the player descent classes
  21. public static final String AIPLAYER_TYPE = "AIPlayer";
  22. public static final String HUMAN_PLAYER_TYPE = "HumanPlayer";
  23. //the constants represent the game result
  24. public static final int WIN = 1;
  25. public static final int LOSE = 2;
  26. public static final int DRAW = 3;
  27. //this is a flag used to indicate that no player is found
  28. public static final Player NO_SUCH_PLAYER = null;
  29. //the maximum player number that this player manager can handle
  30. public static final int DEFAULT_PLAYER_CAPACITY = 100;
  31. //the initialized the player number of the player manager
  32. public static final int RESET_PLAYER_NUMBER = 0;
  33. //in remove and reset methods, the indicator for proceeded action
  34. public static final String
  35. CONFIRM_REMOVE_ALL = "Are you sure you want to remove all players? (y/n)";
  36. public static final String
  37. CONFIRM_RESET_ALL = "Are you sure you want to reset all player statistics? (y/n)";
  38. //confirmation reply of the program user
  39. public static final String CONFIRM_ANSWER = "y";
  40. //error information when an error occurs
  41. public static final String
  42. USERNAME_EXISTS_ERROR = "The username has been used already.";
  43. public static final String
  44. PLAYER_NOT_EXISTS_ERROR = "The player does not exist.";
  45. public static final String
  46. FILE_ERROR = "Error opening file players.dat";
  47. //the player array and the total number of players
  48. private Player[] playerArray;
  49. private int playerTotalNum;
  50. //constructor for a default maximum player number, which is 100
  51. public PlayerManager(){
  52. this(DEFAULT_PLAYER_CAPACITY);
  53. }
  54. //constructor for a given maximum player number
  55. public PlayerManager(int totalPlayers){
  56. playerArray = new Player[totalPlayers];
  57. resetPlayerManager();
  58. resumePlayerStats();
  59. }
  60. //remove all the players in the array
  61. private void resetPlayerManager(){
  62. playerTotalNum = RESET_PLAYER_NUMBER;
  63. }
  64. //find a player given its userName, if not existent, return -1
  65. public Player getPlayer(String userName){
  66. String playerUserName;
  67. if(userName == null){
  68. //no username will be null
  69. return NO_SUCH_PLAYER;
  70. }
  71. for(int i = 0; i < playerTotalNum; i++){
  72. //get the username of player i
  73. playerUserName = playerArray[i].getUserName();
  74. if(playerUserName.equals(userName)){
  75. //if the username is the same as the required one, return its index
  76. return playerArray[i];
  77. }
  78. }
  79. //if can not find the player, just return -1
  80. return NO_SUCH_PLAYER;
  81. }
  82. //add the given Player instance to the player list
  83. public void addPlayer(Player player){
  84. //if the player is null, do nothing
  85. if(player == null){
  86. return;
  87. }
  88. String playerUserName = player.getUserName();
  89. if(getPlayer(playerUserName) != NO_SUCH_PLAYER){
  90. //if the player already exists, print an error
  91. System.out.println(USERNAME_EXISTS_ERROR);
  92. }
  93. else{
  94. //if the player does not exist, add this player to the list
  95. playerArray[playerTotalNum] = player;
  96. //increment the total player number with one
  97. playerTotalNum++;
  98. }
  99. }
  100. //execute the remove command, remove a given player or remove all
  101. public void removePlayer(String userName){
  102. if(userName == null){
  103. //if no name given, ask if remove all the players
  104. System.out.println(CONFIRM_REMOVE_ALL);
  105. String answer = TicTacToe.scanner.nextLine();
  106. if(answer.equals(CONFIRM_ANSWER)){
  107. //remove all the players if user confirms
  108. removeAllPlayers();
  109. }
  110. }
  111. else{
  112. //if one name given, try to get the player instance first
  113. Player player = getPlayer(userName);
  114. if(player == NO_SUCH_PLAYER){
  115. //player does not exist, print error information
  116. System.out.println(PLAYER_NOT_EXISTS_ERROR);
  117. }
  118. else{
  119. //remove the specific player
  120. removeOnePlayer(player);
  121. }
  122. }
  123. }
  124. //remove one player
  125. private void removeOnePlayer(Player player){
  126. int playerNum ;
  127. //trying to find the player's index in the playerArray
  128. for(playerNum = 0; playerNum < playerTotalNum; playerNum++ ){
  129. if(player.equals(playerArray[playerNum]))
  130. break;
  131. }
  132. for(int i = playerNum; i < playerTotalNum - 1; i++){
  133. //move all the player one step forward to cover the removed player
  134. playerArray[i] = playerArray[i + 1];
  135. }
  136. //decrement the total player number with one
  137. playerTotalNum --;
  138. }
  139. //after confirmation, remove all the player in the array
  140. private void removeAllPlayers(){
  141. //reset the player manager to the initialized condition
  142. resetPlayerManager();
  143. }
  144. //edit one player with given family name and given name
  145. public void editPlayer(String userName, String familyName, String givenName){
  146. //trying to get the player instance first
  147. Player player = getPlayer(userName);
  148. if(player == NO_SUCH_PLAYER){
  149. //if no player found, print an error message
  150. System.out.println(PLAYER_NOT_EXISTS_ERROR);
  151. }
  152. else{
  153. //edit the players family name and given name
  154. player.setFamilyName(familyName);
  155. player.setGivenName(givenName);
  156. }
  157. }
  158. //reset the statistics of one or all players
  159. public void resetStats(String userName){
  160. if(userName == null){
  161. //ask the user if reset all players
  162. System.out.println(CONFIRM_RESET_ALL);
  163. String answer = TicTacToe.scanner.nextLine();
  164. if(answer.equals(CONFIRM_ANSWER)){
  165. //reset all player statistics after confirmation
  166. resetAllStats();
  167. }
  168. }
  169. else{
  170. //try get the player instance first
  171. Player player = getPlayer(userName);
  172. if( player == NO_SUCH_PLAYER){
  173. //if no player found, print an error message
  174. System.out.println(PLAYER_NOT_EXISTS_ERROR);
  175. }
  176. else{
  177. //reset statistics of specific player
  178. resetOneStats(player);
  179. }
  180. }
  181. }
  182. //reset statistics of all players
  183. private void resetAllStats(){
  184. for( int i = 0; i < playerTotalNum; i++ ){
  185. //reset every single player in this array
  186. resetOneStats(playerArray[i]);
  187. }
  188. }
  189. //reset the player statistics based on its index
  190. private void resetOneStats(Player player){
  191. //reset player statistics given its instance variable
  192. player.resetStats();
  193. }
  194. //display one or all player information with required format
  195. public void displayPlayer(String userName){
  196. if(userName == null){
  197. //if no username given, display all users
  198. displayAllPlayers();
  199. }
  200. else{
  201. //get the player instance first
  202. Player player = getPlayer(userName);
  203. if(player == NO_SUCH_PLAYER){
  204. //if no player found, print an error message
  205. System.out.println(PLAYER_NOT_EXISTS_ERROR);
  206. }
  207. else{
  208. //display the player according to its index in array
  209. displayOnePlayer(player);
  210. }
  211. }
  212. }
  213. //display all player information and statistics
  214. private void displayAllPlayers(){
  215. //create an array that contain all the players' usernames
  216. String[] userNames = new String[playerTotalNum];
  217. for(int i = 0; i < playerTotalNum; i++){
  218. //copy usernames of the array into the new String array
  219. userNames[i] = playerArray[i].getUserName();
  220. }
  221. //sort the array according to alphabetical sequence
  222. Arrays.sort(userNames);
  223. //print out all the player information alphabetically
  224. for(int i = 0; i< playerTotalNum; i++){
  225. Player player = getPlayer(userNames[i]);
  226. displayOnePlayer(player);
  227. }
  228. }
  229. //display information and statistics of one player given the index
  230. private void displayOnePlayer(Player player){
  231. System.out.println(player.toString());
  232. }
  233. //display the ranking of all the players
  234. public void displayRankings(){
  235. //first print the headers
  236. System.out.println(" WIN | DRAW | GAME | USERNAME");
  237. //sort the whole player array using defined comparison method
  238. Arrays.sort(playerArray, 0, playerTotalNum);
  239. //print out all the player game statistics
  240. for(int i = 0; i < playerTotalNum ; i++){
  241. //format the game statistics with required format
  242. formatResult(playerArray[i]);
  243. }
  244. }
  245. //format the game statistics of certain player
  246. private void formatResult(Player player){
  247. //print the winning ratio into XX% format
  248. System.out.printf(" %3d", Math.round(player.getWinningRatio()*100));
  249. System.out.print("% | ");
  250. //print the drawn ratio into XX% format
  251. System.out.printf("%3d", Math.round(player.getDrawnRatio()*100));
  252. System.out.print("% | ");
  253. //print the number of game played into XX format
  254. System.out.printf("%2d", player.getNumberOfGamePlayed());
  255. System.out.print(" | ");
  256. //print the username and start a new line
  257. System.out.print(player.getUserName());
  258. System.out.println();
  259. }
  260. //when a game finishes, store the game result into the player instance respectively
  261. public void storeGameResult(Player player1, Player player2, int resultStats){
  262. //change to statistics of two players
  263. switch (resultStats){
  264. case WIN:
  265. //player 1 wins player 2
  266. player1.win();
  267. player2.lose();
  268. break;
  269. case LOSE:
  270. //player 2 wins player 1
  271. player1.lose();
  272. player2.win();
  273. break;
  274. case DRAW:
  275. //the two players get drawn
  276. player1.draw();
  277. player2.draw();
  278. break;
  279. default:
  280. }
  281. }
  282. //this method restore all the information and statistics of players to a file
  283. public void recordPlayerStats(){
  284. PrintWriter outputStream = null;
  285. try{
  286. //try to open the file
  287. outputStream = new PrintWriter(new FileOutputStream(DATA_FILE));
  288. }
  289. catch (FileNotFoundException e){
  290. //if file cannot open, system terminates
  291. System.out.println(FILE_ERROR);
  292. System.exit(0);
  293. }
  294. //write the info and stats of every player to the local file
  295. for(int i = 0 ; i < playerTotalNum ; i++){
  296. outputStream.println(playerArray[i].getPlayerInfoStats());
  297. }
  298. outputStream.close();
  299. }
  300. //when system restart, import all the play info and stats into playManager
  301. private void resumePlayerStats(){
  302. Scanner inputStream = null;
  303. try{
  304. //try to open the file to write into
  305. inputStream = new Scanner(new FileInputStream(DATA_FILE));
  306. }
  307. catch (FileNotFoundException e){
  308. //if file cannnot open, give up resuming
  309. return ;
  310. }
  311. //import from file line by line
  312. while(inputStream.hasNextLine()){
  313. //parse the content of every line and add it to playerManager
  314. addPlayerFromRecord(inputStream.nextLine());
  315. }
  316. inputStream.close();
  317. }
  318. //add player to playerManager from the every single line
  319. private void addPlayerFromRecord(String record){
  320. StringTokenizer stOfRecord = new StringTokenizer(record);
  321. //get and split information from the String
  322. String userName = stOfRecord.nextToken();
  323. String familyName = stOfRecord.nextToken();
  324. String givenName = stOfRecord.nextToken();
  325. int numberOfGamePlayed = Integer.parseInt(stOfRecord.nextToken());
  326. int numberOfGameWon = Integer.parseInt(stOfRecord.nextToken());
  327. int numberOfGameDrawn = Integer.parseInt(stOfRecord.nextToken());
  328. //discard the "class" text
  329. stOfRecord.nextToken();
  330. //get the class type of the player
  331. String playerType = stOfRecord.nextToken();
  332. Player player = null;
  333. if(playerType.equals(AIPLAYER_TYPE)){
  334. //if the player is an aiplayer, load the information into an aiplayer class
  335. player = new AIPlayer(userName, familyName, givenName,
  336. numberOfGamePlayed, numberOfGameWon, numberOfGameDrawn);
  337. }
  338. else if(playerType.equals(HUMAN_PLAYER_TYPE)){
  339. //if the player is a human player, load the information into a humanplayer class
  340. player = new HumanPlayer(userName, familyName, givenName,
  341. numberOfGamePlayed, numberOfGameWon, numberOfGameDrawn);
  342. }
  343. else{
  344. //something wrong, system exit
  345. System.exit(-1);
  346. }
  347. //add this player to the player list
  348. addPlayer(player);
  349. }
  350. }