During a test case, if I am trying to call upon methods (placeOnTop() for example), which should test which deck the card is from. I am not sure how this constructor is labeling/ or if at all creating different types of decks...
public class StandardDeck implements Deck {
List<Card> cards = new ArrayList<>();
public StandardDeck() {
for (Suit suit : Suit.values()) {
for (int rank = 1; rank <= 13; rank++) {
Card e = new StandardCard(suit, rank, this);
cards.add(e);
}
}
}
public void placeOnTop(Card c) {
cards.add(0, c);
}
public Card takeTop() {
return cards.remove(0);
}
}
You have no 'labeled' field but every time you call StandardDeck() will return a new StandardDeck object which holds its very own cards object, which is of type List.
Related
I'm creating a blackjack game in Java. I need to have multiple players and need a hand class to store the cards that have been pulled from the deck. I have a hand class that functions, but even when I create two separate hand instances, dealing a card to either hand adds them to both hands.
This is my hand class code:
public class Hand2 {
private List<Cards> hand;
private Cards cards;
private int handValue;
public Hand2(List<Cards> hand) {
this.hand = hand;
}
private Cards addCard(Deck deck) {
hand.add(deck.dealCard());
return cards;
}
public int getHandValue() {
for (Cards cards : hand ) {
handValue += cards.getValue();
}
return handValue;
}
public String toString() {
return "Hand: " + hand;
}
And below I am testing it:
public static void main(String[] args) { //Testing
List<Cards> cards = new ArrayList<Cards>();
Deck deck = new Deck();
deck.shuffle();
Hand2 hand = new Hand2(cards);
Hand2 hand2 = new Hand2(cards);
hand.addCard(deck);
hand2.addCard(deck);
hand2.addCard(deck);
System.out.println(hand2);
System.out.println(hand.getHandValue());
System.out.println(hand2.getHandValue());
}
Terminal:
Hand: [Three of Diamonds, Four of Clubs, Jack of Hearts]
17
17
But I get the same hand value for either hand.
As some have already noted, the same list of cards is shared between all hands. Another problem I see in you code is that you're using fields (cards, handValue) when you should use local variables.
Try this:
public class Hand2 {
private final List<Cards> hand = new ArrayList<>();
public Hand2() {
}
private Cards addCard(Deck deck) {
Cards cards = deck.dealCard();
hand.add(cards);
return cards;
}
public int getHandValue() {
int handValue = 0;
for (Cards cards : hand ) {
handValue += cards.getValue();
}
return handValue;
}
#Override
public String toString() {
return "Hand: " + hand;
}
I have a class Card, with fields suit and value from enum files, and I want to initialize arraylist of Card, card has fields such as suit and value but in the end a have an empty list,seems that problem in initializing with these for loops in deck class, but i dont know how to do it correct with values from enums, i just dont want to add one card after another in list instead to make it with loops, (how to initialize arraylist correct)
public enum Suits {
HEART, DIAMOND, CLUB, SPADE;
}
public enum ValuesOfCards {
SEVEN,EIGHT,NINE,TENTH,JACK,QUEEN,KING,ACE;
}
public class Card {
public static String mast;
private static int points;
private Suits suit;
private ValuesOfCards vof;
public Card( Suits suit, ValuesOfCards vof) {
this.suit = suit;
this.vof = vof;
}
#Override
public String toString() {
return "Card{" +
"suit=" + suit +
", vof=" + vof +
'}';
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class Deck {
private ArrayList<Card> deckOfCards;
public Deck() {
this.deckOfCards = new ArrayList<>();
initializeDeck();
}
public void initializeDeck(){
deckOfCards = new ArrayList<>(32);
for (Card c : deckOfCards){
for(Suits s : Suits.values()){
for (ValuesOfCards v : ValuesOfCards.values()){
deckOfCards.add(new Card(s,v));
}
}
}
}
public ArrayList<Card> getDeckOfCards() {
return deckOfCards;
}
public ArrayList<Card> shuffleDeckOfCards(){
ArrayList<Card> list = new ArrayList<>();
Collections.shuffle(list);
return list;
}
#Override
public String toString() {
return "Deck{" +
"deckOfCards=" + deckOfCards +
'}';
}
}
public class Game {
public static void main(String[] args) {
Deck deck = new Deck();
deck.initializeDeck();
System.out.println( deck.getDeckOfCards());
deck.shuffleDeckOfCards();
System.out.println(deck.getDeckOfCards());
}
}
Just remove the line
for (Card c : deckOfCards){
... and the corresponding closing curly bracket.
Iterating over the empty ArrayList deckOfCards means that the following two for loops will not be executed.
I am trying to create a card game of war. However, for this game, there will be an additional card pile called "trump." If either player 1 or 2 has a card that is references in the trump pile then it is an automatic win regardless of the rank. At the moment, I am stuck with the logic.
In a class called CardPile here is the constructor and the methods.
public CardPile(Card[ ] initialCards)
{
pile = new ArrayList<Card>();
for (int i=0; i<initialCards.length; i++)
pile.add(initialCards[i]);
}
public void add(Card aCard)
{
pile.add(aCard);
}
public Card get(int index)
{
return pile.get(index);
}
In my class called TrumpWar
protected CardPile tCard;
protected CardPile cp;
protected CardPile p1;
protected CardPile p2;
public TrumpWar( )
{
cp = new CardPile (new Card[52]);
cp.shuffle();
tCard = new CardPile ();
for (int i=1; i<7; i++) //<---Stuck.
{
tCard.add(tCard.get(i)); //<---error
}
cp.shuffle();
p1 = new CardPile(new Card [26]);
p2 = new CardPile(new Card [26]);
}
When I run the game I am getting a NullPointerException, and I am pretty sure that is because I am not passing anything into the trump pile. When I try to put in an int for the trump ArrayList I would get an error int cannot be converted to Card [].
How can I get the top six cards from the deck of 52 without removing them just storing them as references, and adding them to the trump pile?
Moreover, am I declaring the player1, player2, and the cardpile correctly?
I greatly appreciate the help, thank you.
You should replace with:
for (int i=0; i<6; i++)
{
tCard.add(cp.get(i));
}
You were trying to get cards from the empty tCard.
Note that this code, would still not work until you call cp = new CardPile(array) where array actually contains cards that are not null. Otherwise, tCard.add(cp.get(0)) would not add the reference to the first card, but just null
Card Class:
public class Card {
Integer i = new Integer(0);
Card(Integer is) {
this.i = is;
}
}
CardPile class:
public class CardPile {
ArrayList<Card> pile = null;
public CardPile(Integer no)
{
pile = new ArrayList<Card>();
for (int i=1; i<=no; i++) {
pile.add(new Card(i));
}
}
public void add(Card aCard)
{
pile.add(aCard);
}
public Card get(int index)
{
return pile.get(index);
}
}
TrumpWar class:
public class TrumpWar {
protected CardPile tCard;
protected CardPile cp;
protected CardPile p1;
protected CardPile p2;
public TrumpWar( )
{
cp = new CardPile (52); // only passing the no of cards to be created.
//cp.shuffle();
tCard = new CardPile(52); // only passing the no of cards to be created.
for (int i=1; i<7; i++)
{
tCard.add(tCard.get(i));
}
// cp.shuffle();
p1 = new CardPile(26);
p2 = new CardPile(26);
}
public static void main(String a[]){
new TrumpWar();
}
}
This is the method I'm trying to display which is supposed to be a 4x4 grid of cards. I feel like there is something wrong possible inside the card objects? This is what I get when i try to run what's in printHiddenCard.
edu.cpp.cs.cs141.memgame.QCard#182decdb
edu.cpp.cs.cs141.memgame.StarCard#26f0a63f
edu.cpp.cs.cs141.memgame.PercCard#4361bd48
edu.cpp.cs.cs141.memgame.PercCard#4361bd48
edu.cpp.cs.cs141.memgame.MinusCard#53bd815b
edu.cpp.cs.cs141.memgame.MinusCard#53bd815b
edu.cpp.cs.cs141.memgame.PoundCard#2401f4c3
edu.cpp.cs.cs141.memgame.QCard#182decdb
edu.cpp.cs.cs141.memgame.SlashCard#7637f22
edu.cpp.cs.cs141.memgame.ExclCard#4926097b
edu.cpp.cs.cs141.memgame.StarCard#26f0a63f
edu.cpp.cs.cs141.memgame.PlusCard#762efe5d
edu.cpp.cs.cs141.memgame.PlusCard#762efe5d
edu.cpp.cs.cs141.memgame.SlashCard#7637f22
edu.cpp.cs.cs141.memgame.ExclCard#4926097b
edu.cpp.cs.cs141.memgame.PoundCard#2401f4c3
private static int rows = 4;
private static int columns = 4;
public static Card[][] card = new Card[rows][columns];
public Card[][] printHiddenCard() {
QCard c1 = new QCard();
StarCard c2 = new StarCard();
MinusCard c3 = new MinusCard();
PoundCard c4 = new PoundCard();
ExclCard c5 = new ExclCard();
PercCard c6 = new PercCard();
SlashCard c7 = new SlashCard();
PlusCard c8 = new PlusCard();
List<Card> allCards = Arrays.asList(c1, c2, c3, c4, c5, c6, c7, c8);
List<Card> list = new ArrayList<>(allCards);
list.addAll(allCards);
Collections.shuffle(list);
int counter = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
card[i][j] = list.get(counter++);
System.out.println(card[i][j] + " ");
}
}
return card;
}
This is what one of the card objects look like:
public class QCard extends Card {
public QCard() {
super("?");
}
}
And this is the superclass:
public abstract class Card {
private String cardType = "";
private boolean isFlipped = false;
public Card(String cardType) {
this.cardType = cardType;
}
public String getCardType() {
return cardType;
}
public boolean isFlipped() {
return isFlipped;
}
public void setFlipped(boolean isFlipped) {
this.isFlipped = isFlipped;
}
}
You should override the toString() method in the object you want to print, like this:
public class QCard extends Card {
public QCard() {
super("?");
}
public String toString() {
return "card data";
}
}
The above example will always print card data, so add the fields you want to include in your printOut.
Like #Molske, you need to override the toString() method. I suggest using the #Override annotation. Also take a look at How to override toString() properly in Java?
The toString() method belongs inside the QCard class.
public class QCard extends Card {
public QCard() {
super("?");
}
public String toString() {
return this.cardType; //as long as that's all you need, this will do.
}
}
Every Object you create in Java extends from Object. Every object, has a toString method. That is why you can literally put anything inside System.Out.println(Object). Anything that goes in there it will print whatever is specified in your toString() method. For a new class it is not specified, so it will print out the class name with the hashcode. So, you will need to override the toString method in your Card class only and every derived class will do the same. Here is an example of how to modify this here.
I'm trying to make a card game, and have my card class and my deck class sort of ready, it compiles ok, but when I try to run deck's method makeDeckFull, i get the output: invalidnumberinvalidnumber...
when I use the showDeck method I then see this instead of "hearts", 1
Cards#597f13c5 (i do not know what it means, or how to fix it)
Any help would be kindly appreciated: code below.
Deck Class:
import java.util.ArrayList;
public class Deck
{
private ArrayList<Cards> deck;
private int index;
public Deck()
{
deck = new ArrayList<Cards>();
}
public void makeDeckFull()
{
Cards h1 = new Cards("Hearts", 1);
Cards h2 = new Cards("Hearts", 2);
Cards h3 = new Cards("Hearts", 3);
deck.add(h1);
index ++;
deck.add(h2);
index ++;
deck.add(h3);
index ++;
//Rest of these is left out to conserve space
}
public void showDeck()
{
System.out.println(deck);
}
Card class:
public class Cards
{
private String HEARTS = "Hearts";
private String CLUBS = "Clubs";
private String DIAMONDS = "Diamonds";
private String SPADES = "Spades";
public int number;
public String suit;
public Cards()
{
suit = "unknown suit";
number = 0;
}
public Cards(String suit, int number)
{
setSuit(suit);
setNumber(number);
}
public void setCard(String suit, int number2)
{
setSuit(suit);
setNumber(number2);
}
public void setSuit(String newSuit)
{
if(
(newSuit.equalsIgnoreCase(HEARTS)) ||
(newSuit.equalsIgnoreCase(DIAMONDS)) ||
(newSuit.equalsIgnoreCase(CLUBS)) ||
(newSuit.equalsIgnoreCase(SPADES)))
{
suit = newSuit;
}
else
{
newSuit = "invalid";
System.out.print("Invalid");
}
}
public int getNumber()
{
return number;
}
public String getSuit()
{
return suit;
}
public void setNumber(int newNumber)
{
if(newNumber >0 && newNumber <=10)
{
number = newNumber;
}
else
{
number = 0;
System.out.print("invalid number");
}
}
}
1) You need to override toString() in the Cards class. As is, you are printing out the reference of the object(the gibberish) instead of the "data." You should also override the toString() method of Deck to only print out the list.
2) I'm stepping through your code snippet of makeDeckFull(), and it seems to work fine. Are you sure those three inserts are where you are getting the invalid print statements?