2

I am building a simple card game based on game called War. It works fine with two players, but I need it to be modified to work with any amount of players entered by the user in the beginning. I am having trouble figuring out how to keep track of both players and scores since I no longer have concrete variables to work with (can't create a variable for every possible player so players are added dynamically). I've hit a wall and can't figure out where to go from here.

Here is my main method:

System.out.println("Welcome to War! How many players are playing?"); //User prompt
    Scanner scanner = new Scanner(System.in); //Scanner init
    int numberOfPlayers = scanner.nextInt();//set number of players to next integer entered

    ArrayList<String> deck = createDeck(numberOfPlayers);

    ArrayList<String> playerNames = new ArrayList<String>();
    Map<String, Integer> players = new HashMap<String, Integer>();

    System.out.println("Enter player name");

    for (int p = 0; p <= numberOfPlayers; p++) {
        String playerID = scanner.next();
        addPlayer(playerID);
        players.put(playerID, 100);
        playerNames.add(playerID);
    }

        for (int j = createDeck(numberOfPlayers).size(); j > 0; j = j - numberOfPlayers) {  //j is set to deck length. Increment down two number each loop. 

            String readString = scanner.nextLine(); //Set variable "readString" to user input
            int score = 0;

            if (readString.equals("")) {    //If user input equals "enter"...

                ArrayList<Integer> currentScore = new ArrayList<Integer>();

                for (int q = 0; q <= numberOfPlayers; q++){

                    score = checkValue(deck);
                    String name = playerNames.get(q);
                    currentScore.add(score);
                    System.out.println(name +" drew a "+ deck.get(0) + " worth " + score + " points!"); //Print player 1's card


                    deck.remove(0); //Remove card
                    players.put(name, players.get(name).intValue() - score);
                }System.out.println(players.values());

            }
        }

This method checks the value of the card drawn and assigns a point value.

int currentScore = 0;

    boolean checkAce = deck.get(0).startsWith("Ace");
    boolean checkTwo = deck.get(0).startsWith("Two");
    boolean checkThree = deck.get(0).startsWith("Three");
    boolean checkFour = deck.get(0).startsWith("Four");
    boolean checkFive = deck.get(0).startsWith("Five");
    boolean checkSix = deck.get(0).startsWith("Six");
    boolean checkSeven = deck.get(0).startsWith("Seven");
    boolean checkEight = deck.get(0).startsWith("Eight");
    boolean checkNine = deck.get(0).startsWith("Nine");
    boolean checkTen = deck.get(0).startsWith("Ten");
    boolean checkJack = deck.get(0).startsWith("Jack");
    boolean checkQueen = deck.get(0).startsWith("Queen");
    boolean checkKing = deck.get(0).startsWith("King");


    if (checkAce) {
        currentScore = 14;
    }else if (checkTwo) {
        currentScore = 2;
    }else if (checkThree) {
        currentScore = 3;
    }else if (checkFour) {
        currentScore = 4;
    }else if (checkFive) {
        currentScore = 5;
    }else if (checkSix) {
        currentScore = 6;
    }else if (checkSeven) {
        currentScore = 7;
    }else if (checkEight) {
        currentScore = 8;
    }else if (checkNine) {
        currentScore = 9;
    }else if (checkTen) {
        currentScore = 10;
    }else if (checkJack) {
        currentScore = 11;
    }else if (checkQueen) {
        currentScore = 12;
    }else if (checkKing) {
        currentScore = 13;
    }


    return currentScore;

}

My main question is what is the best way to handle an unknown amount of multiple players in a way that would allow me to keep track of scores and declare winners. What I have so far prints me the names and how many points they get each round but I don't have a way to manipulate or compare the values with each other.

I used dictionary for the players to have the player key linked with the score value.

EDIT: Any solutions that do not include multiple classes are preferred.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
punygod
  • 197
  • 2
  • 17

1 Answers1

1

You can sort your Hashmap at the end of each round. Then you will printout the first element as a value. It's the simplest way to get the winner.

You can sort for example using:

public static <K,V extends Comparable<? super V>> 
            List<Entry<K, V>> entriesSortedByValues(Map<K,V> map) {

    List<Entry<K,V>> sortedEntries = new ArrayList<Entry<K,V>>(map.entrySet());

    Collections.sort(sortedEntries, 
            new Comparator<Entry<K,V>>() {
                @Override
                public int compare(Entry<K,V> e1, Entry<K,V> e2) {
                    return e2.getValue().compareTo(e1.getValue());
                }
            }
    );

    return sortedEntries;
}

then you will just call: entriesSortedByValues(players);

Example is from here: Sorting the Map<Key,Value> in descending order based on the value

UPDATE: You can store index for the best player in each round, by comparing score with best value, for example:

int best = 0, index = 0;
for (int q = 0; q <= numberOfPlayers; q++){
   score = checkValue(deck);
   if (best < score){
      index = q;
      best = score;
   }
   String name = playerNames.get(q);
   currentScore.add(score);
   System.out.println(name +" drew a "+ deck.get(0) + " worth " + score + " points!"); //Print player 1's card
   deck.remove(0); //Remove card
   players.put(name, players.get(name).intValue() - score);
   }
System.out.println("Best player in this round: " + playerNames.get(index);
Community
  • 1
  • 1
m.aibin
  • 3,528
  • 4
  • 28
  • 47
  • This looks like its getting me in the right direction. But when calling that method, I get a list of the keys in numerical order. Is there a way to then select the top one and preform actions based on its value? I need to add the winners score for the round to their total score and also subtract the other players score from their own total. – punygod Dec 21 '15 at 01:30
  • You can iterate over sorted HashMap, assigning scores per round from the top (first element) to the end (last element). And, I don't understand what you mean by I get a list of the keys in numerical order? You will receive sorted HashMap, with descending order. First element will be always the winner with above-mentioned method. – m.aibin Dec 21 '15 at 01:36
  • This method gives me the order of points based on overall points for each player (which is very helpful for another aspect of this project) but I also need to be able to get the order for each round. I tried to make an arrayList for the current score but I can not find equivalent methods that let me sort them and declare winners accurately. – punygod Dec 21 '15 at 01:40
  • you can simply store q parameter. I will edit the answer. – m.aibin Dec 21 '15 at 01:46
  • no, it should work fine, I am initialising best and index as a 0 each round -> int best = 0, index = 0; Please accept the answer ;) – m.aibin Dec 21 '15 at 01:57
  • Thank you! Sorry I didnt see the second edit. This works great. Thank you! – punygod Dec 21 '15 at 01:58
  • Sorry to bother @m.aibin but would you happen to know a way that would allow you to recognize ties while using this method? – punygod Dec 21 '15 at 02:10
  • tiles at the end? compare two first values after sorting. Tiles after round? Create additional boolean and change it when best=score. Then you should think what to do next ;) – m.aibin Dec 21 '15 at 02:14