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...
Related
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.
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...
I am trying to create mutliple methods which all use data from the same array. The method createDeck works fine. But for the other two methods, they just return null. Is there a way to fix this?
class Deck
{
private static String[] suit = {"Spades", "Diamonds", "Clubs", "Hearts"};
private static String[] rank = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen",
"King", "Ace"};
private static String[] deck = new String[52];
// create deck
static void createDeck()
{
for (int i = 0; i < deck.length; i++)
{
deck[i] = rank[i % 13] + " of " + suit[i / 13];
System.out.println(deck[i]);
}
}
// shuffle deck
static void shuffleDeck()
{
// shuffle the deck
for (int i = 0; i < deck.length; i++)
{
int index = (int) (Math.random() * deck.length);
String temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
// print the shuffled deck
for (String u : deck)
{
System.out.println(u);
}
}
static void findTop()
{
System.out.println(deck[0]);
}
}
One way to solve this is to directly fill the array using a static initalizer which gets called automatically.
Just add this code block after the decalration of the array at the beginning of the class
private static String[] deck = new String[52];
static {
for (int i = 0; i < deck.length; i++)
{
deck[i] = rank[i % 13] + " of " + suit[i / 13];
System.out.println(deck[i]);
}
}
And of course remove the method createDeck since it is no longer needed. The following code will now be executed correctly and printing values from the array
public static void main(String[] args) {
Deck.findTop();
Deck.shuffleDeck();
}
See this question for more info on static initializer
If it is used in your object, you can put the Array inside the constructor of an object.
public class Deck {
String[] deck;
public Deck(){
this.deck = new String[52];
}
}
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.
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" };