Reputation: 13
I have a class named "Card" that stores a character and an integer. I am passing a unicode character of a card (the Unicode vals are taken from this Wikipedia page: https://en.wikipedia.org/wiki/Playing_cards_in_Unicode) into the instance of card. Below is what the class looks like.
import java.util.ArrayList;
import java.util.Collections;
public class Card {
protected char unicodeCard;
protected int value;
public Card() {}
public Card(char unicodeCard, int value) {
this.unicodeCard = unicodeCard;
this.value = value;
}
public ArrayList<Card> buildDeck() {
ArrayList<Card> deck = new ArrayList<>();
deck.add(new Card('\uF0A1', 11));
deck.add(new Card('\uF0B1', 11));
deck.add(new Card('\uF0C1', 11));
deck.add(new Card('\uF0D1', 11));
deck.add(new Card('\uF0A2', 2));
deck.add(new Card('\uF0B2', 2));
deck.add(new Card('\uF0C2', 2));
deck.add(new Card('\uF0D2', 2));
deck.add(new Card('\uF0A3', 3));
deck.add(new Card('\uF0B3', 3));
deck.add(new Card('\uF0C3', 3));
deck.add(new Card('\uF0D3', 3));
deck.add(new Card('\uF0A4', 4));
deck.add(new Card('\uF0B4', 4));
deck.add(new Card('\uF0C4', 4));
deck.add(new Card('\uF0D4', 4));
deck.add(new Card('\uF0A5', 5));
deck.add(new Card('\uF0B5', 5));
deck.add(new Card('\uF0C5', 5));
deck.add(new Card('\uF0D5', 5));
deck.add(new Card('\uF0A6', 6));
deck.add(new Card('\uF0B6', 6));
deck.add(new Card('\uF0C6', 6));
deck.add(new Card('\uF0D6', 6));
deck.add(new Card('\uF0A7', 7));
deck.add(new Card('\uF0B7', 7));
deck.add(new Card('\uF0C7', 7));
deck.add(new Card('\uF0D7', 7));
deck.add(new Card('\uF0A8', 8));
deck.add(new Card('\uF0B8', 8));
deck.add(new Card('\uF0C8', 8));
deck.add(new Card('\uF0D8', 8));
deck.add(new Card('\uF0A9', 9));
deck.add(new Card('\uF0B9', 9));
deck.add(new Card('\uF0C9', 9));
deck.add(new Card('\uF0D9', 9));
deck.add(new Card('\uF0AA', 10));
deck.add(new Card('\uF0BA', 10));
deck.add(new Card('\uF0CA', 10));
deck.add(new Card('\uF0DA', 10));
deck.add(new Card('\uF0AB', 10));
deck.add(new Card('\uF0BB', 10));
deck.add(new Card('\uF0CB', 10));
deck.add(new Card('\uF0DB', 10));
deck.add(new Card('\uF0AD', 10));
deck.add(new Card('\uF0BD', 10));
deck.add(new Card('\uF0CD', 10));
deck.add(new Card('\uF0DD', 10));
deck.add(new Card('\uF0AE', 10));
deck.add(new Card('\uF0BE', 10));
deck.add(new Card('\uF0CE', 10));
deck.add(new Card('\uF0DE', 10));
return deck;
}
public void shuffle(ArrayList<Card> deck) {
Collections.shuffle(deck);
}
public char getCardChar() {
return this.unicodeCard;
}
}
In my main method, I am attempting to print out the Unicode characters in the ArrayList, but all I receive from the console is a ? character. In addition, I have tried creating an instance of PrintStream with encoding set to "UTF-8" but that doesn't seem to work either. I only get outputs that look like this: . Below is what my main method looks like.
public static void main(String[] args) throws UnsupportedEncodingException {
PrintStream out = new PrintStream(System.out, true, "UTF-8");
Card card = new Card();
ArrayList<Card> deck = card.buildDeck();
for (int i = 0; i < deck.size(); i++) {
out.println(deck.get(i).getCardChar());
}
}
Upvotes: 1
Views: 132
Reputation: 338346
1
digit. Example: \u1F0A1
, not \uF0A1
.char
.Character.toString( 0x1F0A1 )
Your code contains the wrong Unicode code point hexadecimal numbers. You failed to include the leading 1
.
\uF0A1
\u1F0A1
The codepoint for Ace of Spades is 1F0A1 hexadecimal, 127,137 decimal.
But you cannot fix your code by doing a search-and-replace changing \u
for \u1
. Your code uses char
type, which fails here.
char
The char
type has been essentially broken since Java 2, and legacy since Java 5. As a 16-bit value, char
is physically incapable of representing most characters.
Java source code is Unicode compliant. So you can embed the actual character you want as a string literal.
String aceOfSpades = "🂡" ;
In this case, those playing card glyphs may be too small to read easily in a code-editor. So you may want to use code point numbers instead.
As alternatives to char
& string literals, use code point integer values to work with individual characters. You’ll find …codePoint…
related methods on various classes including Character
, String
, and StringBuilder
.
Use either hexadecimal literal or decimal literal.
String aceOfSpades = Character.toString( 0x1F0A1 ) ;
Or decimal.
String aceOfSpades = Character.toString( 127_137 ) ;
Your situation is suited (pun!) to enums.
When you have a limited set of named instances known at compile-time, define an enum. An enum is a class, albeit a slightly special kind of class. So you can define fields for your additional bits of info.
package work.basil.example.enums;
// Representing each of the standard 52-card deck of French-suited playing cards.
// https://en.wikipedia.org/wiki/Standard_52-card_deck
public enum Card
{
// Enum
ACE_OF_SPADES ( 0x1F0A1 ), TWO_OF_SPADES ( 0x1F0A2 ), THREE_OF_SPADES ( 0x1F0A3 ),
ACE_OF_HEARTS ( 0x1F0B1 ), TWO_OF_HEARTS ( 0x1F0B2 ), THREE_OF_HEARTS ( 0x1F0B3 ),
ACE_OF_DIAMONDS ( 0x1F0C1 ), TWO_OF_DIAMONDS ( 0x1F0C2 ), THREE_OF_DIAMONDS ( 0x1F0C3 ),
ACE_OF_CLUBS ( 0x1F0D1 ), TWO_OF_CLUBS ( 0x1F0D2 ), THREE_OF_CLUBS ( 0x1F0D3 );
// Fields
public final int codePoint;
public final String character;
// Constructor
Card ( final int theCodePoint )
{
this.codePoint = theCodePoint;
this.character = Character.toString ( this.codePoint );
}
}
We can add some static methods as a convenience, to get a deck of cards in order, and a deck shuffled.
// Collection methods
public static List < Card > deckInOrder ( )
{
return List.of ( Card.values ( ) );
}
public static List < Card > deckShuffled ( )
{
List < Card > deck = new ArrayList <> ( Card.deckInOrder ( ) );
Collections.shuffle ( deck );
return deck;
}
Dump our deck to console.
List < Card > deck = Card.deckShuffled ( );
deck.stream ( ).map ( card -> card.character + " " + card.name ( ) ).forEach ( System.out :: println );
🃓 THREE_OF_CLUBS
🂱 ACE_OF_HEARTS
🃂 TWO_OF_DIAMONDS
🂡 ACE_OF_SPADES
🂣 THREE_OF_SPADES
🃒 TWO_OF_CLUBS
🃁 ACE_OF_DIAMONDS
🃃 THREE_OF_DIAMONDS
🂳 THREE_OF_HEARTS
🂲 TWO_OF_HEARTS
🃑 ACE_OF_CLUBS
🂢 TWO_OF_SPADES
We could do much more. We could add a field for nickname of each card. We could represent the suit of each card by defining a nested enum for Suit
, including a field for pip (U+2660–2667), and add a field of that type Suit
to Card
.
Upvotes: 1
Reputation: 411
Let's consider Ace of Spades as an example. The Wikipedia character has the following values U+1F0A1
. The Java compiler does not agree that U+1F0A1
is a valid syntax and refuses to compile.
In this scenario, you have a few options to output symbols. I think you can replace the U+
with 0x000
and the Wikipedia Unicode.
String test1 = new String(new int[] {0x0001F0A1}, 0, 1);
String test2 = String.valueOf(Character.toChars(0x0001F0A1));
String test3 = Character.toString(0x0001F0A1);
Alternatively, you can try using different Unicode specifically for the platform, i.e., \uD83C\uDCA1
.
Regardless of the options you choose, the output is still Ace of Spades.
🂡
UPDATE: @g00se commented about the redundant leading zero. That's also correct.
String test1 = new String(new int[] {0x1F0A1}, 0, 1);
String test2 = String.valueOf(Character.toChars(0x1F0A1));
String test3 = Character.toString(0x1F0A1);
Still prints 🂡.
Upvotes: 0
Reputation: 37
public class CardGame {
public static void main(String[] args) {
String[] ranks = {
"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"
};
String[] suits = {
"\u2660", // Spades
"\u2665", // Hearts
"\u2666", // Diamonds
"\u2663" // Clubs
};
System.out.println("Deck of Cards:");
for (String suit : suits) {
for (String rank : ranks) {
System.out.print(rank + suit + " ");
}
System.out.println(); // New line after each suit
}
}
}
Output:
Deck of Cards: A♠ 2♠ 3♠ 4♠ 5♠ 6♠ 7♠ 8♠ 9♠ 10♠ J♠ Q♠ K♠ A♥ 2♥ 3♥ 4♥ 5♥ 6♥ 7♥ 8♥ 9♥ 10♥ J♥ Q♥ K♥ A♦ 2♦ 3♦ 4♦ 5♦ 6♦ 7♦ 8♦ 9♦ 10♦ J♦ Q♦ K♦ A♣ 2♣ 3♣ 4♣ 5♣ 6♣ 7♣ 8♣ 9♣ 10♣ J♣ Q♣ K♣
If you need randomized, you can use such way
Random random = new Random();
// Select a random card
String randomRank = ranks[random.nextInt(ranks.length)];
String randomSuit = suits[random.nextInt(suits.length)];
System.out.println("Random Card: " + randomRank + randomSuit);
Upvotes: -2