Home > database >  Is there a better way to do this using an enum?
Is there a better way to do this using an enum?

Time:05-01

My code so far:

package com.company;


public class CardObject {

    public static final int LENGTH = 19; // aka amount of cards  KEEP THIS UPDATED!
    public static final int BEDROCK = 2;

    String name;
    String baseType;
    int attack;
    int health;
    String[] tags;
    String description;

    CardObject(int card) {
        transform(card);
    }

    public void transform(int card) { //  init("" new String[]{}); break; copypasta
        switch (card) { // I will need to make eventually that stuff is replaced (WOB = when on board, OF = on faint, SOT = start of turn, EOT = end of turn)
            case -1: break;
            case  0: init("Zombie",         "mob", 2, 6, new String[]{"undead"}, "WOB: can Wield tools and weapons"); break;
            case  1: init("Lava Bucket",  "spell", 0, 0, new String[]{}, "Give an enemy Burning 3 for 4 turns"); break;
            case  2: init("Bedrock",      "block", 1, 3, new String[]{}, "Immune. Unbuffable. WOB: make allies on either side Immune"); break;
            case  3: init("Creeper",        "mob", 6, 1, new String[]{}, "Thorns 6. Recoil."); break;
            case  4: init("Spider",         "mob", 2, 5, new String[]{}, "WOB: can Combine with Skeleton to Transform into Spider Jockey"); break;
            case  5: init("Skeleton",       "mob", 3, 6, new String[]{}, "OF: Gain Arrow"); break;
            case  6: init("Spider Jockey",  "mob", 2, 5, new String[]{}, "Double Attack. OF: Summon Skeleton"); break;
            case  7: init("Baby Zombie",    "mob", 3, 8, new String[]{}, "Fire Resistance."); break;
            case  8: init("The Sun",      "spell", 0, 0, new String[]{}, "Give all enemy undead mobs burning for 6 turns"); break;
            case  9: init("Lava Bucket",  "spell", 0, 0, new String[]{}, "Give an enemy burning 3 for 4 turns"); break;
            case 10: init("Water Bucket",  "item", 0, 6, new String[]{}, "SOT: remove burning from allies"); break;
            case 11: init("Dispenser",    "block", 0, 6, new String[]{}, "WOB: projectiles cost 1 or are free not sure"); break;
            case 12: init("Arrow",        "spell", 0, 0, new String[]{}, "deal 2 damage"); break;
            case 13: init("Air Block",    "block", 0, 1, new String[]{"unobtainable"}, ""); break;
            case 14: init("Air",          "spell", 0, 0, new String[]{}, "Summon Air for the enemy"); break;
            case 15: init("Bow",           "item", 0, 5, new String[]{}, "WOB: Arrows deal 2x damage. OB: gain 2 arrows"); break;
            case 16: init("Crossbow",      "item", 0, 5, new String[]{}, "WOB: Arrows deal 3x damage once per turn. OB: gain 2 arrows"); break;
            case 17: init("Dropper",      "block", 0, 6, new String[]{"powerable"}, "SOT: optionally play a random card in your hand at a discount"); break;
            case 18: init("Bamboo Shoot", "block", 0, 4, new String[]{}, "EOT: Summon Bamboo"); break;
            case 19: init("Bamboo",       "block", 0, 3, new String[]{"unobtainable"}, "EOT: for every bamboo shoot Summon a 0/2 Bamboo"); break;
            case 20:
            case 21:
            case 22:
            case 23:
            case 24:
            case 25:
            case 26:
        }
    }

    private void init(String n, String bt, int a, int h, String[] t, String d) {
        this.name = n;
        this.baseType = bt;
        this.attack = a;
        this.health = h;
        this.tags = t;
        this.description = d;
    }
}

What I'm pretty sure I'll need later is to be able to find, and create an object based on their name (for stuff like "OF: Summon Skeleton"), and to be able to make card objects. So I'm wondering if using an enum would make this a lot simpler, and how I would use an enum in that way. Also if anyone knows a better way to input a list (what I'm using now: new String[]{"undead"}) than please answer me that too.

CodePudding user response:

You could indeed make CardObject an enum, then you can avoid the giant switch. The main change is making init the constructor instead.

To write the tags more conveniently, you can move the t parameter to the final position, so that you can make it a variable arity parameter String... t, then you can easily pass a list of tags.

enum Card {

    // note the way that the "undead" tag is being passed
    ZOMBIE("Zombie", "mob", 2, 6, "WOB: can Wield tools and weapons", "undead"),
    LAVA_BUCKET("Lava Bucket",  "spell", 0, 0, "Give an enemy Burning 3 for 4 turns"),
    // other cards go here...
    ;

    // add getters for these fields...
    private String name;
    private String baseType; // consider using an enum for the baseType too
    private int attack;
    private int health;
    private String[] tags;
    private String description;

    Card(String n, String bt, int a, int h, String d, String... t) {
        this.name = n;
        this.baseType = bt;
        this.attack = a;
        this.health = h;
        this.tags = t;
        this.description = d;
    }
}

To make a Card, simply use one of the names, such as Card.ZOMBIE. If you have an index number, you can do Card.values(someIndex). This would produce the same card as calling new CardObject(someIndex) with your old code.

The LENGTH constant is not needed, as you can access how many cards there is via Card.values().length.

  • Related