Having problems with black jack card game in java - java

I posted this earlier and the majority of my questions were answered but I am just having 1 last error in my code.
SO basically I am making a game of black jack in java. I have a card class, a deck class and my main. The problem I am having is in my main. In my deck class I create a deck of 52 cards in an arraylist. I then have a method deal that will take the top card and add it into the hand arraylist which is the cards that are in the users hands. Once the user doesn't want to continue anymore the cards stop being dealt. The very last part of my main takes the values in the hand arraylist and adds them up and compares them to 21 to see if the user went over or not. I realize that I am trying to hold a Card value in the int total but what would I use to hold the values in the arraylist so that I can compare them? Any help/suggestions or advice is appreciated
the error that I'm getting on this code is this:
1 error found:
File: E:\Documents\Java Files\Assignment 3\CardGameTester.java [line: 33]
Error: Type mismatch: cannot convert from Card to int
the part of my main that is in question is this:
int total;
for(int index = 0; index <= hand.size(); index++)
{
total = hand.get(index);
}
System.out.println("Your total value for you cards are: " + total);
if(total == 21){
System.out.println("Congrats, you have won for not going over 21");
}
else
{
System.out.println("Sorry, you lose for going over 21");
}
for anyone who is curious here is my Card and Deck classes:
public class Card
{
private int rankValue, suitValue;
private String ranks[] = {"Hearts", "Clubs", "Spades", "Diamonds"};
private String suits[] = {"Ace", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
public Card(int rank, int suit)
{
rankValue = rank;
suitValue = suit;
}
public String convertToString(int rank){
return ranks[rank];
}
public void setRank(int rank){
rankValue = rank;
}
public void setSuit(int suit){
suitValue = suit;
}
public int getRank(){
return rankValue;
}
public int getSuit(){
return suitValue;
}
public String toString(){
String name = ranks[rankValue] + " of " + suits[suitValue];
return name;
}
}
Deck class:
import java.util.ArrayList;
import java.util.Collections;
public class Deck
{
private ArrayList<Card> cards = new ArrayList<Card>();
public Deck()
{
for(int a = 1; a <= 4; a++)
{
for(int b = 1; b <= 13; b++)
{
Card c = new Card(a,b);
cards.add(c);
}
}
shuffle();
}
public void shuffle(){
Collections.shuffle(cards);
}
public Card deal(){
int index = 0;
Card c = cards.remove(index);
index++;
return c;
}
}

cannot convert from Card to int
The card class might have a int value field that is accessed by getValue().

Your Card class should have a method called something like intValue or getValue to get the integer value of the card. Then call it on every card and add up the returned numbers. Dealing with soft aces will be a little tricky though.
Also, use foreach, rather than manual indexing.
int total;
for(Card card: hand)
{
total += card.value();
}

The message is telling you that a Card is not an "int", which of course is perfectly true. I would suggest that you read up about object oriented programming. The basic idea is classes contain properties which may be simple types like int or other instances of other classes. Different classes have different sets of operations and properties. The compiler knows that a Card has certain operations and for that reference only allows Cards or something that looks like a Card. I dont want to go into further details as there are many great discussions and tutorials on the internet that can easily be found.

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, deck of cards, card class, need to get it all working together

I have an assignment for my summer class. FYI, I'm super new to programming in general and this is my first time with java and it's a summer class so it's going super fast (please be nice!) lol.
Basically I started writing my code in one class, then I split it up into a Card class and a DeckOfCards class and I now need to figure out how to get it all to work together. I get a little confused with calling methods sometimes, especially when separate classes are in play. I think I just need a method to deal out five cards that also tells how many cards are left in the deck. Then get it all working together correctly. Also, I need a toString method but I honestly do not know how to go about that. Any help is greatly appreciated! If you could help explain things too that would be awesome! I think I have everything SO FAR correct but I could be wrong and I'm sure there are better ways to write the code, I'll take any suggestions for a cleaner look too. FYI, I think the prof would rather arrays then enums since we're dealing with arrays right now.
Here are the directions...
Design and implement a class called Card that represents a standard playing card. Each card has a suit and a face value. Then create a class called DeckOfCards that stores 52 objects of the Card class. Include methods to shuffle the deck, deal a card and report the number of cards left in the deck. The shuffle methods should assume a full deck. Create a driver class (CardsGame) with a main method that deals five cards from the shuffled deck, printing each card as it is dealt. Make sure to write the appropriate constructors, getters, setters, toString and other methods as required for both classes.
The main class, CardsGame Class
import java.util.Scanner;
public class CardsGame {
public static void main (String [] args) {
}
}
Card Class
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 int rank;
private int suit;
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[ cardRank ] );
}
public String toString() {
return ( Rank[ cardRank ] + Suit[ cardSuit ] );
}
}
DeckOfCards Class
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
}
}
How do I get it all to work together?
How do I instantiate the deck of cards?
To instantiate the deck of cards, use the following code DeckOfCards deck = new DeckOfCards();
How do I call the methods of this class?
To call a method in the class DeckOfCards, you first need to instantiate an object of type DeckOfCards (which we just did). Then, you simply refer to the instantiated variable name (deck), put a ., and call the name of the method.
public class CardsGame {
public static void main (String [] args) {
DeckOfCards deck = new DeckOfCards();
//call shuffle
deck.shuffle();
}
}
DeckOfCards class structure
Currently, I don't believe the methods you wrote in DeckOfCards are accessible. function shuffle() should be placed outside of the constructor. If you wish to call it inside your constructor, simply call shuffle();
toString
Here is an example toString method for DeckOfCards
(note this should be placed after the constructor)
#Override public String toString() {
return "DeckOfCards";
}

