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];
}
}
Related
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...
So I am building up to a card game but, but I am having some trouble building the deck of cards and OOP in general so I was wondering if I could get some help. This is what I have so far.
public class Card {
String[] rank = {"Ace", "2", "3", "4", "5", "6",
"7", "8", "9", "10", "Jack", "Queen", "King"};
String suit;
int value;
String color;
public Card(String suit, int value) {
this.suit = suit;
this.value = value;
if (suit.equals("Hearts") || suit.equals("Diamonds")) {
color = "red";
} else {
color = "black";
}
}
public int getValue() {
return value;
}
public String getColor() {
return color;
}
public String getSuit() {
return suit;
}
public String getName() {
name = rank[(value - 1)];
return name;
}
public String toString() {
return name + " of " + suit;
}
}
The class for my deck of cards (so far) is as follows:
public class Deck {
String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
static String[] cards = new String[52];
public Deck() {
int index = 0;
for (int i = 0; i < 4; i++) {
// For each value of card with this suit.
for (int j = 1; j <= 13; j++) {
Card card = new Card(suits[i], j);
cards[index] += card;
index += 1;
}
}
}
public static void all() {
for (int i = 0; i < cards.length; i++) {
System.out.println(cards[i]);
}
}
}
So my question was when I print out the cards, I get something like
nullnull of Hearts
nullnull of Hearts
nullnull of Hearts
nullnull of Hearts....
nullnull of Diamonds
nullnull of Diamonds
nullnull of Diamonds
nullnull of Diamonds
nullnull of Diamonds... etc.
Why am I getting these nulls? What am I doing wrong? Also, any other tips to improve my code would be greatly appreciated.
Your problem is the following line of code from the constructor of class Deck.
cards[index] += card;
You need to remove the +.
An array of objects in java is always initialized such that every element is null. Hence you are appending a card to null.
If you would step through your code with a debugger, you would have discovered that. All good IDEs have a debugger. You should learn to use it.
Note that the code in your question does not compile but I figured out how to fix it since the problems are minor.
For the sake of completeness. Here is your code with my fixes. Compare it to your code.
Class Card
public class Card {
String[] rank = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
String suit;
int value;
String color;
public Card(String suit, int value) {
this.suit = suit;
this.value = value;
if (suit.equals("Hearts") || suit.equals("Diamonds")) {
color = "red";
}
else {
color = "black";
}
}
public int getValue() {
return value;
}
public String getColor() {
return color;
}
public String getSuit() {
return suit;
}
public String getName() {
String name = rank[(value - 1)];
return name;
}
public String toString() {
return getName() + " of " + suit;
}
}
Class Deck
(Note that I added a main() method just for testing purposes.)
public class Deck {
String[] suits = {"Hearts", "Diamonds", "Clubs", "Spades"};
Card[] cards = new Card[52];
public Deck() {
int index = 0;
for (int i = 0; i < 4; i++) {
// For each value of card with this suit.
for (int j = 1; j <= 13; j++) {
Card card = new Card(suits[i], j);
cards[index] = card;
index += 1;
}
}
}
public void all() {
for(int i = 0; i < cards.length; i++) {
System.out.println(cards[i]);
}
}
public static void main(String[] args) {
new Deck().all();
}
}
Your example does not look complete, as I don't see name field in Card class defined. But what I see is that name is initialized in getName methods. I guess you don't initialize it.
Either use getName in toString:
public String toString(){
return getName() + " of " + suit;
}
or initialize name in the constructor: name = rank[(value - 1)]
Prefer initialization in the constructor, otherwise if you refer to name in some other place you can get the same issue.
I have a problem in my Java program Black Jack. I can't seem to work out my "this.cards[o++]" as it always goes into ArrayIndexOutOfBoundException. But if I change it into "this.cards[j] OR this.cards[i]" it doesn't get an error but I know its wrong.
Here's the errors for:
**this.cards[o++]**
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 13
at CardDeck.<init>(CardDeck.java:18)
at BlackJoker.main(BlackJoker.java:17)
**this.cards[j]**
null
Kc
Qc
8c
null
null
**this.cards[i]**
null
Ac
Ah
null
null
Ad
Here's my code:
import java.util.*;
public class CardDeck
{
private String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10",
"J", "Q", "K", "A" };
private char[] suits = {'s','h','d','c'};
private Card[] cards = new Card[13];
private int currentCard;
CardDeck()
{
Card newCard;
int o = 0;
for(int i=0; i<this.suits.length; i++)
{
for(int j=0; j<this.ranks.length; j++)
{
this.cards[o++] = new Card(this.ranks[j], this.suits[i]);
}
}
this.shuffle();
}
public void testing() //just for testing
{
System.out.println(this.suits[0]);
}
public Card drawNextCard()
{
return cards[currentCard++];
}
private void shuffle()
{
Card[] tmp = new Card[13];
for (int i = 0; i < cards.length; i++)
{
int index = (int)(Math.random() * (cards.length));
tmp[index] = cards[i];
cards[i] = cards[index];
cards[index] = tmp[i];
}
}
}
public class BlackJoker
{
public static void main(String[] args)
{
CardDeck cardDeck = new CardDeck();
//cardDeck.testing();
System.out.println(cardDeck.drawNextCard());
System.out.println(cardDeck.drawNextCard());
System.out.println(cardDeck.drawNextCard());
System.out.println(cardDeck.drawNextCard());
System.out.println(cardDeck.drawNextCard());
System.out.println(cardDeck.drawNextCard());
//System.out.println(cardDeck.drawNextCard());
}
}
You are allocating an array that will only hold 13 cards:
private Card[] cards = new Card[13];
Try making it 52:
private Card[] cards = new Card[52];
In addition to increasing the card array length , In the shuffle function , you are calculating the index using Math.random, that causes ArrayIndexOutbound exception if the index is beyond the card array length. You need to handle this.
This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 6 years ago.
How can i improve on my code such that it would not produce hash values when i call my print method? I reckon the #2a.... etc behind the Card keyword are hash values.
My codes produce the following output when i call my method to print them out:
run:
card.Card#2a139a55
card.Card#15db9742
card.Card#6d06d69c
card.Card#7852e922
My code:
public class Card {
/**
* #param args the command line arguments
*/
static String[] rank = {"2","3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
static String[] suit = {"Spades","Hearts", "Clubs", "Diamonds"};
public Card(String r, String s)
{
}
public static void init(Card[] deck)
{
for(int x = 0; x<deck.length; x++)
{
Card newCard = new Card(rank[x%13], suit[x/13]);
deck[x] = newCard;
}
}
public static void swap(Card[] deck, int a, int b)
{
Card temp = deck[a];
deck[a] = deck[b];
deck[b] = temp;
}
public static void shuffle(Card[] deck)
{
Random rnd = new Random();
for(int x = 0; x<deck.length; x++)
{
swap(deck, x, (rnd.nextInt(deck.length)));
}
}
public static void print(Card[] deck)
{
for(int x = 0; x<deck.length; x++)
System.out.println(deck[x]);
}
public static void main(String[] args) {
// TODO code application logic here
Card[] deck = new Card[52];
init(deck);
print(deck);
}
You should override the toString() method of your class Card.
public String toString()
{
return "I want to print this";
}
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...