如何创建一个;抽奖池;在java中使用枚举的分幅

如何创建一个;抽奖池;在java中使用枚举的分幅,java,enums,Java,Enums,我想通过制作一个应用程序来了解enums在Java中是如何工作的,这个应用程序有一个“可绘制的瓷砖”池,可以转移到“玩家的手”上。我正在为这个概念挣扎,有人能帮忙吗 如果我有一个像下面这样的枚举,我如何使用它使其具有每个值的4个副本,使其总共有136个“分片”?我想用那些“136块瓷砖”作为一个可耗尽的池,这样用户就可以从中绘制,并将他绘制的“瓷砖”放入自己的“手”(我猜也是一个枚举?) 问题: 我曾经使用一个普通的字符串列表来实现这个特性,但是我发现了一个开源的lib() 我想用。我应该如何处

我想通过制作一个应用程序来了解enums在Java中是如何工作的,这个应用程序有一个“可绘制的瓷砖”池,可以转移到“玩家的手”上。我正在为这个概念挣扎,有人能帮忙吗

如果我有一个像下面这样的枚举,我如何使用它使其具有每个值的4个副本,使其总共有136个“分片”?我想用那些“136块瓷砖”作为一个可耗尽的池,这样用户就可以从中绘制,并将他绘制的“瓷砖”放入自己的“手”(我猜也是一个枚举?)

问题: 我曾经使用一个普通的字符串列表来实现这个特性,但是我发现了一个开源的lib() 我想用。我应该如何处理这个问题?我应该创建两个新的枚举吗?一个包含每个牌的4个副本,一个用于该玩家的手?然后像列表一样从一个转移到另一个

这是枚举

public enum Tile {
    M1(0, MANZU, 1),
    M2(1, MANZU, 2),
    M3(2, MANZU, 3),
    M4(3, MANZU, 4),
    M5(4, MANZU, 5),
    M6(5, MANZU, 6),
    M7(6, MANZU, 7),
    M8(7, MANZU, 8),
    M9(8, MANZU, 9),

    P1(9, PINZU, 1),
    P2(10, PINZU, 2),
    P3(11, PINZU, 3),
    P4(12, PINZU, 4),
    P5(13, PINZU, 5),
    P6(14, PINZU, 6),
    P7(15, PINZU, 7),
    P8(16, PINZU, 8),
    P9(17, PINZU, 9),

    S1(18, SOHZU, 1),
    S2(19, SOHZU, 2),
    S3(20, SOHZU, 3),
    S4(21, SOHZU, 4),
    S5(22, SOHZU, 5),
    S6(23, SOHZU, 6),
    S7(24, SOHZU, 7),
    S8(25, SOHZU, 8),
    S9(26, SOHZU, 9),

    TON(27, FONPAI, 0),//東
    NAN(28, FONPAI, 0),//南
    SHA(29, FONPAI, 0),//西
    PEI(30, FONPAI, 0),//北

    HAK(31, SANGEN, 0),//白
    HAT(32, SANGEN, 0),//発
    CHN(33, SANGEN, 0);//中

    private int code;
    private TileType type;
    private int number;

    Tile(int code, TileType type, int number) {
        this.code = code;
        this.type = type;
        this.number = number;
    }

我怀疑你误解了Enum的目的。它们只是一个具有固定对象集的类。您可以使用普通类实现完全相同的功能,这通常是一个更好的选择

首先,一旦您有了一组可能的分片,所有分片的堆栈或组绝对不应该是枚举。相反,它应该是一个
列表
(或其他允许重复的集合)。这样你就可以洗牌,交易等等

其次,您的枚举名实际上嵌入了两条信息——类型和编号。这通常是一个迹象,表明你最好把它们分开

如果使用
enum
的目的是允许特定分幅的特殊情况,那么您可以通过让enum实现一个接口来组合这种方法

这里有一个潜在的替代设计供您考虑:

enum TileType { ... };

interface Tile {
    String getName();
    int getCode();
    TileType getType();
}

class StandardTile implements Tile {
    ...
}

enum FonpaiTile implements Tile {
    TON, NAN, SHA, PEI;
    public TileType getType() { return TileType.FONPAI; }
}

enum SangenTile implements Tile {
    HAK, HAT, CHN;
    public TileType getType() { return TileType.SANGEN; }
}

class TileSet {
    private final Set<Tile> tiles = new HashSet<>();
    private int id = 0;
    public TileSet() {
        // create all the standard and special tiles and add to set
    }
}

class Pool {
    private final List<Tile> tiles = new ArrayList<>();

    public Pool() {
        TileSet tileSet = new TileSet();
        for (int i = 0; i < 4; i++)
            tiles.addAll(tileSet);
        ...
        Collections.shuffle(tiles);
    }

    public Tile takeTile() {
        return tiles.remove(0);
    }

    public boolean isEmpty() {
        return tiles.isEmpty();
    }
}
enum TileType{…};
界面砖{
字符串getName();
int getCode();
TileType getType();
}
类StandardTile实现了平铺{
...
}
enum FonpaiTile实现平铺{
东,南,沙,佩,;
public TileType getType(){return TileType.FONPAI;}
}
enum SangenTile实现平铺{
哈特,中国;
public TileType getType(){return TileType.SANGEN;}
}
类平铺集{
私有最终集tiles=new HashSet();
私有int id=0;
公共瓷砖集(){
//创建所有标准和特殊瓷砖并添加到集合
}
}
班级池{
私有最终列表平铺=新的ArrayList();
公共泳池(){
TileSet TileSet=新TileSet();
对于(int i=0;i<4;i++)
tiles.addAll(tileSet);
...
收藏。洗牌(瓷砖);
}
公共瓷砖takeTile(){
返回瓷砖。移除(0);
}
公共布尔值为空(){
返回tiles.isEmpty();
}
}

这样,您仍然可以使用诸如
tile==SangenTile.CHN之类的条件来在必要时使用特殊条件进行编码。

我喜欢您的解释,这非常有帮助。事实上,这个话题让我有点纠结(还是有点纠结)。一开始我想用一个列表,我做到了。但看到@mahjong4j这些人正在使用enum定义他们最初的“tile”,我很感兴趣。我是说。该库用于麻将游戏,包含34个值的枚举在始终需要初始34个值的4个副本的游戏中(抽签池)自身不可能有用。所以,我真的想知道他们为什么选择这个。你能想出什么理由吗?我觉得如果不理解这一点,我就无法继续前进。使用枚举是一个有效的选择——它满足了一个类的固定对象集的标准用例。他们可能正在使用枚举,因为他们在代码的其他地方有关于单个分幅(而不是分幅类型)的特殊情况。因此,他们希望与枚举成员进行比较,而不是字符串比较。这很有道理。事实上,您可以组合这些方法,因为枚举可以实现接口。为了你的兴趣,我会在我的回答中举一个例子。非常有趣。我已经把你的初步答复记为对我问题的回答。感谢您进一步编辑。这会让我忙上一段时间,但我现在能够更清晰地深入这个话题。