Java Deck of Cards List Shuffle - java

Need some assistance on this program I'm working on. Basically a card draw program that creates a deck of cards (card and deck classes), shuffles the created deck, and adds the first card of the shuffled deck to the player's hand. (CardPlayer class).
package cards;
public class Card {
private String[]cardSuit = {"Hearts", "Diamonds", "Spades", "Clubs"};
private String[]cardFaceValue = {"Ace", "King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"};
private int suit;
private int faceValue;
public Card(int newSuit, int newValue) {
suit = newSuit;
faceValue = newValue;
}
public String toString() {
String card = cardFaceValue[faceValue] + " of " + cardSuit[suit];
return card;
}
}
package cards;
import java.util.*;
public class Deck {
ArrayList<Card> deck = new ArrayList<>();
public Deck() {
for(int suit = 0; suit <= 3; suit++) {
for(int value = 0; value <= 12; value++) {
deck.add(new Card(suit,value));
}
}
}
public void Shuffle() {
Collections.shuffle(deck);
}
public Card Deal() {
Card card = deck.get(0);
deck.remove(0);
return card;
}
}
package cards;
import java.util.*;
public class CardPlayer {
Deck deck = new Deck();
ArrayList<Card> hand = new ArrayList<>();
public void getCard(){
hand.add(deck.Deal());
}
public ArrayList<Card> showCards(){
return hand;
}
}
package cards;
public class Demonstration {
public static void main(String[] args) {
Deck deck;
deck = new Deck();
CardPlayer cardPlayer;
cardPlayer = new CardPlayer();
System.out.println("The deck contains the cards: " + deck.deck);
deck.Shuffle();
System.out.println("New order of cards: " + deck.deck);
cardPlayer.getCard();
cardPlayer.getCard();
cardPlayer.getCard();
cardPlayer.getCard();
cardPlayer.getCard();
System.out.println("The card player's hand is now: " + cardPlayer.showCards());
}
}
My issue is that whenever I run the demonstration program, the deck and shuffle work, but when I try to show the cards in the player's hand, it's always the same cards in the order created by the initial deck creation, without the shuffle. How would I go about fixing this issue?

You are having two instances of Deck class - one in the main method and one in the CardPlayer class. The one in the CardPlayer class is used in getCard but that deck isn't shuffled.
Either shuffle the deck created in CardPlayer class. Or pass the shuffled deck created in main to the constructor of the CardPlayer class.

Related

Stack Overflow Error: Using constructors in base class and extended class?