How to Bogo sorting playing cards value?

The first class "cards" creates cards of different ranks and suits. It also includes a method to compare ranks of 2 cards.
public class card implements Comparable
{
private int suit;
private int rank;
public card(int card)
{rank = card % 13;
suit = card / 13;
}
public int getSuit()
{return suit;}
public int getRank()
{ return rank;}
public int compareTo(Object other)
{
card c = (card) other;
if (getRank() > c.getRank())
return 1;
else if (getRank() <c.getRank())
return -1;
return 0;
}
public String toString()
{
String[] ranks = {"2", "3", "4" , "5", "6", "7" , "8", "9" , "10", "Jack", "Queen", "King",
"Ace" };
String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};
return ranks[getRank()] + " of " + suits[getSuit()];
}
}
The second class gives me 10 random cards in the hand1 ArrayList.
import java.util.Collections;
import java.util.ArrayList;
import java.util.Random;
public class Gin
{
public static void main(String []args)
{
ArrayList<card> deck = new ArrayList<card>();
Random r = new Random();
for (int i = 0; i <52; i++)
deck.add (new card(i));
//deal 10 cards to a hand from the deck
ArrayList<card> hand1 = new ArrayList<card>();
card c;
for (int i=0; i<10;i++)
{
int pickACard = r.nextInt (deck.size());
c = deck.remove(pickACard);
hand1.add(c);
System.out.println (c);
}
System.out.println (" ");
}
}
If the hand is not in order I'll use Collections.shuffle(hand1) to bogo sort.But how can I check if
element 0 >= element 1 >= element 2>= element 3>= ect... in hand1? I tired writing a smaller
portion of the code that will compare element 0 and 1 in hand1 below:
if(hand1.get(0).compareTo(hand1.get(1)== 1))
System.out.print(hand1.get(0));
else if (hand1.get(0).compareTo(1)==-1)
System.out.print (hand1.get(1));
else
System.out.print ("Equal");
However I got the error "Incompatible types: card and int. Any help would be appreciated.
if(hand1.get(0).compareTo(hand1.get(1)== 1))
Here you're comparing hand1.get(0), which is the first alement of the list of cards, and is thus a card, with hand1.get(1)== 1. What you want is
if (hand1.get(0).compareTo(hand1.get(1)) > 0)
(because a comparison can return any positive number to mean first > second).
else if (hand1.get(0).compareTo(1)==-1)
And not you're comparing hand1.get(0), which is the first alement of the list of cards, and is thus a card, with1`, which is an int. It doesn't make sense either. You want
else if (hand1.get(0).compareTo(hand1.get(1)) < 0)
Also, note that yoy should use generics for your class. It should be declared as a Comparable<card>, and not as a raw Comparable:
public class card implements Comparable<card>
public int compareTo(card other) {
...
}
}
And of course, it should also respect the Java naming conventions: classes start with an uppercase letter:
public class Card implements Comparable<Card>
public int compareTo(Card other) {
...
}
}

Card Class java

I am making a card and deck class that make a deck of 52 cards and the cardProgram class is the driver.The Card class has a property for the card's suit and a property for the value (Ace, King,10,9, etc). It also has a constructor for the properties and a toString representation for the card. The deck class ahs a property to represent cards in the deck and a constructor wit no parameters that will create 52 cards and add them to the deck, a method to randomly remove a card and return the card object that was drawn, and a toString to show the cards contained in the deck. Tha main will create the deck of cards. The user enters the number they would like to draw. Each card they draw is printed and then the cards remaining in the deck will be printed. I am using ArrayList to do this and I would just like to know if I am going in the right direction. I keep getting errors and I know there is something wrong in my classes. I have never used ArrayList before so any information 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;
//this.value = value;
}
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()
{
for(int a =0; a<=3; a++)
{
for(int b =0; b<=12;b++)
{
cards.add(drawRandomCard());
}
cards.addAll(cards);
}
}
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: ");
C = deck.drawRandomCard();
System.out.println(C.toString());
}
}
In terms of design guidelines there a couple things I would suggest:
1) Keep your local variables lower case (Card c)
2) Think about creating Java Enum for both rank and suit.
Your deck creation for loops would then look something like this:
cards = new ArrayList<Cards>();
for(Rank k : Rank.values())
for(Suit s: Suit.values())
cards.add(new Card(k,s));
3) An error you will get is probably an ArrayOutOfBoundsException since your Deck constructor is calling drawRandomCards() when initially cards is empty. Good Luck!
4) As was pointed out, you also haven't initialized cards yet.
Looking at your code, I think you are getting NullPointerException as you are talking about error.
You have defined private ArrayList<Card> cards; but you never initialized it in your Deck Class.
It should go something like
private ArrayList<Card> cards; // currently its null
cards = new ArrayList<Card>(); // initializing here and no more null
I think this is what you need. So what have I changed?
1.
When you initialised the deck, you need to populate the ArrayList with a card for each number combination. This is achieved by cards.add(new Card(a,b));. I've also removed the cards.addAll(cards) because you were adding the whole list to itself.
edit: oh yeh, and I initialised the ArrayList as well. That bits kind of important!
2.
In your CardProgram, you got the number of cards you wanted to draw, so I looped that many times calling, drawRandomCard().
3.
I haven't printed the remaining cards, that's up to you to figure out.
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;
//this.value = value;
}
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(52);
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());
}
System.out.println(C.toString());
}
}

Categories

Resources