166 lines
5.8 KiB
Java
166 lines
5.8 KiB
Java
package ch.epfl.javass.jass;
|
|
|
|
import ch.epfl.javass.bits.Bits32;
|
|
import ch.epfl.javass.jass.Card.Color;
|
|
import ch.epfl.javass.jass.Card.Rank;
|
|
|
|
/**
|
|
* Allows us to manipulate cards from a Jass game packed in an integer.
|
|
*
|
|
* @author Charles BEAUVILLE
|
|
* @author Celia HOUSSIAUX
|
|
*
|
|
*/
|
|
public final class PackedCard {
|
|
|
|
private PackedCard() {
|
|
}
|
|
|
|
/**
|
|
* Contains the binary value 111111, which represents an invalid packed card
|
|
*/
|
|
public static final int INVALID = 0b111111;
|
|
|
|
/**
|
|
* Returns the packed card having the proper {@link Color} and {@link Rank}.
|
|
*
|
|
* @param c
|
|
* the {@link Color} of the wanted packed {@link Card}.
|
|
* @param r
|
|
* the {@link Rank} of the wanted packed {@link Card}.
|
|
* @return the packed {@link Card} version of the given {@link Rank} and
|
|
* {@link Color}.
|
|
*/
|
|
public static int pack(Color c, Rank r) {
|
|
return Bits32.pack(r.ordinal(), RANK_SIZE, c.ordinal(), COLOR_SIZE);
|
|
}
|
|
|
|
private static final int RANK_INDEX = 0;
|
|
private static final int COLOR_INDEX = 4;
|
|
|
|
private static final int MAX_RANK_VALUE = 8;
|
|
|
|
private static final int RANK_SIZE = 4;
|
|
private static final int COLOR_SIZE = 2;
|
|
private static final int UNUSED_SIZE = 25;
|
|
|
|
private static final int INDEX_TRUMP = 0;
|
|
private static final int INDEX_NORMAL = 1;
|
|
|
|
private static final int[][] PTS = { { 0, 0 }, { 0, 0 }, { 0, 0 },
|
|
{ 14, 0 }, { 10, 10 }, { 20, 2 }, { 3, 3 }, { 4, 4 }, { 11, 11 } };
|
|
|
|
/**
|
|
* Returns true only if the value is a valid packed {@link Card}, which
|
|
* means if the bits containing the rank contain a value between 0 and
|
|
* 8(included) and if the useless bits are all equal to 0.
|
|
*
|
|
* @param pkCard
|
|
* an int representing the packed version of a Jass {@link Card}.
|
|
* @return a boolean true if the packed version of the {@link Card} is valid
|
|
*/
|
|
public static boolean isValid(int pkCard) {
|
|
return (Bits32.extract(pkCard, RANK_INDEX, RANK_SIZE) <= MAX_RANK_VALUE
|
|
&& Bits32.extract(pkCard, RANK_INDEX, RANK_SIZE) >= 0
|
|
&& Bits32.extract(pkCard, RANK_SIZE + COLOR_SIZE,
|
|
UNUSED_SIZE) == 0);
|
|
}
|
|
|
|
/**
|
|
* Returns the {@link Color} of the packed {@link Card}.
|
|
*
|
|
* @param pkCard
|
|
* an int representing the packed version of a Jass {@link Card}.
|
|
* @return the {@link Color} of the given packed {@link Card}.
|
|
*/
|
|
public static Color color(int pkCard) {
|
|
assert isValid(pkCard) : "Invalid card in color function of pkCard";
|
|
|
|
int pkColor = Bits32.extract(pkCard, COLOR_INDEX, COLOR_SIZE);
|
|
|
|
return Color.ALL.get(pkColor);
|
|
}
|
|
|
|
/**
|
|
* Returns the {@link Rank} of the packed {@link Card}.
|
|
*
|
|
* @param pkCard
|
|
* an int representing the packed version of a Jass {@link Card}.
|
|
* @return the {@link Rank} of the given packed {@link Card}.
|
|
*/
|
|
public static Rank rank(int pkCard) {
|
|
assert isValid(pkCard) : "Invalid card in rank function of pkCard";
|
|
|
|
int pkRank = Bits32.extract(pkCard, RANK_INDEX, RANK_SIZE);
|
|
|
|
return Rank.ALL.get(pkRank);
|
|
}
|
|
|
|
/**
|
|
* Compares the first {@link Card} entered with the second one, knowing that
|
|
* the {@link Color} is trump.
|
|
*
|
|
* @param trump
|
|
* the trump {@link Color}
|
|
* @param pkCardL
|
|
* the {@link Card} to be compared with
|
|
* @param pkCardR
|
|
* the {@link Card} to be compared to
|
|
* @return a boolean which is true only if the first {@link Card} entered is
|
|
* superior to the second one, knowing that trump is the asset.
|
|
*/
|
|
public static boolean isBetter(Color trump, int pkCardL, int pkCardR) {
|
|
assert isValid(
|
|
pkCardL) : "Invalid pkCardL in isBetter function of pkCard";
|
|
assert isValid(
|
|
pkCardR) : "Invalid pkCardR in isBetter function of pkCard";
|
|
|
|
boolean bothTrump = color(pkCardL).equals(trump) && color(pkCardR).equals(trump);
|
|
boolean betterTrumpRank = rank(pkCardL).trumpOrdinal() > rank(pkCardR).trumpOrdinal();
|
|
boolean betterRank = rank(pkCardL).ordinal() > rank(pkCardR).ordinal();
|
|
boolean bothNotTrump = !color(pkCardL).equals(trump) && !color(pkCardR).equals(trump);
|
|
boolean sameColor = color(pkCardL).equals(color(pkCardR));
|
|
|
|
if(sameColor)
|
|
return bothTrump ? betterTrumpRank : betterRank;
|
|
else
|
|
return !bothNotTrump ? color(pkCardL).equals(trump) : false;
|
|
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the packed {@link Card}.
|
|
*
|
|
* @param trump
|
|
* the trump {@link Color}.
|
|
* @param pkCard
|
|
* an int representing the packed version of a Jass {@link Card}.
|
|
* @return the value of the given packed {@link Card}.
|
|
*/
|
|
public static int points(Color trump, int pkCard) {
|
|
assert isValid(pkCard) : "Invalid card in points function of pkCard";
|
|
|
|
return color(pkCard).equals(trump)
|
|
? PTS[rank(pkCard).ordinal()][INDEX_TRUMP]
|
|
: PTS[rank(pkCard).ordinal()][INDEX_NORMAL];
|
|
}
|
|
|
|
/**
|
|
* Returns a representation of the packed {@link Card} under a string of
|
|
* character containing the symbol of the {@link Color} and the shorted name
|
|
* of the {@link Rank}.
|
|
*
|
|
* @param pkCard
|
|
* an int representing the packed version of a Jass {@link Card}.
|
|
* @return a string the description of the given packed {@link Card} (its
|
|
* {@link Rank} and its {@link Color}).
|
|
*/
|
|
public static String toString(int pkCard) {
|
|
assert isValid(pkCard) : "Invalid card in toString function of pkCard";
|
|
|
|
return color(pkCard).toString() +
|
|
rank(pkCard).toString();
|
|
}
|
|
|
|
}
|