I'm pretty new to Java but I'm trying to fix this stack overflow error. Essentially, I'm trying to create a deck of cards using a constructor call in main: Deck newDeck = new Deck();
Then, creating the Cards array of 52 elements (cards) in the base class "Deck", and populating the array at each index with two int values, representing the rank and suit of each card.
I believe the stack overflow error is occurring due to a recursive constructor call between the base class and extended class, though I might be wrong. Can anyone provide a suggestion on how to fix this error, or populate the Cards array in a different way? The base class and extended class format is necessary for my project. Thanks.
Error:
Exception in thread "main" java.lang.StackOverflowError
at java.base/java.util.Random.<init>(Random.java:105)
at Deck.<init>(Deck.java:12)
at Cards.<init>(Cards.java:19)
at Deck.<init>(Deck.java:27)
at Cards.<init>(Cards.java:19)
at Deck.<init>(Deck.java:27)
at Cards.<init>(Cards.java:19)
at Deck.<init>(Deck.java:27)
at Cards.<init>(Cards.java:19)
at Deck.<init>(Deck.java:27)
at Cards.<init>(Cards.java:19)
Main:
import java.util.Random;
import java.util.Scanner;
public class PokerProgram {
public static void main(String[] args) {
// CREATING SCANNER OBJECT
Scanner scnr = new Scanner(System.in);
Random random = new Random();
// INITIALIZING VARIABLES
String play = "y";
double blind = 10;
double playerBalance = 1000;
double playerBet;
double pot;
int playerScore = 0;
int compScore = 0;
String[] Hands = {"Equal hand", "One Pair", "Two Pair", "Three of a Kind", "Straight", "Flush", "Full House", "Four of a Kind", "Straight Flush", "Royal Flush"};
Deck newDeck = new Deck();
Base class:
import java.util.Random;
public class Deck{
// Creating Random object
Random random = new Random();
// FIELD VARIABLES
public static int handScore;
public static int cardValue;
private static final Cards[] newDeck = new Cards[52];
// CONSTRUCTORS
// For Deck
public Deck () {
int i = 0;
for (int j = 0; j < 13; j++) {
for (int k = 0; k < 4; k++) {
newDeck[i] = new Cards(j, k);
i++;
}
}
}
Extended Class :
public class Cards extends Deck{
// Field Variables
private int rank;
private int suit;
// Rank and Suit Arrays
private static String [] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
private static String [] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
// CONSTRUCTOR
public Cards (int rank, int suit) {
this.rank = rank;
this.suit = suit;
}
Cards extend Deck. Upon creating a Deck you invoke the Cards constructor which happen to be a Deck which invokes the Cards constructor...

Basic Poker Program - Printing Deck

I'm working on a poker project that just deals the 5 top cards from a shuffled deck and lets the user to reject all, some, or none. I understand that there should be ideally 2-3 classes, one with the actual main and the other two being the card and deck. I have created the Deck class and a very basic Tester program that is just supposed to print the shuffled cards. However, when I print the deck, I get something along the lines of "Deck####d##a". What am I doing wrong?
import java.util.Random;
public class Deck {
// Constructing a deck from two arrays
String[] suit = { "Clubs", "Diamonds", "Hearts", "Spades" };
String[] rank = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
String[] deck = new String[suit.length * rank.length];
// Storing public variables
int suits = suit.length;
int ranks = rank.length;
int deckSize = deck.length;
public Deck()
{
for(int i = 0; i < suits; i++)
{
for(int j = 0; j < ranks; j++)
{
deck[ranks*i + j] = rank[j] + " of " + suit[i];
}
}
}
// Fisher-Yates Shuffle
public void shuffle()
{
Random rand = new Random();
for (int i = 0; i < deckSize; i++)
{
int x = rand.nextInt(deckSize);
String temp = deck[x];
deck[x] = deck[i];
deck[i] = temp;
}
}
}
And the tester class:
import java.util.Scanner;
public class DeckTester {
public static void main(String[] args) {
Deck deck = new Deck();
System.out.println(deck);
}
}
Output: Deck####d###a
You're seeing the default `toString() method from the Object class, and you're finding that it's not too helpful. You're also not creating a Card or a true Deck class and so you can't give any class a decent toString() method.
Solutions:
Create a Card class.
Give it a rank and a value field.
Give it a toString() method.
Create a Deck class
Give it a collection of Cards.
Give it a decent toString() method.
e.g.,
// for Deck
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Card card: cards) {
sb.append(card.toString() + ", ");
}
return sb.toString();
}
Printing an object calls its toString() method. If your class or any of its ancestors do not override toString(), it calls the default, which is the toString() method of Object.
But the default toString() is not very clever - it just gives you the name and hash code of the deck.
So it is very recommended, for any class that you're going to print (and even for those you don't, but you may want to debug) to override the toString() method. In the overridden method, you should construct a string that represents the contents of your class. It could be as simple as calling Arrays.toString() in your case.
Also, note that you have defined a shuffle() method, but you are not actually calling it from anywhere, so once you do succeed in printing your deck, it will not be shuffled.

Printing Objects in Stack [Java]

So the project is to make a deck of cards, create methods to shuffle and deal the cards and compare.
Not even going that far, I'm having an issue displaying the contents of the Stack.
I'm getting the output randomdeck.Card#10ed7f5c but with different addresses for every card.
I did a size check and there are 52 objects in the stack, meaning I filled it and it actually exists.
Looking at my Card constructor I know I'm not actually filling it with the cSuit/cRank String array. My original code had it so I would fill it with the integers then have a method to read those integers and put those integers into a the String arrays displaying the String.
But I had to partially scrap that because it was just an array, not a Stack.
If there was a way to directly pass the String array into the Card so what it's pushed into the Deck I could pop it off and instantly see the contents that would be great. But I fear that's not possible and I'm failing to grasp something fundamental about Stacks/Queues.
I wish I kept my old code completely intact to show what I was previously doing, but I don't think it matters at this point.
Here is my current code.
package randomdeck;
//import java.util.Arrays;
import java.util.Stack;
public class Card
{
int Suit;
int Rank;
public Card(int Rank, int Suit)
{
this.Suit=Suit;
this.Rank=Rank;
}
public String[] cSuit = new String[4];
{
cSuit[0]="Hearts";
cSuit[1]="Spades";
cSuit[2]="Diamonds";
cSuit[3]="Clubs";
}
public String[] cRank = new String[13];
{
cRank[0]="Ace";
cRank[1]="2";
cRank[2]="3";
cRank[3]="4";
cRank[4]="5";
cRank[5]="6";
cRank[6]="7";
cRank[7]="8";
cRank[8]="9";
cRank[9]="10";
cRank[10]="Jack";
cRank[11]="Queen";
cRank[12]="King";
}
void displayCard()
{
//System.out.println(cRank + " Of " + cSuit);
System.out.println(cRank[Rank] + " of " + cSuit[Suit]);
}
}
Here is the Deck class
package randomdeck;
//import java.util.Arrays;
import java.util.Stack;
public class Deck
{
int cardNum=0;
//static int DeckSize=52;
Stack<Card> Deck = new Stack<Card>();
public Deck()
{
for(int rank=0; rank<13; rank++)
{
for(int suit=0; suit<4; suit++)
{
Deck.push(new Card(rank,suit));
System.out.println(Deck.peek());
//System.out.println(Deck.size());
//Deck[cardNum] = new Card(rank,suit);
//cardNum++;
}
}
}
public void Peek()
{
System.out.println(Deck.peek());
}
public void Size()
{
System.out.println(Deck.size());
}
}
Here is the last class
package randomdeck;
//import java.util.Arrays;
import java.util.Stack;
public class RandomDeck {
public static void main(String[] args)
{
Deck testDeck= new Deck();
testDeck.Size();
}
}
I think you want to add a toString() method to your Card class like so,
public String toString() {
return cRank[Rank] + " of " + cSuit[Suit];
}
Also, I think you should rename Rank and Suit to rank and suit respectively.
Finally, a more idiomatic String array initialization would be
public String[] cSuit = new String[] { "Hearts",
"Spades", "Diamonds", "Clubs" };
public String[] cRank = new String[] { "Ace", "2",
"3", "4", "5", "6", "7", "8", "9", "10", "Jack",
"Queen", "King" };

Java ArrayList Deck Class

This program is supposed to use ArrayList to create a deck of cards. The user enters how many cards to draw and those cards are printed, then the rest of the cards that are remaining in the deck are printed. I got the user's cards to print but I cant figure out how to get the remaining cards in the deck to print. Any help would be appreciated.
public class Card
{
private int type, value;
private String[] cardType = {"Clubs", "Spades", "Diamonds", "Hearts"};
private String[] cardValue = {"Ace", "King", "Queen", "Jack", "10",
"9", "8", "7", "6", "5", "4", "3", "2"};
public Card(int types, int values)
{
type = types;
value = values;
}
public String toString()
{
String finalCard = cardValue[value] + " of " + cardType[type];
return finalCard;
}
}
import java.util.Random;
import java.util.ArrayList;
public class Deck
{
private ArrayList<Card> cards;
public Deck()
{
cards = new ArrayList<Card>();
for(int a =0; a<=3; a++)
{
for(int b =0; b<=12;b++)
{
cards.add(new Card(a,b));
}
}
}
public Card drawRandomCard()
{
Random generator = new Random();
int index = generator.nextInt(cards.size());
return cards.remove(index);
}
public String toString()
{
String result = "Cards remaining in deck: " + cards;
return result;
}
}
import java.util.Scanner;
public class CardProgram
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
Card C;
Deck deck = new Deck();
System.out.println("Enter number of cards to be dealt: ");
int numberCards = scan.nextInt();
System.out.println("Cards drawn: ");
for(int i=0; i<numberCards; i++)
{
C = deck.drawRandomCard();
System.out.println(C.toString());
}
//C = deck.toString();
//System.out.println(cards.toString());
// System.out.println(C.toString());
}
}
I think this should do your work
System.out.println(deck.toString());
//System.out.println(deck); // Note : this will also work
Though I think creating a new method remainingCard and returning the cards ArrayList makes sense rather than Overriding toString with remaining cards.
for(int i=0; i<deck.cards.size(); i++)
{
System.out.println(deck.cards.get(i).toString());
}
Try this for loop right after you have a for loop printing out the cards you have drawn
You have a deck in the main method...a deck has cards...you draw some cards out of your deck....then you say deck.cards which gives you the decks array list of cards...then you say .get(i) to get each card in that deck...and finally .toString() to print out the content of the card
Note: you would have to make the private array list of cards in your deck class public or add a public getter method in the deck class to get the arraylist of cards...

