Calculate cardSum (Hands of Strings) - java

I am trying to create a Blackjack game. The game itself is pretty easy (at least my version). A player draws a card from a shuffled deck and calculates the sum of the cards which has been drawn. I have a decklist of cards with the type String and that is now a big problem for me. I have no clue how I can calculate the sum since they are of the type String. Do you have any guidelines on what I can do? The only solution I've figured out is really bad and is to compare the card with a String and give it a value. For example, drawnCard.equals("Four of hearts") = "4";
public class Player {
private String nickName;
private int playerNumOfCards;
ArrayList<Card> playerHand = new ArrayList<>();
public Player (String name){
this.nickName = name;
}
public String getNickName() {
return nickName;
}
public void addCard(Card aCard){
playerHand.add(aCard);
this.playerNumOfCards++;
}
public void getHandSum(){
}
public void getPlayerHand(){
for(Card cards: playerHand){
System.out.println(cards.toString());
}
}
}
public class DeckOfCards {
private Card[] deck;
private static final Random random = new Random();
private int currentCard; //index of next Card to be deal (0-51)
private static int NUMBER_OF_CARDS = 52; //Constant number of cards
public DeckOfCards(){
String [] faces = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack","Queen", "King"};
String [] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
deck = new Card [NUMBER_OF_CARDS]; // create array with Cards (52)
currentCard = 0;
//Populate deck with Cards
for(int count = 0; count < deck.length; count++)
deck [count] = new Card(faces [count % 13], suits [count / 13]);
}
public void shuffleDeck(){
currentCard = 0;
for (int first = 0; first < deck.length; first++){
int second = random.nextInt(NUMBER_OF_CARDS); //Select a random card from number 0-51 (Number_of_cards)
//Loops through all the cards and swaps it with the "Second" card which is randomly chosen card from hte same list.
Card temp = deck[first];
deck [first] = deck [second];
deck [second] = temp;
}
}
public void getCardDeck(){
int start = 1;
for(Card k : deck) {
System.out.println("" + start + "/52 " + k);
start++;
}
}
public Card dealNextCard(){
//Get the top card
Card topCard = this.deck[0];
//shift all the subsequent cards to the left by one index
for(int currentCard = 1; currentCard < NUMBER_OF_CARDS; currentCard ++){
this.deck[currentCard-1] = this.deck[currentCard];
}
this.deck[NUMBER_OF_CARDS-1] = null;
//decrement the number of cards in our deck
this.NUMBER_OF_CARDS--;
return topCard;
}
}
public class Card {
private String face; //Face of card, i.e "King" & "Queen"
private String suit; //Suit of card, i.e "Hearts" & "diamonds"
public Card (String cardFace, String cardSuit){ //Constructor which initializes card's face and suit
this.face = cardFace;
this.suit = cardSuit;
}
public String toString(){ //return String representation of Card
return face + " of " + suit;
}
}
public class BlackJackGame {
public static void main(String[] args) {
DeckOfCards deck1 = new DeckOfCards();
Player player1 = new Player("mille");
deck1.shuffleDeck();
}
}

