fork download
  1. import java.util.ArrayList;
  2. import java.util.Arrays;
  3. import java.util.Random;
  4.  
  5. class GameSimulator {
  6. public static void main(String[] args) {
  7. int playerCount = Integer.parseInt(args[0]); //100K
  8. int gameCount = Integer.parseInt(args[1]); //1M
  9. GameSimulator simulator = new GameSimulator(playerCount, gameCount);
  10. }
  11.  
  12. final int playerCount;
  13. final int gameCount;
  14. final Player[] playerList;
  15. ArrayList<Player> game;
  16. int gameFavorsWinner = 0;
  17. double imbalance = 0;
  18. double upsetImbalance = 0;
  19. double upsetTeamOne = 0;
  20. double upsetTeamTwo = 0;
  21.  
  22. public GameSimulator(int playerCount, int gameCount) {
  23. this.playerCount = playerCount;
  24. this.gameCount = gameCount;
  25.  
  26. playerList = new Player[playerCount];
  27. Random random = new Random();
  28.  
  29. for(int currentGame = 0; currentGame < gameCount; currentGame++) {
  30. game = new ArrayList<Player>();
  31. while(game.size() < 24) {
  32. //create a game of 24 players with no duplicates
  33. int playerId = random.nextInt(playerCount);
  34. if(!game.contains(getPlayer(playerId))) {
  35. game.add(getPlayer(playerId));
  36. }
  37. }
  38.  
  39. if(saveMatch()) {
  40. gameFavorsWinner++;
  41. }
  42. }
  43. //Print the distribution
  44. printWinLossBuckets();
  45. }
  46.  
  47. public void printWinLossBuckets() {
  48. //Get everyone's W/L
  49. final double[] winLoss = new double[playerCount];
  50. for(int i = 0; i < playerCount; i++) {
  51. getPlayer(i); //instantiate null players
  52. winLoss[i] = playerList[i].getWinRate(); //get win rate
  53. }
  54. Arrays.sort(winLoss);
  55. int bucketBracket = 0;
  56. int bucketCount = 0;
  57. double totalWinRate = 0;
  58. int totalGamesPlayed = 0;
  59. int mostGamesPlayed = 0;
  60.  
  61. for(int i = 0; i < playerCount; i++) {
  62. totalWinRate += winLoss[i]; //calculate average WR
  63. totalGamesPlayed += playerList[i].gamesPlayed; // calculate average games
  64. mostGamesPlayed = mostGamesPlayed < playerList[i].gamesPlayed ? playerList[i].gamesPlayed : mostGamesPlayed;
  65. while(winLoss[i] > bucketBracket) {
  66. if(bucketCount > 0) {
  67. System.out.println(bucketBracket + "\t" + bucketCount);
  68. }
  69. bucketBracket+=2;
  70. bucketCount = 0;
  71. }
  72. bucketCount++;
  73. }
  74. System.out.println("Average WR: " + (totalWinRate / (double) playerCount));
  75. System.out.println("Favored Team Victory: " + (gameFavorsWinner/ (double) gameCount * 100d));
  76. System.out.println("Average Imbalance: " + (imbalance/ (double) gameCount));
  77. System.out.println("Biggest Upset: " + upsetTeamOne + " vs " + upsetTeamTwo);
  78. System.out.println("Average Games Played: " + (totalGamesPlayed / (double) playerCount));
  79. System.out.println("Most Games Played by One Player: " + mostGamesPlayed);
  80. }
  81.  
  82. private boolean saveMatch() {
  83. double teamOneSkill = 0;
  84. double teamTwoSkill = 0;
  85. for(int i = 0; i < 12; i++) {
  86. teamOneSkill+= game.get(i).skillLevel;
  87. }
  88. for(int i = 12; i < 24; i++) {
  89. teamTwoSkill+= game.get(i).skillLevel;
  90. }
  91.  
  92. final double chanceToWin = teamOneSkill / (teamOneSkill + teamTwoSkill);
  93. Random random = new Random();
  94. boolean firstTeamWins = random.nextDouble() < chanceToWin;
  95. boolean firstTeamFavored = teamOneSkill >= teamTwoSkill;
  96.  
  97. double matchImbalance = Math.abs(teamOneSkill - teamTwoSkill);
  98.  
  99. imbalance += matchImbalance;
  100.  
  101. for(int i = 0; i < 12; i++) {
  102. game.get(i).playedGame(firstTeamWins);
  103. }
  104. for(int i = 12; i < 24; i++) {
  105. game.get(i).playedGame(!firstTeamWins);
  106. }
  107.  
  108. if((firstTeamWins && firstTeamFavored) || (!firstTeamWins && !firstTeamFavored)) {
  109. return true;
  110. }
  111. if(upsetImbalance < matchImbalance) {
  112. upsetImbalance = matchImbalance;
  113. upsetTeamOne = teamOneSkill;
  114. upsetTeamTwo = teamTwoSkill;
  115. }
  116. return false;
  117. }
  118.  
  119. private void saveMatch(boolean firstTeamWins) {
  120. for(int i = 0; i < 12; i++) {
  121. game.get(i).playedGame(firstTeamWins);
  122. }
  123. for(int i = 12; i < 24; i++) {
  124. game.get(i).playedGame(!firstTeamWins);
  125. }
  126. }
  127.  
  128. public Player getPlayer(int id) {
  129. if(playerList[id] == null) {
  130. playerList[id] = new Player();
  131. }
  132. return playerList[id];
  133. }
  134.  
  135.  
  136. class Player {
  137. int gamesWon = 0;
  138. int gamesPlayed = 0;
  139. final double skillLevel;
  140. public Player() {
  141. Random random = new Random();
  142. skillLevel = random.nextDouble();
  143. }
  144. void lostGame() {
  145. gamesPlayed++;
  146. }
  147. void wonGame() {
  148. gamesPlayed++;
  149. gamesWon++;
  150. }
  151. void playedGame(boolean won) {
  152. if(won)
  153. wonGame();
  154. else
  155. lostGame();
  156. }
  157. double getWinRate() {
  158. return (double) gamesWon / (double) gamesPlayed * (double) 100;
  159. }
  160. }
  161. }
  162.  
Runtime error #stdin #stdout #stderr 0.11s 320576KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
	at GameSimulator.main(Main.java:7)