I am implementing a simple version of the Cluedo game. There are 3 types of cards in the game, Character, Weapon and Room. Since one card is nothing more than a String (ie no functionality or information other than the name is stored in a card), I chose not to have a Card interface and each type extends Card. Rather I had three enums in my game which are:
public enum Character {Scarlett, Mustard, White, Green, Peacock, Plum;}
public enum Weapon {Candlestick, Dagger, LeadPipe, Revolver, Rope, Spanner;}
public enum Room {Kitchen, Ballroom, Conservatory, BilliardRoom, Library, Study, Hall;}
However there is one case where three types of cards are put together and dealt evenly to each player of the game. For example, one player may have a hand of 2 Characters, 2 Weapons and 1 Room, another player may have 3 Rooms and 2 Characters, so long the total number of cards are even it doesn't matter what type that is.
And that's why I wonder if there is a way to randomly choose one single value from all three enums in Java?
Or I shouldn't do this three enums thing in the first place? (Badly designed)
A simple way is to collect all the enum members into a single Object[]
, then take a random element from it.
Note that an enum can also implement an interface, so you can even have some shared API across all the enums. Typically you'll find yourself writing a lot of switch
statements on the value of the enum; those can mostly be replaced by dynamic dispatch against such interface methods. Further note that each enum member can provide its own method implementation.
I think you should keep it like it is, but then put them all in the same list:
List<Enum> enums = new ArrayList<>();
enums.addAll(Arrays.asList(Character.values()));
enums.addAll(Arrays.asList(Weapon.values()));
enums.addAll(Arrays.asList(Room.values()));
And then you take random values of that list. More closely resembles what you do in real life.
You can write something like this:
public enum Character {Scarlett, Mustard, White, Green, Peacock, Plum;}
public enum Weapon {Candlestick, Dagger, LeadPipe, Revolver, Rope, Spanner;}
public enum Room {Kitchen, Ballroom, Conservatory, BilliardRoom, Library, Study, Hall;}
private static final Random RANDOM = new Random(); // random number generator - declared static, because we need only one for whole program
private static final int TOTAL_CARDS = Character.values().length + Weapon.values().length + Room.values().length; // sum up all enum lenghts - in this case, it will be 6 + 6 + 7 = 19
private Enum<?> getRandomCard() {
int randomNumber = RANDOM.nextInt(TOTAL_CARDS); // we "roll a dice" to get some random number. Let's assume that we get "15"
if (randomNumber < Character.values().length) { // is 15 less then 6? No, so we skip this part
return Character.values()[randomNumber];
}
randomNumber -= Character.values().length; // randomNumber = 15 - 6 = 9
if (randomNumber < Weapon.values().length) { // is 9 < 6 ? No, so we skip this
return Weapon.values()[randomNumber];
}
randomNumber -= Weapon.values().length; // randomNumber = 9 - 6 = 3
if (randomNumber < Room.values().length) { // Is 3 < 7 ? Yes!
// so it means that our "dice" has chosen a Room with array index 3
// We call Room.values() to get all room types as an array and then we pick one with index 3
return Room.values()[randomNumber];
}
return null; // should never happen
}
If you don't understand any part of this, please let me know - I'll add some comments.
However, I believe that solution proposed by Oskar Kjellin is far more elegant then this one :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.