Create an enum to represent Face
enum Face {
Ace(number), //I don't know what number is for Ace and others.
Deuce(number),
Three(3),
Four(4),
Five(5),
Six(6),
Seven(7),
Eight(8),
Nine(9),
Ten(10),
Jack(number),
Queen(number),
King(number);
private final int number;
Faces(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
}
Change type of face from String to Face.
class Card {
private Face face;
private String suit;
public Card (Face cardFace, String cardSuit){card's face and suit
this.face = cardFace;
this.suit = cardSuit;
}
public String toString(){
return face + " of " + suit;
}
public int getNumber() {
return face.getNumber();
}
}
Add a method to get the face number from card class and then use it accordingly. You will need to change other parts or your project as well but I will leave that for you to do.
Also suggest using enum for Suit.

I couldn't see the deck list there, but if your card Strings always follow the same naming convention (i.e. "four of hearts") you could make your job a little easier by splitting each string by the " " space fields and then comparing the first word in the string to get the number (or corresponding 10 for king/queen etc..)
String cardName = "four of hearts" (or whatever the variable name is);
String[] parts = string.split(" ");
String number = parts[0];
thus number would equal "four" only instead of having to compare "four of hearts" to return the number 4.
Hope that helps

Related

|Java| Spades Game unexpected output on print statements

Recently, I've tried to create a Spades game in java. Ive managed to make the card and the deck class, but whenever I try to print out either a random card or a deck of cards, sans 2 of diamonds and clubs, I have an unexpected result. Here is my code:
Main class
package com.star.spades;
import com.star.cards.Card;
import com.star.cards.Deck;
public class Spades {
public static void main(String[] args) {
Deck deck = new Deck();
Card randCard = deck.drawCard();
System.out.println(deck);
System.out.println(randCard);
}
}
Card Class:
package com.star.cards;
public class Card
{
private int suit;
private int value;
private String [] suits = {"Diamonds", "Clubs", "Spades", "Hearts", };
private String [] values = {"Ace", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "Jack", "Queen", "King"};
private String [] joker = {"Joker"};
private String [] jokerValue = {"Little", "Big"};
public Card(int suit, int value)
{
this.suit = suit;
this.value = value;
}
public String outputCard()
{
return value + "of" + suit;
}
public String outputJoker()
{
return value + " " + suit;
}
Deck Class:
package com.star.cards;
import java.util.ArrayList;
import java.util.Random;
public class Deck {
private int numberOfSuits = 4;
private int numberOfValues = 52;
private int jokers = 1;
private int jokerSize = 2;
private ArrayList<Card> deck;
private ArrayList <Card> hands;
public Deck()
{
deck = new ArrayList<Card>();
for(int i = 0; i < numberOfSuits; i++)
for(int j =0; j < numberOfValues; j++)
{
deck.add(new Card(i, j));
}
for(int i = 0; i < jokerSize; i++)
for(int j = 0; j < jokers; j++)
{
deck.add(new Card(i, j));
}
deck.remove(1);
deck.remove(13);
}
//draws random card and removes it from deck.
public Card drawCard()
{
Random rand = new Random();
int index = rand.nextInt(deck.size());
return deck.remove(index);
}
//deals 13 random cards to the player
public ArrayList<Card> dealCards()
{
for(int i = 0; i < 13; i++)
{
hands.add(drawCard());
}
return hands;
}
}
and here is the result:
com.star.cards.Deck#143b9a5f
com.star.cards.Card#5513dd59
Could you let me know what I need to do to print out my deck and cards on the console?
You are trying to print objects directly. By default, the toString() method, which is called by print, will print out the reference to your object. So that weird thing you are getting is actually code for the location in memory where your object is stored. If you want to print out something else (for example some properties of the class) you must override the toString() method in your object's class.
You need to either implement toString in your classes or call a specific method that returns a string representation. Currently when you do System.out.println(card) it prints card's instance toString but since you didn't implement it yourself, it uses the parent class that did implement it - Object. Since Object has no information about your specific object, it prints a generic name and reference location address string.
If you choose to implement toString, all you have to do is add the method to your classes, for instance in Card class:
#Override
public String toString() {
return value + " " + suit;
}
And the same for your Deck class (not sure what you want to print there). Your Spades class is left untouched.
You need to implement/override the toString method in your classes. You will find many examples online for how to do that. For your Card class, a simple version could look like this:
#Override
public String toString()
{
return "Card[suit=" + suits[suit] + ",value=" + values[value] + "]";
}

Simple card game, letting user chose amount of decks in the game

Instead of translating I've added comment in the code. But its mainly strings that are in Swedish.
I have trouble adding a feature where the game asks the user the amount of decks (each deck containing the standard 52 cards.)
Just like how the game ask if the deck should be shuffled or not the user should be asked how many decks the game should contain, the rest can be as it is for now.
I've tried (but ofc it didnt work):
int n = //amount of decks
int[] deck = new int[52*n];
Here is the program:
import java.util.Scanner;
public class KortSpel {
public static void main(String[] args) {
Boolean fortsatt = true;
while(fortsatt){
Scanner scan = new Scanner(System.in);
int[] deck = new int[52];
String[] suits = {"Hjärter", "Spader", "Ruter", "Klöver"}; //the suits
String[] ranks = {"Ess", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Knäckt", "Drottning", "Kung"}; //the rank of the cards
for( int i = 0; i < deck.length; i++) deck[i] = i;
System.out.print("Skriv dra för att dra korten annars avsluta."); //ask the user if he want to keep playing or not
String svar2 = scan.nextLine();
if (svar2.equalsIgnoreCase("Avsluta")){
fortsatt = false;
System.out.println("Du har nu avslutat."); //tells the user he has exit
}
else {
System.out.print("Vill du bland korten? (ja/nej) "); //ask the user if he want to shuffle the cards Y/N
String svar = scan.nextLine();
if (svar.equalsIgnoreCase("ja")) { // if shuffled
for( int i = 0; i < deck.length; i++) {
int index = (int)(Math.random() * deck.length);
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
for( int i = 0; i < 52; i++) {
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println("Kort nummer " + deck[i] + ": " + suit + " " + rank);
}
}
else { //if not suffled
for( int i = 0; i < deck.length; i++) deck[i] = i;
for( int i = 0; i < 52; i++) {
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println("Kort nummer " + deck[i] + ": " + suit + " " + rank);
}
}
}
}
}
}
All help is appreciated and since Im not very good with java, simplicity is preferred.
Thanks in advance!
All this gets a lot easier if you take up a formal Object Oriented model instead of informally defining a card.
What is a card? In this context, that's rather simple; it's a pair of values, one of which is a suit, and the other is a rank. So long as the suit and rank are both valid, both are cards. This gives us the following class:
public class Card{
public final String suit;
public final String rank;
public Card(String s, String r){
suit = s;
rank = r;
}
}
Before we go further, I would like to note here that using the type String for suit and rank is not a great idea; both have a finite set of potential values and as such can be better represented as an enumerated type (or Enum). We can define the Enums like this (though obviously you could change the words to be swedish):
public enum Suit{
HEARTS,
SPADES,
CLUBS,
DIAMONDS
}
public enum Rank{
ACE,
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING
}
Which changes our Card class to look like this:
public class Card{
public final Suit suit;
public final Rank rank;
public Card(Suit s, Rank r){
suit = s;
rank = r;
}
}
From here, creating a deck class is easy:
public class Deck{
private ArrayList<Card> deck; //An array of cards that represents this deck.
public Deck(){
deck = new ArrayList<Card>();
//For every combination of suit and rank, create and add a card to this deck
for(Suit s : Suit.values()){
for(Rank r : Rank.values()){
deck.add(new Card(s, r));
}
}
}
}
From here you can add functionality to the deck class for shuffling, drawing cards, etc.
For your original question, creating multiple decks is just a question of creating many single decks and adding all of their contents together. We can create a constructor that does that, and add that to our deck class:
public class Deck{
private ArrayList<Card> deck; //An array of cards that represents this deck.
public Deck(){
deck = new ArrayList<Card>();
//For every combination of suit and rank, create and add a card to this deck
for(Suit s : Suit.values()){
for(Rank r : Rank.values()){
deck.add(new Card(s, r));
}
}
}
/** Creates a deck that is the sum of all the cards in the input deck(s) */
public Deck(Deck... decks){
deck = new ArrayList<Card>();
for(Deck d : decks){
deck.addAll(d.deck);
}
}
}

JAVA changing from an array to a list and using the shuffle method

I have an assignment to create a deck of cards and deal five random cards. I finally got it "working" but I need help with a couple things. One I just read that java now has a shuffle method to shuffle a list. We're on arrays right now so I think arrays were wanted is there a way to use the shuffle method with an array? If not can someone guide me in switching to a list? I think it will help with answer my next question. The only thing left for me to do is somehow state how many cards are left in the deck after the 5 random cards are dealt. However, seeing as how I'm using an array and you cannot remove items from an array because it's fixed (right?) I wanted to see if there was a way to simulate removing the cards from the array so that they aren't dealt again? Or would it just be easier to turn the arrays into a list/collection?
Here is my code. Any help is greatly appreciated. Also, I'll take any suggestions on cleaning the code up too...
public class CardGame {
public static void main (String [] args) {
DeckOfCards deck = new DeckOfCards();
//call shuffle
deck.shuffle(1000);
Card b;
for (int i = 0; i < 5; i++) {
b = deck.deal();
System.out.println("Deal a card: " + b);
}
}
}
class Card {
public static final int SPADE = 4;
public static final int HEART = 3;
public static final int CLUB = 2;
public static final int DIAMOND = 1;
private static final String[] Suit = {"*", "Hearts", "Clubs", "Spades", "Diamonds"};
private static final String[] Rank = {"*", "*", "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
private int cardSuit;
private int cardRank;
public Card( int suit, int rank ) {
if ( rank == 1 )
cardRank = 14; // Give Ace the rank 14
else
cardRank = (int) rank;
cardSuit = (int) suit;
}
public int suit() {
return ( this.cardSuit );
}
public String suitStr() {
return( this.Suit[ this.cardSuit ] );
}
public int rank() {
return ( this.cardRank );
}
public String rankStr() {
return ( Rank[ this.cardRank ] );
}
public String toString() {
return ( Rank[ this.cardRank ] + " of "+ Suit[ this.cardSuit ] );
}
}
class DeckOfCards {
public static final int NEWCARDS = 52;
private Card[] deckOfCards; // Contains all 52 cards
private int currentCard; // deal THIS card in deck
public DeckOfCards( ) {
deckOfCards = new Card[ NEWCARDS ];
int i = 0;
for (int suit = Card.DIAMOND; suit <= Card.SPADE; suit++)
for ( int rank = 1; rank <= 13; rank++ )
deckOfCards[i++] = new Card(suit, rank);
currentCard = 0;
}
//shuffle(n): shuffle the deck
public void shuffle(int n) {
int i, j, k;
for ( k = 0; k < n; k++ ){
i = (int) ( NEWCARDS * Math.random() ); // Pick 2 random cards
j = (int) ( NEWCARDS * Math.random() ); // in the deck
//swap these randomly picked cards
Card temp = deckOfCards[i];
deckOfCards[i] = deckOfCards[j];
deckOfCards[j] = temp;
}
currentCard = 0; // Reset current card to deal
}
//deal(): deal deckOfCards[currentCard] out
public Card deal() {
if (currentCard < NEWCARDS) {
return ( deckOfCards[currentCard++] );
}
else{
System.out.println("Out of cards error");
return ( null ); // Error;
}
}
public String toString() {
String s = "";
int k;
k = 0;
for ( int i = 0; i < 4; i++ ) {
for ( int j = 1; j <= 13; j++ )
s += (deckOfCards[k++] + " ");
s += "\n";
}
return (s);
}
}
After all the help I decided to rewrite my code and here is what I got but I'm having a little trouble bringing it all together and making it work!
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CardGame {
public static void main (String [] args) {
DeckOfCards deck = new DeckOfCards();
//call shuffle
deck.shuffle();
Card b;
for (int i = 0; i < 5; i++) {
b = deck.deal();
System.out.println("Deal a card: " + b);
}
}
}
class Card {
enum Suit {
HEARTS(1),
CLUBS(2),
DIAMONDS(3),
SPADES(4);
private int suitValue;
private Suit (int suitValue)
{
this.suitValue = suitValue;
}
public int getSuitValue()
{
return suitValue;
}
}
private Suit suit;
private Value value;
public Card (Suit suit, Value value)
{
this.suit = suit;
this.value = value;
}
public Suit getSuit() {
return suit;
}
public Value getValue() {
return value;
}
/*
public int compareTo(Card o) {
return 0;
}
} */
class DeckOfCards
{
private List<Card> cards = new ArrayList<Card>();
public DeckOfCards () {
for (Suit suit : Suit.values()) {
for (Value value : Value.values()) {
Card card = new Card(suit, value);
cards.add(card);
}
}
}
public List<Card> getCards() {
return cards;
}
public void shuffleDeckOfCards() {
Collections.shuffle(cards);
}
public String toString() {
return this.Value + " of "+ this.Suit;
}
}
Here is a fully working sample program which demonstrates all the things you need - Shuffling and removing cards from an array.
Sample Card class:
public class Card {
private String value = "";
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Card(String value) {
super();
this.value = value;
}
}
Sample program:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class CardGame {
public static void main(String[] args) {
List<Card> pack = new ArrayList<Card>();
Card c1 = new Card("c1");
Card c2 = new Card("c2");
Card c3 = new Card("c3");
pack.add(c1);
pack.add(c2);
pack.add(c3);
System.out.print("List : ");
CardGame.displayCardList(pack);
Card[] packArr = cardListToArray(pack);
System.out.print("Array : ");
CardGame.displayCardArray(packArr);
// http://stackoverflow.com/questions/4228975/how-to-randomize-arraylist
long seed = System.nanoTime();
Collections.shuffle(pack, new Random(seed));
System.out.print("Shuffle List : ");
CardGame.displayCardList(pack);
packArr = cardListToArray(pack);
System.out.print("Shuffle Array : ");
CardGame.displayCardArray(packArr);
System.out.print("Remove Card from Array : ");
CardGame.removeCardFromArray(packArr, new Card("c1"));
CardGame.displayCardArray(packArr);
}
public static boolean removeCardFromArray(Card[] packArr, Card card) {
boolean cardFound = false;
for (int i = 0; i < packArr.length; i++) {
if (packArr[i].getValue().equalsIgnoreCase(card.getValue())) {
packArr[i] = null;
cardFound = true;
break;
}
}
return cardFound;
}
public static Card[] cardListToArray(List<Card> pack) {
Card[] packArr = new Card[pack.size()];
for (int i = 0; i < pack.size(); i++) {
packArr[i] = pack.get(i);
}
return packArr;
}
public static void displayCardList(List<Card> pack) {
for (Card c : pack) {
System.out.print(c.getValue() + ", ");
}
System.out.println();
}
public static void displayCardArray(Card[] packArr) {
for (Card c : packArr) {
if (c == null) {
System.out.print("REMOVED, ");
} else {
System.out.print(c.getValue() + ", ");
}
}
System.out.println();
}
}
Card
In the Card class the suits should be an enum. You can create the enum like this.
enum Suit {
SPADE,
HEART,
CLUB,
DIAMOND
};
Then the class should hold a variable of it's current suit like
Suit suit;
You can change the value of it very easily.
suit = Suit.HEART;
If you must use an index to access a suit you could use
suit = Suit.values()[index];
When getting the rank of the card you could use
return Rank[suit.ordinal()];
The name of the functions in the Card class are not the typical names you should use. Some of these should be getters. I would recommend names like getSuit() and getSuitName(), you want names that just by reading them you can understand what they do. Names like suit() are a little confusing, they don't tell you what they are doing with suit.
DeckOfCards
In the DeckOfCards class, when initializing the deck use a for each loop for the suits.
for (Suit suit : Suits.values()) {
...
}
This will loop over every suit.
If you wanted to switch over to a List you should declare your private variable deckOfCards to be an ArrayList.
private List<Card> deckOfCards = new ArrayList<>();
If you haven't worked with lists before, this is creating a list of Card objects. The diamond operator (<>) assumes the object type from the type you specified before (Card) This is a java 7 feature, if you are working with older version you would use
new ArrayList<Card>();
Instead of tracking your position in the deck, you add a card with the add() function
deckOfCards.add(card);
This would allow you to use Collections.shuffle(deckOfCards) to shuffle the cards around randomly.
To access a card, you use the get(int i) function
deckOfCards.get(index);
If you are still using arrays, when you are shuffling use a Random object. Throw a
Random random = new Random();
in the begging of your class. The inside of the for loop could look like this
int i = random.nextInt(NEWCARDS);
int j = random.nextInt(NEWCARDS);
Card temp = deckOfCards[i];
deckOfCards[i] = deckOfCards[j];
deckOfCards[j] = temp;
In the shuffle function I would change the names of i, j, and k. Variable K should be called i because it is the iterator. Variable j and k should be renamed to more meaningful names.
If you want to convert Arrays to lists you can use
Arrays.asList(new ArrayList<Card>());
And the opposite of that, to convert back to an array.
list.toArray();//This will return an array of Objects[]
Card[] cards = new Card[NEWCARDS];
list.toArray(cards)//This will store the list into the array cards.
//Note if the lists is bigger than the array it is storing it in, the function will return a new array that can hold all of the elemnents in the list.
Note: In these example I have been using ArrayList, there are other implementations of the List class which you may want to research.
Personal Preference
I would remove the parenthesis off of the return statements except on your toString() for the Card class.
You have some extra spaces when using parenthesis in your code such as your DeckOfCards constructor. I would make it like so
public DeckOfCards() {
There also shouldn't be spaces surrounding the stuff inside parenthesis such as
i = (int) ( NEWCARDS * Math.random() );
//should be
i = (int) (NEWCARDS * Math.random());

Deck of cards JAVA

I have created my deck of cards that deals every card and a suit until there is no card remaining. For my project, I need to split it up into 3 classes which includes a driver class. I first created one class with everything so I knew how to make it all work.
public class DeckOfCards2 {
public static void main(String[] args) {
int[] deck = new int[52];
String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};
String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
// Initialize cards
for (int i = 0; i < deck.length; i++) {
deck[i] = i;
}
// Shuffle the cards
for (int i = 0; i < deck.length; i++) {
int index = (int)(Math.random() * deck.length);
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
// Display the all the cards
for (int i = 0; i < 52; i++) {
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println( rank + " of " + suit);
}
}
}
Now trying to split it up into 3 classes. I am getting red sqiggle lines on ALL my deck/suit variables on my DeckOfCards class. I dont know how to fix it.
public class DeckOfCards {
private Card theCard;
private int remainingCards = 52;
DeckOfCards() {
theCard = new Card();
}
public void shuffle(){
for (int i = 0; i < deck.length; i++) {
int index = (int)(Math.random() deck.length);
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
remainingCards--;
}
}
public void deal(){
for (int i = 0; i < 52; i++) {
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println( rank + " of " + suit);
System.out.println("Remaining cards: " + remainingCards);
}
}
}
Card class:
public class Card {
int[] deck = new int[52];
String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};
String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
Card() {
for (int i = 0; i < deck.length; i++) {
deck[i] = i;
}
}
}
Dealer class
public class Dealer {
public static void main(String[]args){
System.out.println("The deck will randomly print out a card from a full deck each time");
DeckOfCards player = new DeckOfCards();
player.deal();
}
}
As somebody else already said, your design is not very clear and Object Oriented.
The most obvious error is that in your design a Card knows about a Deck of Cards. The Deck should know about cards and instantiate objects in its constructor. For Example:
public class DeckOfCards {
private Card cards[];
public DeckOfCards() {
this.cards = new Card[52];
for (int i = 0; i < ; i++) {
Card card = new Card(...); //Instantiate a Card
this.cards[i] = card; //Adding card to the Deck
}
}
Afterwards, if you want you can also extend Deck in order to build different Deck of Cards (for example with more than 52 cards, Jolly etc.). For Example:
public class SpecialDeck extends DeckOfCards {
....
Another thing that I'd change is the use of String arrays to represent suits and ranks. Since Java 1.5, the language supports Enumeration, which are perfect for this kind of problems. For Example:
public enum Suits {
SPADES,
HEARTS,
DIAMONDS,
CLUBS;
}
With Enum you get some benefits, for example:
1) Enum is type-safe you can not assign anything else other than predefined Enum constants to an Enum variable. For Example, you could write your Card's constructor as following:
public class Card {
private Suits suit;
private Ranks rank;
public Card(Suits suit, Ranks rank) {
this.suit = suit;
this.rank = rank;
}
This way you are sure to build consistent cards that accept only values ​​of your enumeration.
2) You can use Enum in Java inside Switch statement like int or char primitive data type (here we have to say that since Java 1.7 switch statement is allowed also on String)
3) Adding new constants on Enum in Java is easy and you can add new constants without breaking existing code.
4) You can iterate through Enum, this can be very helpful when instantiating Cards. For Example:
/* Creating all possible cards... */
for (Suits s : Suits.values()) {
for (Ranks r : Ranks.values()) {
Card c = new Card(s,r);
}
}
In order to not invent again the wheel, I'd also change the way you keep Cards from array to a Java Collection, this way you get a lot of powerful methods to work on your deck, but most important you can use the Java Collection's shuffle function to shuffle your Deck. For example:
private List<Card> cards = new ArrayList<Card>();
//Building the Deck...
//...
public void shuffle() {
Collections.shuffle(this.cards);
}
This is my implementation:
public class CardsDeck {
private ArrayList<Card> mCards;
private ArrayList<Card> mPulledCards;
private Random mRandom;
public enum Suit {
SPADES,
HEARTS,
DIAMONDS,
CLUBS;
}
public enum Rank {
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING,
ACE;
}
public CardsDeck() {
mRandom = new Random();
mPulledCards = new ArrayList<Card>();
mCards = new ArrayList<Card>(Suit.values().length * Rank.values().length);
reset();
}
public void reset() {
mPulledCards.clear();
mCards.clear();
/* Creating all possible cards... */
for (Suit s : Suit.values()) {
for (Rank r : Rank.values()) {
Card c = new Card(s, r);
mCards.add(c);
}
}
}
public static class Card {
private Suit mSuit;
private Rank mRank;
public Card(Suit suit, Rank rank) {
this.mSuit = suit;
this.mRank = rank;
}
public Suit getSuit() {
return mSuit;
}
public Rank getRank() {
return mRank;
}
public int getValue() {
return mRank.ordinal() + 2;
}
#Override
public boolean equals(Object o) {
return (o != null && o instanceof Card && ((Card) o).mRank == mRank && ((Card) o).mSuit == mSuit);
}
}
/**
* get a random card, removing it from the pack
* #return
*/
public Card pullRandom() {
if (mCards.isEmpty())
return null;
Card res = mCards.remove(randInt(0, mCards.size() - 1));
if (res != null)
mPulledCards.add(res);
return res;
}
/**
* Get a random cards, leaves it inside the pack
* #return
*/
public Card getRandom() {
if (mCards.isEmpty())
return null;
Card res = mCards.get(randInt(0, mCards.size() - 1));
return res;
}
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
* <code>Integer.MAX_VALUE - 1</code>.
*
* #param min Minimum value
* #param max Maximum value. Must be greater than min.
* #return Integer between min and max, inclusive.
* #see java.util.Random#nextInt(int)
*/
public int randInt(int min, int max) {
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = mRandom.nextInt((max - min) + 1) + min;
return randomNum;
}
public boolean isEmpty(){
return mCards.isEmpty();
}
}
Here is some code. It uses 2 classes (Card.java and Deck.java) to accomplish this issue, and to top it off it auto sorts it for you when you create the deck object. :)
import java.util.*;
public class deck2 {
ArrayList<Card> cards = new ArrayList<Card>();
String[] values = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
String[] suit = {"Club", "Spade", "Diamond", "Heart"};
static boolean firstThread = true;
public deck2(){
for (int i = 0; i<suit.length; i++) {
for(int j=0; j<values.length; j++){
this.cards.add(new Card(suit[i],values[j]));
}
}
//shuffle the deck when its created
Collections.shuffle(this.cards);
}
public ArrayList<Card> getDeck(){
return cards;
}
public static void main(String[] args){
deck2 deck = new deck2();
//print out the deck.
System.out.println(deck.getDeck());
}
}
//separate class
public class Card {
private String suit;
private String value;
public Card(String suit, String value){
this.suit = suit;
this.value = value;
}
public Card(){}
public String getSuit(){
return suit;
}
public void setSuit(String suit){
this.suit = suit;
}
public String getValue(){
return value;
}
public void setValue(String value){
this.value = value;
}
public String toString(){
return "\n"+value + " of "+ suit;
}
}
Very Simple code to generate deck off Card:
class Card{
private final String suit;
private final String rank;
public Card(String suit, String rank){
this.suit = suit;
this.rank = rank;
}
#Override
public String toString() {
return "Card [suit=" + suit + ", rank=" + rank + "]";
}
}
class DeckOfCard{
private static final String suits[] = {"club", "diamond", "heart", "spade"};
private static final String ranks[] = {null,"ace", "deuce", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "jack", "queen", "king"};
private final ArrayList<Card> cards;
public DeckOfCard(){
cards = new ArrayList<Card>();
for (int i = 0; i<suits.length; i++) {
for(int j=0; j<ranks.length; j++){
this.cards.add(new Card(suits[i],ranks[j]));
}
}
//Shuffle after the creation
Collections.shuffle(this.cards);
}
public ArrayList<Card> getCards() {
return cards;
}
}
public class CardPuzzle {
public static void main(String[] args) {
DeckOfCard deck = new DeckOfCard();
ArrayList<Card> cards = deck.getCards();
for(Card card:cards){
System.out.println(card);
}
}
}
There is something wrong with your design. Try to make your classes represent real world things. For example:
The class Card should represent one card, that is the nature of a "Card". The Card class does not need to know about Decks.
The Deck class should contain 52 Card objects (plus jokers?).
First you have an architectural issue with your classes. You moved the property deck inside your class Card. But of couse it is a property of the card deck and thus has to be inside class DeckOfCards. The initialization loop should then not be in the constructor of Card but of your deck class. Moreover, the deck is an array of int at the moment but should be an array of Cards.
Second, inside method Deal you should refer to suits as Card.suits and make this member static final. Same for ranks.
And last, please stick to naming conventions. Method names are always starting with a lower case letter, i.e. shuffle instead of Shuffle.
There are many errors in your code, for example you are not really calling your deck by just typing deck in your Shuffle method. You can only call it by typing theCard.deck
I have changed your shuffle method:
public void Shuffle(){
for (int i = 0; i < theCard.deck.length; i++) {
int index = (int)(Math.random()*theCard.deck.length );
int temp = theCard.deck[i];
theCard.deck[i] = theCard.deck[index];
theCard.deck[index] = temp;
remainingCards--;
}
}
Also, as it is said you have structural problem. You should name classes as you understand in real life, for example, when you say card, it is only one card, when you say deck it is supposed to be 52+2 cards. In this way your code would be more understandable.
There is a lot of error in your program.
Calculation of index. I think it should be Math.random()%deck.length
In the display of card. According to me, you should make a class of card which has rank suit and make the array of that class type
If you want I can give you the Complete structure of that but it is better if u make it by yourself
I think the solution is just as simple as this:
Card temp = deck[cardAindex];
deck[cardAIndex]=deck[cardBIndex];
deck[cardBIndex]=temp;
public class shuffleCards{
public static void main(String[] args) {
String[] cardsType ={"club","spade","heart","diamond"};
String [] cardValue = {"Ace","2","3","4","5","6","7","8","9","10","King", "Queen", "Jack" };
List<String> cards = new ArrayList<String>();
for(int i=0;i<=(cardsType.length)-1;i++){
for(int j=0;j<=(cardValue.length)-1;j++){
cards.add(cardsType[i] + " " + "of" + " " + cardValue[j]) ;
}
}
Collections.shuffle(cards);
System.out.print("Enter the number of cards within:" + cards.size() + " = ");
Scanner data = new Scanner(System.in);
Integer inputString = data.nextInt();
for(int l=0;l<= inputString -1;l++){
System.out.print( cards.get(l)) ;
}
}
}
import java.util.List;
import java.util.ArrayList;
import static java.lang.System.out;
import lombok.Setter;
import lombok.Getter;
import java.awt.Color;
public class Deck {
private static #Getter List<Card> deck = null;
final int SUIT_COUNT = 4;
final int VALUE_COUNT = 13;
public Deck() {
deck = new ArrayList<>();
Card card = null;
int suitIndex = 0, valueIndex = 0;
while (suitIndex < SUIT_COUNT) {
while (valueIndex < VALUE_COUNT) {
card = new Card(Suit.values()[suitIndex], FaceValue.values()[valueIndex]);
valueIndex++;
deck.add(card);
}
valueIndex = 0;
suitIndex++;
}
}
private enum Suit{CLUBS("Clubs", Color.BLACK), DIAMONDS("Diamonds", Color.RED),HEARTS("Hearts", Color.RED), SPADES("Spades", Color.BLACK);
private #Getter String name = null;
private #Getter Color color = null;
Suit(String name) {
this.name = name;
}
Suit(String name, Color color) {
this.name = name;
this.color = color;
}
}
private enum FaceValue{ACE(1), TWO(2), THREE(3),
FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT (8), NINE(9), TEN(10),
JACK(11), QUEEN(12), KING(13);
private #Getter int cardValue = 0;
FaceValue(int value) {
this.cardValue = value;
}
}
private class Card {
private #Getter #Setter Suit suit = null;
private #Getter #Setter FaceValue faceValue = null;
Card(Suit suit, FaceValue value) {
this.suit = suit;
this.faceValue = value;
}
public String toString() {
return getSuit() + " " + getFaceValue();
}
public String properties() {
return getSuit().getName() + " " + getFaceValue().getCardValue();
}
}
public static void main(String...inputs) {
Deck deck = new Deck();
List<Card> cards = deck.getDeck();
cards.stream().filter(card -> card.getSuit().getColor() != Color.RED && card.getFaceValue().getCardValue() > 4).map(card -> card.toString() + " " + card.properties()).forEach(out::println);
}
}

Attempting to add 5 different "cards" to an Array, BUT it is adding 5 of the SAME cards

Please, any help would be greatly appreciated and I'm sure this should be a simply problem.
I am a university student, very new to Java, and attempting some lab course work.
The requirement is quite a simple poker program, which simply needs to:
Generate a deck of 52 cards in a specified order (already functional)
Read in number of players, and player names (already functional)
Deal 5 cards to each (2) players and the dealer from the top of the deck (unsure if functional)
Then display the cards via the following output:
Number of players: 2
Player 1: Homer
Player 2: Marge
Homer has AH 4H 7H 10H KH
Marge has 2H 5H 8H JH AD
Dealer has 3H 6H 9H QH 2D
There are several classes - Dealer, Player, Deck, Hand, Card
Now the output I am getting is:
Number of players: 2
Player 1: Homer
Player 2: Marge
Homer has KH KH KH KH KH
Marge has AD AD AD AD AD
Dealer has 2D 2D 2D 2D 2D
The relevant code for the Dealer class:
public class Dealer {
public static void main(String[] args)
{ new Dealer(); }
private Deck deck = new Deck();
private Hand hand = new Hand();
public ArrayList<Player> players = new ArrayList<Player>();
....
private void deal()
{
for(int i = 0; i < 5; i ++) {
for (Player player : players)
player.add(next());
add(next());
}
} // deal five cards to each player and the dealer
// in the stated order
private void add(Card card)
{ hand.add(card); }
private Card next()
{ return deck.next(); }
private void show()
{
for (Player player : players)
System.out.println(player.getName() + " has " + player.showHand());
System.out.println("Dealer has " + hand.toString());
}
}
Here is the relevant code in the Player class:
public class Player{
private String name;
private int number;
private Hand hand = new Hand();
....
public void add(Card card)
{ hand.add(card); }
public String showHand()
{
String show = "" + hand.toString();
return show;
}
Here is the relevant code in the Hand class:
public class Hand {
private Card[] cards = new Card[5];
....
public void add(Card card)
{
for (int i = 0; i < cards.length; i++)
cards[i] = new Card(card.valueReturn(), card.suitReturn());
}
public String toString()
{
String display = "";
display = cards[0].toString() + cards[1].toString() + cards[2].toString() + cards[3].toString() + cards[4].toString();
return display;
}
}
Here is the relevant code from the Deck class:
public class Deck{
private Card[] cards = new Card[52];
private int i = 0, deck = 0;
private char[] suits = {'H', 'D', 'C', 'S'};
public Deck()
{
for (int suit = 0; suit < 4; suit++){
for(int value = 1; value <= 13; value++){
cards[deck++] = new Card(value, suits[suit]);
}
}
} // create the cards in the stated order and add them to the deck
// This function works by side effect
// It uses the standard "next" pattern you will see next week
public Card next()
{ return cards[i++]; }
}
And finally here is the relevant code from the Card class:
public class Card{
private int cardValue;
private char suit;
public Card(int cardValue, char suit)
{
this.cardValue = cardValue;
this.suit = suit;
}
public String valueDisplay()
{
switch (cardValue)
{
case 1: return "A";
case 11: return "J";
case 12: return "Q";
case 13: return "K";
default: return "" + cardValue;
}
}
public int valueReturn()
{
this.cardValue = cardValue;
return cardValue;
}
public char suitReturn()
{
this.suit = suit;
return suit;
}
public String toString()
{
return valueDisplay() + suit + " ";
}
}
In Hand.add():
for (int i = 0; i < cards.length; i++)
cards[i] = new Card(card.valueReturn(), card.suitReturn());
}
You are creating five new cards with exactly the same values.
One would expect something like (ugly but quick fix):
for (int i = 0; i < cards.length; i++)
if (cards[i] == null) {
cards[i] = card;
return;
}
}
Additionally, for these situations, learning to use the debugger and watch your system status step by step is very useful.

Categories

Resources