So I only have one problem with my code and that is checking for the same card, because I do not want these cards to repeat. There is no reshuffling or whatsoever, its just random cards being dealt until there is none left. I have no clue on how to do it. Id appreciate some help; whether its theanswe or just a little nudge.
package Card;
import java.util.Random;
public class deckOfCards {
public String[] suite = { "Hearts", "Spade", "Diamonds", "Clubs" };
public String[] faceValue = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
public int deckCount = 0;
private Card[] deck = new Card[52];
public int index;
public void buildDeck() {
for (int i = 0; i < suite.length; i++) {
for (int j = 0; j < faceValue.length; j++) {
deck[deckCount] = new Card(suite[i], faceValue[j]);
deckCount++;
}
}
}
public Card shuffle(){
Random rand = new Random();
int index = rand.nextInt(52);
return deck[index];
}
}
this creates the card and randomizes them
package Card;
public class Card {
private String suite;
private String faceValue;
public Card(){
}
public Card(String suite, String faceValue){
this.setSuite(suite);
this.setFaceValue(faceValue);
}
public String getSuite(){
return suite;
}
//array list
//
public void setSuite(String suite){
this.suite = suite;
}
public String getFaceValue(){
return faceValue;
}
public void setFaceValue(String faceValue){
this.faceValue = faceValue;
}
}
package Card;
public class Driver {
public deckOfCards cards = new deckOfCards();
private Card [] discard = new Card[52];
public static void main(String[] args) {
Driver driver = new Driver();
driver.DealCards();
}
public void DealCards(){
int cardsLeft = 52;
cards.buildDeck();
Card randomCard = new Card();
for (int i = 0; i < 5; i++) {
cardsLeft--;
randomCard = cards.shuffle();
System.out.println(randomCard.getFaceValue() + " of " + randomCard.getSuite());
}
System.out.println("Cards left:" + cardsLeft);
}
}
this deals the cards. Again, any help is appreciated.
I think that what is missing is a method to remove a card from the deck.
Whenever a card is dealt, it needs to be removed, and a new random draw is performed on the remaining deck rather than on all 52 cards each time. This is called a draw without replacement. The current code performs a draw with replacement.
The quickest way to achieve this is to only modify the deckOfCards class:
Use a vector or cards rather than an array. This allows insertions and deletions. In an array, the size cannot be changed: a new array must be created every time, which is very inefficient.
In the shuffle function, instead of only returning a random card, you need to also remove it from the vector.
In the shuffle function, adapt 52 as the deck shrinks.
Related
I'm getting no output and not sure where to go from here.
Design and implement a class called Card, which represents a standard playing card. Each card has a suit and a face value. Then, create a driver class that stores 52 objects of the Card class into an array. Include methods to shuffle the deck, deal a card and report the number of cards left in the deck. The shuffle method should assume a full deck. Your main method should deal each card from a shuffled deck, printing each card (suit and face value) as it is dealt.
Here's what I have so far:
import java.util.Random;
public class card {
public static void main(String[] args) {}
public class deck {
int[] deck = new int[52];
String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};
String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
public void create() {//initialize cards
for (int i = 0; i < deck.length; i++) deck[i] = i;
}
public void shuffle() {//deck shuffle
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;
}
//display all the cards!
for (int i = 0; i < deck.length; i++)
{
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println("Card number " + deck[i] + ": " + rank + " of " + suit);
}
}
}
}
In java, the method main() is where your code will start running. You have nothing in your main method right now:
public static void main(String[] args) {}
To get it to do something, change it to something like this:
public static void main(String[] args) {
deck myDeck = new deck();
myDeck.create();
myDeck.shuffle();
}
As a note, it is good practice in java to name your classes with capital letters.
Here, I tried to write some code for you, its not complete, but provides a framework for you to continue, all you have to do is implement your own shuffle method and add more variables to ranks:
public class CardDriver {
public static void main(String[] args) {
Deck myDeck = new Deck();
myDeck.shuffle();
System.out.println("Dealt cards are:");
myDeck.dealAllCards();
}
}
class Card {
String suite, faceValue;
Card(String suite, String faceValue) {
this.suite = suite;
this.faceValue = faceValue;
}
void printCard() {
System.out.println(faceValue + " " + suite);
}
}
class Deck {
String[] suits = { "Spades", "Hearts", "Diamonds", "Clubs" };
String[] ranks = { "6", "7" };
int count = ranks.length * suits.length;
Card deck[] = new Card[count];
Deck() { // fills out the deck
int index = 0; // this is for simple deck filling
for (int i = 0; i < ranks.length; i++) { // for ranks
for (int j = 0; j < suits.length; j++) { // for suits
deck[index] = new Card(suits[j], ranks[i]);
index++;
}
}
};
void shuffle() { // shuffles the deck
// your code here
}
Card dealCard() { // gives card from deck
if (returnLeft() > 0) {
count--;
return deck[count];
} else return null;
}
int returnLeft() {
return count;
}
void dealAllCards() {
int counter = count;
for (int i = 0; i < counter; i++) {
Card someCard = dealCard();
someCard.printCard();
}
}
}
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] + "]";
}
I would like to first say that this is not homework, but a pet project that I am working on in Java to better understand a complete Java program, and will hopefully be my first attempt at making my own GUI.
That aside, I have a question about creating a hand of cards from my current code. As it stands, I have a main class called DummyRummy, a class for creating cards, a class that creates a standard deck of cards (which includes Jokers and "shuffles" the deck when a new deck is created), and a PlayerHands class. I am strictly working with ArrayLists for all of the code, and the PlayersHands class should return two ArrayLists that will be used. However, when I try to call the PlayerHands() method in the public static void main(), PlayerHands cannot be located for some reason... Here is the code for PlayerHands:
package dummyrummy;
public class PlayerHands {
private Card[] playerOneCards;
private Card[] playerTwoCards;
private int[] value;
PlayerHands(deck d, int round)
{
value = new int[round+3];
playerOneCards = new Card[round+2];
playerTwoCards = new Card[round+2];
//(round+2) is the handsize at any given time
for (int x=0; x<round+3; x++)
{
playerOneCards[x] = d.drawFromDeck(); //fills up one hand.
playerTwoCards[x] = d.drawFromDeck(); //fills up second hand.
}
}
}
Here is the DummyRummy class.
package dummyrummy;
import java.util.*;
public class DummyRummy {
public static void main(String[] args) {
deck testDeck;
testDeck = new deck();
System.out.println(testDeck.getTotalCards());
System.out.println(testDeck.getClass());
int round = 1;
PlayerHands(testDeck, round); //This is where the error is occurring
}//End of arguments
}//End of DummyRummy class
Here is the Card class:
package dummyrummy;
public class Card
{
private short rank, suit;
private static String[] suits = { "Hearts", "Spades", "Diamonds", "Clubs", "Joker" };
private static String[] ranks = { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
private static String[] jokers = {"Joker", "Joker"};
private static String[] ranks2 = {"0", "0"};
public static String rankAsString( int __rank ) {
if (__rank != 0){
return ranks[__rank];
}//End of if statement
return ranks2[__rank];
}//End of rankAsString class
Card(short suit, short rank)
{
this.rank=rank;
this.suit=suit;
}//End of Card Initializer
public #Override String toString()
{
if(suit == 5){
return "Joker";
}//End of if statement that calls jokers
if(rank == 0){
return "Joker";
}
return ranks[rank] + " of " + suits[suit];
}//End of toString method
public short getRank() {
return rank;
}//End of getRank method
public short getSuit() {
return suit;
}//End of getSuit method
}//End of Card
And finally, here is the deck() class:
package dummyrummy;
import java.util.Random;
import java.util.ArrayList;
public class deck {
private ArrayList<Card> cards;
deck()
{
cards = new ArrayList<Card>();
int index_1, index_2;
Random generator = new Random();
Card temp;
short jokerSuit=5;
short jokerRank = 0;
cards.add(new Card(jokerSuit, jokerRank));
cards.add(new Card(jokerSuit,jokerRank));
for (short suit=0; suit<=3; suit++)
{
for (short rank=0; rank<=12; rank++)
{
cards.add(new Card(suit,rank));
}
}//End of for-loop
int deckSize = 54;
for (int i=0; i<1000; i++)
{
index_1 = generator.nextInt( cards.size() );
index_2 = generator.nextInt( cards.size() );
temp = cards.get( index_2 );
cards.set( index_2 , cards.get( index_1 ) );
cards.set( index_1, temp );
}//End of for-loop
}//End of deck()
public Card drawFromDeck()
{
/*
* This method removes the top card of the already shuffled deck.
* The next step to take with this class is put the drawn card into another
* array that represents a players hand.
* This will take two arrays, and must be called depending on what player 'drawsFromDeck'.
*/
return cards.remove( 0 );
}//End of drawFromDeck()
public int getTotalCards()
{
return cards.size();
}//End of getTotalCards()
}//End of class deck
Thank you for your time, and I appreciate any help that may come. I would also be more than happy to provide my other code, if necessary.
EDIT: I have added the class and package above.
PlayerHands(deck, int) is a constructor. Therefore you have to call it like this (in class DummyRummy):
new PlayerHands(testDeck, round);
And since i guess you want to work with the instance you created, you should save the reference to a variable:
PlayerHands playerHands = new PlayerHands(testDeck, round);
PlayerHands(deck d, int round) is not a method, it is a constructor.
To correctly get the two hands, you can use this code:
...
int round = 1;
PlayerHands playerHands = new PlayerHands(testDeck, round); //This creates a new instance of the PlayerHands class
//access the players' hands like this:
Card[] player1Hand = playerHands.playerOneCards; //sets "player1Hand" to the "Card[] playerOneCards" contained in "playerHands"
Card[] player2Hand = playerHands.playertwoCards; //sets "player2Hand" to the "Card[] playerTwoCards" contained in "playerHands"
}//End of arguments
}//End of DummyRummy class
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());
}
}
So I have the code for a deck, but I dont know how to make another class to deal 4 hands of 10 cards each. The other class should print on the screen, in text, 4 hands of 10 random cards. Can someone show me the code on how to accomplish this? Im using blueJ aswell.
Below is my code for the deck:
public class Card
{
public static void main(String[] args)
{
String[] suit = { "Clubs", "Diamonds", "Hearts", "Spades" };
String[] rank = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace" };
int SUITS = suit.length;
int RANKS = rank.length;
int N = SUITS * RANKS;
// initialize deck
String[] deck = new String[N];
for (int i = 0; i < RANKS; i++) {
for (int j = 0; j < SUITS; j++) {
deck[SUITS*i + j] = rank[i] + " of " + suit[j];
}
}
// shuffle the deck
for (int i = 0; i < N; i++) {
int r = i + (int) (Math.random() * (N-i));
String t = deck[r];
deck[r] = deck[i];
deck[i] = t;
}
for (int i = 0; i < N; i++) {
System.out.println(deck[i]);
}
}
}
In the spirit of the game, let's create a hierarchy for handling could work. The largest scope will be the Game, which will delegate the actions to the other classes. We will also have 3 classes: Deck, Dealer, Player.
A Game will have a Dealer, and an ArrayList of Player
A Dealer will have a Deck
A Player will have an ArrayList of String indicating your cards
A Game can then tell a dealer to create and shuffle a deck. You can call a dealCards passing the Players as a param to the dealer who can, based on the number of players, give them the next element in the Deck, and remove that element from the deck.
Once you have dealt all the cards, the game can then tell the players to show their hands, printing the results.
public Dealer{
private Deck deck;
....
public void shuffleDeck(){...}
public void dealCards(List<Player> players){ ...}
}
public Player{
private List<String> hand;
....
public void addToHand(String card){....}
}
Your Card / Deck class should be broken up into two classes.
A Card class would describe a card.
public class Card {
private String rank;
private String suit;
public Card(String rank, String suit) {
this.rank = rank;
this.suit = suit;
}
public String getRank() {
return rank;
}
public String getSuit() {
return suit;
}
#Override
public String toString() {
return rank + " of " + suit;
}
}
A Deck class describes a deck of cards.
public class Deck {
private String[] rank = { "2", "3", "4", "5", "6", "7", "8", "9",
"10", "Jack", "Queen", "King", "Ace" };
private String[] suit = { "Clubs", "Diamonds", "Hearts", "Spades" };
private Card[] cards;
public Deck() {
cards = new Card[suit.length * rank.length];
for (int i = 0; i < rank.length; i++) {
for (int j = 0; j < suit.length; j++) {
cards[suit.length * i + j] = new Card(rank[i], suit[j]);
}
}
}
public Card[] shuffleDeck() {
for (int i = 0; i < cards.length; i++) {
int r = (int) (Math.random() * (cards.length - 1));
Card t = cards[r];
cards[r] = cards[i];
cards[i] = t;
}
return cards;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < cards.length; i++) {
builder.append(cards[i].toString());
builder.append(System.getProperty("line.separator"));
}
return builder.toString();
}
}
Until you understand how these two classes work together, there's no point introducing other classes.
The point of Java, or any object oriented computer language, is to break up your problem into smaller classes that each do one thing and do it well.