Extending class, implicit super constructor is undefined error

I am using Java. I have got 2 classes
class Card
class Deck extends Card
I get a constructor error.
I have to make a blackjack game for college and Deck class has to be extended.
What can I do to solve this problem?
class Card
{
int rank, suit;
String[] suits = { "hearts", "spades", "diamonds", "clubs" };
String[] ranks = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
Card(int suit, int rank)
{
this.rank=rank;
this.suit=suit;
}
String toString()
{
return ranks[rank] + " of " + suits[suit];
}
int getRank() {
return rank;
}
int getSuit() {
return suit;
}
}
class Deck extends Card{
ArrayList <Card> cards;
int numberdeck;
Deck()
{
cards = new ArrayList<Card>();
for (int a=0; a<=3; a++)
{
for (int b=0; b<=12; b++)
{
cards.add( new Card(a,b) );
}
}
}
Card drawFromDeck()
{
Random generator = new Random();
int index= generator.nextInt( cards.size() );
return cards.remove(index);
}
int getTotalCards()
{
return cards.size();
}
}
The constructor in the subclass is supposed to invoke the corresponding constructor in the super class, but, such a constructor is not found in your code.
Either add a constructor that takes no argument to the superclass or make the constructor in the subclass invoke the constructor in the superclass.
You can invoke the constructor of the superclass using super(0, 0); at the beginning of the body of the constructor of the subclass.
Deck really ought not extend Card. Sub-classing encodes an is-a relationship. A lion is an animal, so Lion extends Animal. You can tell that sub-classing is inappropriate because the getRank() and getSuit() methods make no sense on an entire deck of cards.
A deck of cards is not a card; a deck contains other cards. The contains relationship is already represented by the ArrayList <Card> cards array.

Categories