Untitled
unknown
plain_text
2 years ago
6.5 kB
5
Indexable
package sezione15.javaCollections.esercitazione3.cardChallenge.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import sezione15.javaCollections.esercitazione3.cardChallenge.exception.InvalidFaceException;
/**
* Represent a poker card
*
* @author Nicola Colasanto
*
*/
public class Card implements Comparable<Card> {
/**
* The suit of a poker card
*
* @author Nicola Colasanto
*
*/
public enum Suit {
CLUB, DIAMOND, HEART, SPADE;
/**
* @return the relative image
*/
public char getImage() {
return switch (this) {
case DIAMOND -> (char) 9830;
case HEART -> (char) 9829;
case SPADE -> (char) 9824;
default -> (char) 9827;
};
}
}
/**
* The valid letter of a poker card
*
* @author Nicola Colasanto
*
*/
private enum Letter {
A, Q, J, K;
/**
* @return the relative value
*/
public int getRank() {
return switch (this) {
case J -> 9;
case Q -> 10;
case K -> 11;
case A -> 12;
default -> 0;
};
}
}
// The char that represent the suit of the card
private char suit;
// The face of the card
private String face;
// The value of the card
private int rank;
/**
* Create a poker card
*
* @param suit
* @param face it must be between 2 and 10 or J, Q, K, A. It can contains
* spaces and it's not case sensitive.
*/
public Card(Suit suit, String face) {
// Remove all spaces
face = face.replaceAll(" ", "");
// Check if the String passed is valid and set the relative value of this card
checkValidFaceAndSetRank(face);
// Get and set the of this card based on the suit passed
this.suit = suit.getImage();
}
public char getSuit() {
return suit;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj == null || this.getClass() != obj.getClass()) {
return false;
}
var card2 = (Card) obj;
return (suit == card2.suit) && (face.equals(card2.face));
}
public String getFace() {
return face;
}
public int getRank() {
return rank;
}
@Override
public String toString() {
return "%s%c(%d)".formatted(face, suit, rank);
}
/**
* The cards are sorted according to the same suit and the natural numerical order of their value.
*/
@Override
public int compareTo(Card cardToCompare) {
var suit1 = this.suit + "";
var suit2 = cardToCompare.suit + "";
var result = suit1.compareTo(suit2);
if (result == 0) {
Integer rank1 = this.rank;
Integer rank2 = cardToCompare.rank;
result = rank1.compareTo(rank2);
}
return result;
}
/**
* Check if the String passed is valid and set the relative value of this card
*
* @param face the string to check
*/
private void checkValidFaceAndSetRank(String face) {
try {
int value = Integer.parseInt(face);
// If its a number but its not in the range, throw the exception
if (value < 2 || value > 10) {
throw new InvalidFaceException(InvalidFaceException.INVALID_FACE_NUMBER);
} else {
// Set the face corresponding to the valid number passed
this.face = face;
// Set the relative value
rank = value - 2;
}
} catch (NumberFormatException e) {
// At this point the string passed its not numeric.
// Check if the first letter of the string is a valid card letter, if its so set the realtive
// value, if its not throw the exception.
if (!checkValidFirstLetter(face)) {
throw new InvalidFaceException(InvalidFaceException.INVALID_FACE_LETTER);
}
}
}
/**
* Check if the first letter of the string is a valid poker card letter, if it's so set the relative
* value, if it's return false
*
* @param face the string to check
* @return true if it is, false otherwise
*/
private boolean checkValidFirstLetter(String face) {
// Set the string to upper case and get only the first char (in String)
face = face.toUpperCase().substring(0, 1);
// Get all suits values
var letters = Letter.values();
// Check if the string its equal at one of the letter values
for (var l : letters) {
if (face.equals((l).toString())) {
// Set the face corresponding to the valid letter passed
this.face = face;
// Set the relative value of the letter
rank = l.getRank();
return true;
}
}
return false;
}
/**
* Create the standard deck of 52 poker cards
*
* @return deck
*/
public static ArrayList<Card> getStandardDeck() {
var deck = new ArrayList<Card>();
var suits = Suit.values();
// For each suits, add to the deck all the card form 2 to A
Arrays.asList(suits).forEach(s -> {
for (int i = 0; i < 13; i++) {
if (i < 9) {
deck.add(new Card(s, (i + 2) + ""));
} else {
switch (i) {
case 10 -> deck.add(new Card(s, "Q"));
case 11 -> deck.add(new Card(s, "K"));
case 12 -> deck.add(new Card(s, "A"));
default -> deck.add(new Card(s, "J"));
}
}
}
});
return deck;
}
/**
* Print an ordered deck, a row for each suit
*
* @param description of the deck
* @param deck to print
*/
public static void printDeck(String description, List<Card> deck) {
Objects.requireNonNull(description);
Objects.requireNonNull(deck);
// Order based on the compareTo of the card
deck.sort(Comparator.naturalOrder());
// If description is not empty, print it
if (!description.isBlank())
System.out.println(description);
// The suit of the first card
var suit = deck.get(0).suit + "";
// In the each row will be print the same suit cards
for (var card : deck) {
// Check if the suit is the same of the previous one
if (suit.equals(card.suit + "")) {
System.out.print(card + " ");
} else {
// If it's not, change row
System.out.println();
System.out.print(card + " ");
suit = card.suit + "";
}
}
// Change the row
System.out.println();
}
public static Card getRandomCard() {
String[] faces = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "A", "J", "Q", "K"};
Suit[] suits = Suit.values();
Random random = new Random();
return new Card(suits[random.nextInt(0,suits.length)], faces[random.nextInt(0,faces.length)]);
}
}
Editor is loading...