Solved HashMap is null when splitting arraylist into 1 - 4 equal teams

Discussion in 'Plugin Development' started by callum2904, Apr 8, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    callum2904

    I am creating a plugin for fun and educational purpose and i cannot figure out how i could split a list of players in the arena to a set amount of groups which can be 1 - 4.

    I use this code to check what color groups there will be
    Code:java
    1. public ArrayList<ArenaTeam> getTeams(String arenaName){
    2. Arena arena = getArena(arenaName);
    3.  
    4. ArrayList<ArenaTeam> teams = new ArrayList<ArenaTeam>();
    5.  
    6. teams.clear();
    7.  
    8. if(arena.teamCount() == 0 || arena.teamCount() == 1){
    9. teams.add(ArenaTeam.BLUE);
    10. }else if(arena.teamCount() == 2){
    11. teams.add(ArenaTeam.BLUE);
    12. teams.add(ArenaTeam.RED);
    13. }else if(arena.teamCount() == 3){
    14. teams.add(ArenaTeam.BLUE);
    15. teams.add(ArenaTeam.RED);
    16. teams.add(ArenaTeam.GREEN);
    17. }else if(arena.teamCount() == 2){
    18. teams.add(ArenaTeam.BLUE);
    19. teams.add(ArenaTeam.RED);
    20. teams.add(ArenaTeam.GREEN);
    21. teams.add(ArenaTeam.YELLOW);
    22. }
    23.  
    24. return teams;
    25. }
    26.  
    27. public void setTeams(String arenaName){
    28. Config config = new Config("", "Arenas");
    29. Arena arena = getArena(arenaName);
    30. if(arena !=null){
    31.  
    32. }
    33. }


    And this is the arena class that will handle where the groups and things are stored

    Code:java
    1. import java.util.ArrayList;
    2. import java.util.HashMap;
    3.  
    4. import org.bukkit.Bukkit;
    5. import org.bukkit.Location;
    6.  
    7. public class Arena {
    8.  
    9. public static ArrayList<Arena> arenaObjects = new ArrayList<Arena>();
    10. public static HashMap<ArenaTeam, String> team = new HashMap<ArenaTeam, String>();
    11.  
    12. private ArrayList<String> players = new ArrayList<String>();
    13.  
    14.  
    15. private Location start, lobby;
    16. private String name;
    17. private int maxPlayers, maxMobs, teams;
    18. private boolean inGame;
    19.  
    20. public Arena(String arenaName) {
    21.  
    22. this.name = arenaName;
    23.  
    24. arenaObjects.add(this);
    25.  
    26. }
    27.  
    28. public int teamCount(){
    29. return this.teams;
    30. }
    31.  
    32. public void setTeams(int amount){
    33. this.teams = amount;
    34. }
    35.  
    36. public void setLobbyLocation(Location lobby){
    37. this.lobby = lobby;
    38. }
    39.  
    40. public Location getLobbyLocation(){
    41. return this.lobby;
    42. }
    43.  
    44. public void setInGame(boolean bool){
    45. this.inGame = bool;
    46. }
    47.  
    48. public boolean getInGame(){
    49. return this.inGame;
    50. }
    51.  
    52. public Location getStartLocation() {
    53. return this.start;
    54. }
    55.  
    56. public void setStartLocation(Location start) {
    57. this.start = start;
    58. }
    59.  
    60. public String getName() {
    61. return this.name;
    62. }
    63.  
    64. public void setName(String name) {
    65. this.name = name;
    66. }
    67.  
    68. public int getMaxPlayers() {
    69. return this.maxPlayers;
    70. }
    71.  
    72. public void setMaxPlayers(int maxPlayers) {
    73. this.maxPlayers = maxPlayers;
    74. }
    75.  
    76. public int getMaxMobs(){
    77. return this.maxMobs;
    78. }
    79.  
    80. public void setMaxMobs(int max){
    81. this.maxMobs = max;
    82. }
    83.  
    84. public ArrayList<String> getPlayers() {
    85. return this.players;
    86. }
    87.  
    88. public int playerCount(){
    89. return this.players.size();
    90. }
    91.  
    92. public boolean isFull() {
    93. if (players.size() >= maxPlayers) {
    94. return true;
    95. } else {
    96. return false;
    97. }
    98. }
    99.  
    100. public void sendMessage(String message) {
    101. for (String s : players) {
    102. Bukkit.getPlayer(s).sendMessage(message);
    103. }
    104. }
    105.  
    106. }


    Example
    if arena 1 has 2 teams the code i need help with will randomly split the players list for that arena into 2 groups which isnt too hard

    if arena 2 has 3 teams the code i need help with will randomly split the players list for that arena into 3 teams which is a bit more difficult

    but finally if i want the code i need help with will do the same as above but into 4.

    I need this to do it with some kind of algorithm or something to check how many groups there is and then split them up accordingly and then set them to the hashmap as show at the top of the arena class.

    I hope you get what im trying to say i try to explain in too much detail and sometimes go off track and make it hard to understand.



    Finally, if you need any other classes ask.
     
  2. Offline

    xXSniperzzXx_SD

    callum2904
    I'm currently on my phone so I can't see the code, but to make teams even just loop through all the players checking how many players are in each team, then depending on that you can figure out where to add the player
     
  3. Offline

    callum2904


    I know, thats what i tried and then i messed up so i tried again and i did it about 3 different ways which all didnt work this morning so i thought id ask for help instead of giving up on my challenge.
     
  4. Offline

    xXSniperzzXx_SD

    callum2904

    If you goto github.SniperzCiinema.com
    Then go into crankeds code and look at the arena class I believed I have a addtoteam function that does what you're looking for
     
  5. Offline

    callum2904

    unfortunately this only works for 2 teams and i have no clue how i could make that work with 1, 2, 3 or 4 teams which is what i need. That code is slightly like the code i first had.
     
  6. Offline

    xXSniperzzXx_SD

    callum2904
    You should be able to just add a third.(Just wrote by hand)
    Code:java
    1. int i = 1;
    2. for(Player player : listOfPlayers){
    3. switch(i){
    4. case 1:
    5. addToList1(player);
    6. break;
    7. case 2:
    8. addToList1(player);
    9. break;
    10. case 3:
    11. addToList1(player);
    12. break;
    13. }
    14. i++;
    15. if(i == 4)
    16. i = 0;
    17. }
     
  7. Offline

    skyrimfan1

    Code:java
    1. public List<List<E>> splitList(List<E> list, int times) {
    2. int size = list.size();
    3. if (times < 2) {
    4. List<List<E>> theChosenOne = new ArrayList<List<E>>(1);
    5. theChosenOne.add(list);
    6. return theChosenOne;
    7. }
    8. else if (times == 2) {
    9. List<E> one = list.subList(0, size / 2);
    10. List<E> two = list.subList(size / 2);
    11. List<List<E>> total = new ArrayList<List<E>>(2);
    12. total.add(one);
    13. total.add(two);
    14. return total;
    15. }
    16. else if (times == 3) {
    17. List<E> one = list.subList(0, size / 3);
    18. List<E> two = list.subList(size / 3, size * 2 / 3);
    19. List<E> three = list.subList(size * 2 / 3);
    20. List<List<E>> total = new ArrayList<List<E>>(3);
    21. total.add(one);
    22. total.add(two);
    23. total.add(three);
    24. return total;
    25. }
    26. else {
    27. throw new IllegalArgumentException("Divisor amount is over 3: "+times);
    28. }


    The method suggested by xXSniperzzXx_SD will also work if you want to sort out a list (think of a card dealer dealing out cards). Mine will keep the same list order but split it into (divisor) subsections and won't work over three (still thinking about an algorithm that simplifies case-by-case input).
     
  8. Offline

    callum2904

    skyrimfan1 @xXSniperzzXx_SD
    Code:java
    1. public static List<List<Object>> createBatch(List<Object> originalList, int chunkSize) {
    2. List<List<Object>> listOfChunks = new ArrayList<List<Object>>();
    3. for (int i = 0; i < originalList.size() / chunkSize; i++) {
    4. listOfChunks.add(originalList.subList(i * chunkSize, i * chunkSize
    5. + chunkSize));
    6. }
    7. if (originalList.size() % chunkSize != 0) {
    8. listOfChunks.add(originalList.subList(originalList.size()
    9. - originalList.size() % chunkSize, originalList.size()));
    10. }
    11. return listOfChunks;
    12. }


    i found this and have tried playing around with it but i dont know how to check what team it would be eg if it was split into 2 groups it would be blue and red. 3 groups... blue red green (i need this so that i can add it to my hashmap)

    any suggestions?
     
  9. Offline

    skyrimfan1

    callum2904
    This looks like the algorithm I was looking for :p ... although I would recommend using List<E> (changeable element) instead of List<Object> which is more generic.

    As for the HashMap dilemma, I have provided a possible solution. You'd need to reference the given teams you want to use and the list of lists of players (lol):

    Code:
    public HashMap<ArenaTeam, List<String>> getFormattedTeams(List<ArenaTeam> teams, List<List<String>> players) {
        HashMap<ArenaTeam, List<String>> map = new HashMap<ArenaTeam, List<String>>(players.size());
        for (int i = 0; i < players.size(); i++) {
              ArenaTeam team = teams.get(i);
              List<String> subPlayers = players.get(i);
              map.put(team, subPlayers);
        }
        return map;
    }
    
    Do note that I am using Strings in the players list rather than the Player objects themselves. Storing Player objects in collections, while convenient, can create memory leaks by creating two Player objects representing the same user. To avoid this, I stored player names in the list rather than the instances. To transfer from the player's name to his/her corresponding instance, you could simply use: Bukkit.getPlayerExact(String name);
     
  10. Offline

    callum2904



    I am now using this which creates no errors but doesnt seem to set the hashmap in the arena class

    Code:java
    1. public ArrayList<ArenaTeam> getTeams(String arenaName){
    2. Arena arena = getArena(arenaName);
    3.  
    4. ArrayList<ArenaTeam> teams = new ArrayList<ArenaTeam>();
    5.  
    6. if(arena.teamCount() == 0 || arena.teamCount() == 1){
    7. teams.add(ArenaTeam.BLUE);
    8. }else if(arena.teamCount() == 2){
    9. teams.add(ArenaTeam.BLUE);
    10. teams.add(ArenaTeam.RED);
    11. }else if(arena.teamCount() == 3){
    12. teams.add(ArenaTeam.BLUE);
    13. teams.add(ArenaTeam.RED);
    14. teams.add(ArenaTeam.GREEN);
    15. }else if(arena.teamCount() == 4){
    16. teams.add(ArenaTeam.BLUE);
    17. teams.add(ArenaTeam.RED);
    18. teams.add(ArenaTeam.GREEN);
    19. teams.add(ArenaTeam.YELLOW);
    20. }
    21.  
    22. return teams;
    23. }
    24.  
    25. public HashMap<ArenaTeam, List<String>> getFormattedTeams(List<ArenaTeam> teams, List<List<String>> players) {
    26. HashMap<ArenaTeam, List<String>> map = new HashMap<ArenaTeam, List<String>>(players.size());
    27. for (int i = 0; i < players.size(); i++) {
    28. ArenaTeam team = teams.get(i);
    29. List<String> subPlayers = players.get(i);
    30. map.put(team, subPlayers);
    31. }
    32. return map;
    33. }
    34.  
    35. public static List<List<String>> createBatch(List<String> originalList, int chunkSize) {
    36. List<List<String>> listOfChunks = new ArrayList<List<String>>();
    37. for (int i = 0; i < originalList.size() / chunkSize; i++) {
    38. listOfChunks.add(originalList.subList(i * chunkSize, i * chunkSize
    39. + chunkSize));
    40. }
    41. if (originalList.size() % chunkSize != 0) {
    42. listOfChunks.add(originalList.subList(originalList.size()
    43. - originalList.size() % chunkSize, originalList.size()));
    44. }
    45. return listOfChunks;
    46. }
    47.  
    48. public void setTeams(String arenaName){
    49. Arena arena = getArena(arenaName);
    50. if(arena !=null){
    51. arena.team = getFormattedTeams(getTeams(arenaName), createBatch(arena.getPlayers(), getTeams(arenaName).size()));
    52. printlnfx(ChatColor.BLUE + Arrays.asList(arena.team.get(ArenaTeam.BLUE)).toString());
    53. printlnfx(ChatColor.RED + Arrays.asList(arena.team.get(ArenaTeam.RED)).toString());
    54. printlnfx(ChatColor.GREEN + Arrays.asList(arena.team.get(ArenaTeam.GREEN)).toString());
    55. printlnfx(ChatColor.YELLOW + Arrays.asList(arena.team.get(ArenaTeam.YELLOW)).toString());
    56.  
    57. }
    58. }


    the console returns [null] 4 times in each color set above

    Thank you everyone for your help the last problems was my fault. The player list was null...

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 7, 2016
Thread Status:
Not open for further replies.

Share This Page