mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
ColorSet: turn Set into an Enum (#8757)
This commit is contained in:
@@ -17,14 +17,12 @@
|
||||
*/
|
||||
package forge.card;
|
||||
|
||||
import com.google.common.collect.UnmodifiableIterator;
|
||||
import forge.card.MagicColor.Color;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.util.BinaryUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@@ -37,90 +35,56 @@ import java.util.stream.Stream;
|
||||
*
|
||||
*
|
||||
*/
|
||||
public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Serializable {
|
||||
public enum ColorSet implements Iterable<Color>, Serializable {
|
||||
|
||||
C(Color.COLORLESS),
|
||||
W(Color.WHITE),
|
||||
U(Color.BLUE),
|
||||
WU(Color.WHITE, Color.BLUE),
|
||||
B(Color.BLACK),
|
||||
WB(Color.WHITE, Color.BLACK),
|
||||
UB(Color.BLUE, Color.BLACK),
|
||||
WUB(Color.WHITE, Color.BLUE, Color.BLACK),
|
||||
R(Color.RED),
|
||||
RW(Color.RED, Color.WHITE),
|
||||
UR(Color.BLUE, Color.RED),
|
||||
URW(Color.BLUE, Color.RED, Color.WHITE),
|
||||
BR(Color.BLACK, Color.RED),
|
||||
RWB(Color.RED, Color.WHITE, Color.BLACK),
|
||||
UBR(Color.BLUE, Color.BLACK, Color.RED),
|
||||
WUBR(Color.WHITE, Color.BLUE, Color.BLACK, Color.RED),
|
||||
G(Color.GREEN),
|
||||
GW(Color.GREEN, Color.WHITE),
|
||||
GU(Color.GREEN, Color.BLUE),
|
||||
GWU(Color.GREEN, Color.WHITE, Color.BLUE),
|
||||
BG(Color.BLACK, Color.GREEN),
|
||||
WBG(Color.WHITE, Color.BLACK, Color.GREEN),
|
||||
BGU(Color.BLACK, Color.GREEN, Color.BLUE),
|
||||
GWUB(Color.GREEN, Color.WHITE, Color.BLUE, Color.BLACK),
|
||||
RG(Color.RED, Color.GREEN),
|
||||
RGW(Color.RED, Color.GREEN, Color.WHITE),
|
||||
GUR(Color.GREEN, Color.BLUE, Color.RED),
|
||||
RGWU(Color.RED, Color.GREEN, Color.WHITE, Color.BLUE),
|
||||
BRG(Color.BLACK, Color.RED, Color.GREEN),
|
||||
BRGW(Color.BLACK, Color.RED, Color.GREEN, Color.WHITE),
|
||||
UBRG(Color.BLUE, Color.BLACK, Color.RED, Color.GREEN),
|
||||
WUBRG(Color.WHITE, Color.BLUE, Color.BLACK, Color.RED, Color.GREEN)
|
||||
;
|
||||
|
||||
private static final long serialVersionUID = 794691267379929080L;
|
||||
|
||||
// needs to be before other static
|
||||
private static final ColorSet[] cache = new ColorSet[MagicColor.ALL_COLORS + 1];
|
||||
static {
|
||||
byte COLORLESS = MagicColor.COLORLESS;
|
||||
byte WHITE = MagicColor.WHITE;
|
||||
byte BLUE = MagicColor.BLUE;
|
||||
byte BLACK = MagicColor.BLACK;
|
||||
byte RED = MagicColor.RED;
|
||||
byte GREEN = MagicColor.GREEN;
|
||||
Color C = Color.COLORLESS;
|
||||
Color W = Color.WHITE;
|
||||
Color U = Color.BLUE;
|
||||
Color B = Color.BLACK;
|
||||
Color R = Color.RED;
|
||||
Color G = Color.GREEN;
|
||||
|
||||
//colorless
|
||||
cache[COLORLESS] = new ColorSet(C);
|
||||
|
||||
//mono-color
|
||||
cache[WHITE] = new ColorSet(W);
|
||||
cache[BLUE] = new ColorSet(U);
|
||||
cache[BLACK] = new ColorSet(B);
|
||||
cache[RED] = new ColorSet(R);
|
||||
cache[GREEN] = new ColorSet(G);
|
||||
|
||||
//two-color
|
||||
cache[WHITE | BLUE] = new ColorSet(W, U);
|
||||
cache[WHITE | BLACK] = new ColorSet(W, B);
|
||||
cache[BLUE | BLACK] = new ColorSet(U, B);
|
||||
cache[BLUE | RED] = new ColorSet(U, R);
|
||||
cache[BLACK | RED] = new ColorSet(B, R);
|
||||
cache[BLACK | GREEN] = new ColorSet(B, G);
|
||||
cache[RED | GREEN] = new ColorSet(R, G);
|
||||
cache[RED | WHITE] = new ColorSet(R, W);
|
||||
cache[GREEN | WHITE] = new ColorSet(G, W);
|
||||
cache[GREEN | BLUE] = new ColorSet(G, U);
|
||||
|
||||
//three-color
|
||||
cache[WHITE | BLUE | BLACK] = new ColorSet(W, U, B);
|
||||
cache[WHITE | BLACK | GREEN] = new ColorSet(W, B, G);
|
||||
cache[BLUE | BLACK | RED] = new ColorSet(U, B, R);
|
||||
cache[BLUE | RED | WHITE] = new ColorSet(U, R, W);
|
||||
cache[BLACK | RED | GREEN] = new ColorSet(B, R, G);
|
||||
cache[BLACK | GREEN | BLUE] = new ColorSet(B, G, U);
|
||||
cache[RED | GREEN | WHITE] = new ColorSet(R, G, W);
|
||||
cache[RED | WHITE | BLACK] = new ColorSet(R, W, B);
|
||||
cache[GREEN | WHITE | BLUE] = new ColorSet(G, W, U);
|
||||
cache[GREEN | BLUE | RED] = new ColorSet(G, U, R);
|
||||
|
||||
//four-color
|
||||
cache[WHITE | BLUE | BLACK | RED] = new ColorSet(W, U, B, R);
|
||||
cache[BLUE | BLACK | RED | GREEN] = new ColorSet(U, B, R, G);
|
||||
cache[BLACK | RED | GREEN | WHITE] = new ColorSet(B, R, G, W);
|
||||
cache[RED | GREEN | WHITE | BLUE] = new ColorSet(R, G, W, U);
|
||||
cache[GREEN | WHITE | BLUE | BLACK] = new ColorSet(G, W, U, B);
|
||||
|
||||
//five-color
|
||||
cache[WHITE | BLUE | BLACK | RED | GREEN] = new ColorSet(W, U, B, R, G);
|
||||
}
|
||||
|
||||
private final Collection<Color> orderedShards;
|
||||
private final byte myColor;
|
||||
private final float orderWeight;
|
||||
private final Set<Color> enumSet;
|
||||
private final String desc;
|
||||
|
||||
public static final ColorSet ALL_COLORS = fromMask(MagicColor.ALL_COLORS);
|
||||
public static final ColorSet NO_COLORS = fromMask(MagicColor.COLORLESS);
|
||||
|
||||
private ColorSet(final Color... ordered) {
|
||||
this.orderedShards = Arrays.asList(ordered);
|
||||
this.myColor = orderedShards.stream().map(Color::getColorMask).reduce((byte)0, (a, b) -> (byte)(a | b));
|
||||
this.orderWeight = this.getOrderWeight();
|
||||
this.enumSet = EnumSet.copyOf(orderedShards);
|
||||
this.desc = orderedShards.stream().map(Color::getShortName).collect(Collectors.joining());
|
||||
this.orderWeight = this.calcOrderWeight();
|
||||
}
|
||||
|
||||
public static ColorSet fromMask(final int mask) {
|
||||
final int mask32 = mask & MagicColor.ALL_COLORS;
|
||||
return cache[mask32];
|
||||
return values()[mask32];
|
||||
}
|
||||
|
||||
public static ColorSet fromEnums(final Color... colors) {
|
||||
@@ -167,7 +131,10 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean hasAnyColor(final int colormask) {
|
||||
return (this.myColor & colormask) != 0;
|
||||
return (this.ordinal() & colormask) != 0;
|
||||
}
|
||||
public boolean hasAnyColor(final Color c) {
|
||||
return this.orderedShards.contains(c);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,12 +145,12 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean hasAllColors(final int colormask) {
|
||||
return (this.myColor & colormask) == colormask;
|
||||
return (this.ordinal() & colormask) == colormask;
|
||||
}
|
||||
|
||||
/** this has exactly the colors defined by operand. */
|
||||
public boolean hasExactlyColor(final int colormask) {
|
||||
return this.myColor == colormask;
|
||||
return this.ordinal() == colormask;
|
||||
}
|
||||
|
||||
/** this has no other colors except defined by operand. */
|
||||
@@ -193,17 +160,17 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
|
||||
/** this has no other colors except defined by operand. */
|
||||
public boolean hasNoColorsExcept(final int colormask) {
|
||||
return (this.myColor & ~colormask) == 0;
|
||||
return (this.ordinal() & ~colormask) == 0;
|
||||
}
|
||||
|
||||
/** This returns the colors that colormask contains that are not in color */
|
||||
public ColorSet getMissingColors(final byte colormask) {
|
||||
return fromMask(this.myColor & ~colormask);
|
||||
return fromMask(this.ordinal() & ~colormask);
|
||||
}
|
||||
|
||||
/** Operand has no other colors except defined by this. */
|
||||
public boolean containsAllColorsFrom(final int colorProfile) {
|
||||
return (~this.myColor & colorProfile) == 0;
|
||||
return (~this.ordinal() & colorProfile) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,7 +179,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
* @return the int
|
||||
*/
|
||||
public int countColors() {
|
||||
return BinaryUtil.bitCount(this.myColor);
|
||||
return BinaryUtil.bitCount(this.ordinal());
|
||||
} // bit count
|
||||
|
||||
// order has to be: W U B R G multi colorless - same as cards numbering
|
||||
@@ -222,7 +189,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
*
|
||||
* @return the order weight
|
||||
*/
|
||||
private float getOrderWeight() {
|
||||
private float calcOrderWeight() {
|
||||
float res = this.countColors();
|
||||
if (hasWhite()) {
|
||||
res += 0.0005f;
|
||||
@@ -241,6 +208,10 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public float getOrderWeight()
|
||||
{
|
||||
return orderWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is colorless.
|
||||
@@ -248,7 +219,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
* @return true, if is colorless
|
||||
*/
|
||||
public boolean isColorless() {
|
||||
return this.myColor == 0;
|
||||
return this == C;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,7 +237,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
* @return true, if is all colors
|
||||
*/
|
||||
public boolean isAllColors() {
|
||||
return this == ALL_COLORS;
|
||||
return this == WUBRG;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,17 +257,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
* @return true, if is equal
|
||||
*/
|
||||
public boolean isEqual(final byte color) {
|
||||
return color == this.myColor;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(final ColorSet other) {
|
||||
return Float.compare(this.orderWeight, other.orderWeight);
|
||||
return color == this.ordinal();
|
||||
}
|
||||
|
||||
// Presets
|
||||
@@ -346,23 +307,13 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
}
|
||||
|
||||
public ColorSet inverse() {
|
||||
byte mask = this.myColor;
|
||||
byte mask = (byte)this.ordinal();
|
||||
mask ^= MagicColor.ALL_COLORS;
|
||||
return fromMask(mask);
|
||||
}
|
||||
|
||||
public byte getColor() {
|
||||
return myColor;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return desc;
|
||||
return (byte)ordinal();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,7 +323,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean sharesColorWith(final ColorSet ccOther) {
|
||||
return (this.myColor & ccOther.myColor) != 0;
|
||||
return (this.ordinal() & ccOther.ordinal()) != 0;
|
||||
}
|
||||
|
||||
public ColorSet getSharedColors(final ColorSet ccOther) {
|
||||
@@ -380,50 +331,20 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
|
||||
}
|
||||
|
||||
public ColorSet getOffColors(final ColorSet ccOther) {
|
||||
return fromMask(~this.myColor & ccOther.myColor);
|
||||
return fromMask(~this.ordinal() & ccOther.ordinal());
|
||||
}
|
||||
|
||||
public Set<Color> toEnumSet() {
|
||||
return EnumSet.copyOf(enumSet);
|
||||
return EnumSet.copyOf(orderedShards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Byte> iterator() {
|
||||
return new ColorIterator();
|
||||
}
|
||||
|
||||
private class ColorIterator extends UnmodifiableIterator<Byte> {
|
||||
int currentBit = -1;
|
||||
|
||||
private int getIndexOfNextColor(){
|
||||
int nextBit = currentBit + 1;
|
||||
while (nextBit < MagicColor.NUMBER_OR_COLORS) {
|
||||
if ((myColor & MagicColor.WUBRG[nextBit]) != 0) {
|
||||
break;
|
||||
}
|
||||
nextBit++;
|
||||
}
|
||||
return nextBit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return getIndexOfNextColor() < MagicColor.NUMBER_OR_COLORS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte next() {
|
||||
currentBit = getIndexOfNextColor();
|
||||
if (currentBit >= MagicColor.NUMBER_OR_COLORS) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
return MagicColor.WUBRG[currentBit];
|
||||
}
|
||||
//@Override
|
||||
public Iterator<Color> iterator() {
|
||||
return this.orderedShards.iterator();
|
||||
}
|
||||
|
||||
public Stream<Color> stream() {
|
||||
return this.toEnumSet().stream();
|
||||
return this.orderedShards.stream();
|
||||
}
|
||||
|
||||
//Get array of mana cost shards for color set in the proper order
|
||||
|
||||
@@ -593,7 +593,7 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
||||
|
||||
public PaperCardFlags withMarkedColors(ColorSet markedColors) {
|
||||
if(markedColors == null)
|
||||
markedColors = ColorSet.NO_COLORS;
|
||||
markedColors = ColorSet.C;
|
||||
return new PaperCardFlags(this, markedColors, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,25 +112,19 @@ public abstract class PaperCardPredicates {
|
||||
}
|
||||
|
||||
private static final class PredicateColor implements Predicate<PaperCard> {
|
||||
private final byte operand;
|
||||
private final MagicColor.Color operand;
|
||||
|
||||
private PredicateColor(final byte color) {
|
||||
private PredicateColor(final MagicColor.Color color) {
|
||||
this.operand = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(final PaperCard card) {
|
||||
for (final byte color : card.getRules().getColor()) {
|
||||
if (color == operand) {
|
||||
return true;
|
||||
}
|
||||
if (card.getRules().getColor().hasAnyColor(operand)) {
|
||||
return true;
|
||||
}
|
||||
if (card.getRules().getType().hasType(CardType.CoreType.Land)) {
|
||||
for (final byte color : card.getRules().getColorIdentity()) {
|
||||
if (color == operand) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (card.getRules().getType().hasType(CardType.CoreType.Land) && card.getRules().getColorIdentity().hasAnyColor(operand)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -235,11 +229,11 @@ public abstract class PaperCardPredicates {
|
||||
public static final Predicate<PaperCard> IS_RARE_OR_MYTHIC = PaperCardPredicates.IS_RARE.or(PaperCardPredicates.IS_MYTHIC_RARE);
|
||||
public static final Predicate<PaperCard> IS_SPECIAL = new PredicateRarity(CardRarity.Special);
|
||||
public static final Predicate<PaperCard> IS_BASIC_LAND_RARITY = new PredicateRarity(CardRarity.BasicLand);
|
||||
public static final Predicate<PaperCard> IS_BLACK = new PredicateColor(MagicColor.BLACK);
|
||||
public static final Predicate<PaperCard> IS_BLUE = new PredicateColor(MagicColor.BLUE);
|
||||
public static final Predicate<PaperCard> IS_GREEN = new PredicateColor(MagicColor.GREEN);
|
||||
public static final Predicate<PaperCard> IS_RED = new PredicateColor(MagicColor.RED);
|
||||
public static final Predicate<PaperCard> IS_WHITE = new PredicateColor(MagicColor.WHITE);
|
||||
public static final Predicate<PaperCard> IS_BLACK = new PredicateColor(MagicColor.Color.BLACK);
|
||||
public static final Predicate<PaperCard> IS_BLUE = new PredicateColor(MagicColor.Color.BLUE);
|
||||
public static final Predicate<PaperCard> IS_GREEN = new PredicateColor(MagicColor.Color.GREEN);
|
||||
public static final Predicate<PaperCard> IS_RED = new PredicateColor(MagicColor.Color.RED);
|
||||
public static final Predicate<PaperCard> IS_WHITE = new PredicateColor(MagicColor.Color.WHITE);
|
||||
public static final Predicate<PaperCard> IS_COLORLESS = paperCard -> paperCard.getRules().getColor().isColorless();
|
||||
public static final Predicate<PaperCard> IS_UNREBALANCED = PaperCard::isUnRebalanced;
|
||||
public static final Predicate<PaperCard> IS_REBALANCED = PaperCard::isRebalanced;
|
||||
|
||||
Reference in New Issue
Block a user