Java从3个不同的枚举中获取随机值

5

我正在实现一个Cluedo游戏的简单版本。 游戏中有三种类型的卡片,分别是角色、武器和房间。由于一张卡片仅仅是一个字符串(即除了名称之外没有任何功能或信息存储在卡片中),我选择不使用Card接口,而是让每种类型都继承Card。我在我的游戏中使用了三个枚举,它们是:

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;}

然而,有一种情况是将三种类型的卡牌放在一起,并平均发给游戏中的每个玩家。例如,一个玩家可能有2张角色卡、2张武器卡和1张房间卡,另一个玩家可能有3张房间卡和2张角色卡,只要卡牌的总数是偶数,不管是什么类型都没关系。
这就是为什么我想知道是否有一种方法可以从Java的所有三个枚举中随机选择一个单一的值?
或者我一开始就不应该使用这三个枚举?(设计得不好)
3个回答

5
一个简单的方法是将所有枚举成员收集到一个单独的Object[]中,然后从中选择一个随机元素。
请注意,枚举也可以实现接口,因此您甚至可以在所有枚举之间共享一些API。通常,您会发现自己编写了很多基于枚举值的switch语句;这些语句大部分可以通过针对此类接口方法进行动态调度来替换。进一步注意,每个枚举成员可以提供其自己的方法实现。

枚举也可以实现一个接口。这对我很有帮助!原来我确实需要一个Card接口!非常感谢! - Shenbo

2
我认为你应该保持现状,但将它们全部放在同一个列表中:
List<Enum> enums = new ArrayList<>();
enums.addAll(Arrays.asList(Character.values()));
enums.addAll(Arrays.asList(Weapon.values()));
enums.addAll(Arrays.asList(Room.values()));

然后您从该列表中随机取值,更贴近实际生活中的操作。


1
你可以写出类似这样的内容:
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
}

如果您不理解任何部分,请告诉我 - 我会添加一些注释。
然而,我相信Oskar Kjellin提出的解决方案比这个更优雅 :)

这可能是一个有用的答案。但是,仅仅尝试这段代码的回答对其他读者来说并不有帮助。相反,您应该添加一个最小的代码描述,这将有助于其他未来的读者。 ;) - Lucky
@Lucky 我扩展了我的回答 :) - Greg Witczak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接