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.
Related
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.
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();
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have most of my program, but I have hit the wall near the end, and I would love the help!
I have to write a program that picks four cards out of a deck of 52 and computes the sum. An Ace, King, Queen, and Jack represent 1, 13, 12, and 11 respectively. The program should display the number of pick that yields the sum of 24.
What I have so far:
public class Exercise07_29 {
public static void main(String[] args){
//initialize everything
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"};
//initialize the cards
for(int i = 0; i< deck.length; i ++)
deck[i] = i;
//shuffle the cards
for(int i = 0; i < deck.length; i++){
//generate an index randomly
int index = (int)(Math.random() * deck.length);
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
//display the four cards
for(int i = 0; i < 4; i++){
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println(rank + " of " + suit);
}
//initialize Ace Jack Queen King
int Ace, Jack, Queen, King;
//Assign a point vale to each
int[] points = {Ace = 1, Jack = 11, Queen = 12, King = 13};
//add the cards together and show output
}
}
I tried a loop for the addition, but am having trouble when it comes to adding a random output together....
Any and all help would be greatly appreciated! :)
import java.util.*;
public class Exercise07_29 {
public static void main(String[] args){
//initialize everything
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"};
List<String> pickedCards = new ArrayList<String>();
//initialize the cards
for(int i = 0; i< deck.length; i ++)
deck[i] = i;
//shuffle the cards
for(int i = 0; i < deck.length; i++){
//generate an index randomly
int index = (int)(Math.random() * deck.length);
int temp = deck[i];
deck[i] = deck[index];
deck[index] = temp;
}
//display the four cards
for(int i = 0; i < 4; i++){
String suit = suits[deck[i] / 13];
String rank = ranks[deck[i] % 13];
System.out.println(rank + " of " + suit);
pickedCards.add(rank);
}
//initialize Ace Jack Queen King
int Ace, Jack, Queen, King;
//Assign a point vale to each
int[] points = {Ace = 1, Jack = 11, Queen = 12, King = 13};
//add the cards together and show output
int sum = 0;
int jack = 11;
int queen = 12;
int king = 13;
int ace = 1;
Iterator<String> iterator = pickedCards.iterator();
while(iterator.hasNext()) {
String rank = iterator.next();
System.out.println(rank);
if(rank.equalsIgnoreCase("Jack")){
sum = sum+jack;
}
else if(rank.equalsIgnoreCase("Queen")){
sum = sum+queen;
}
else if(rank.equalsIgnoreCase("King")){
sum = sum+king;
}
else if(rank.equalsIgnoreCase("Ace")){
sum = sum+ace;
}
else {
sum = sum+Integer.parseInt(rank);
}
}
System.out.println("Sum of picked cards is : "+sum);
}
}
I am not sure what is your problem here. If it is that you are wondering how to map the Ace, Jack, Queen and King to points then I would suggest the following.
Map<Integer, String> cardToPoints = new HashMap<Integer, String>();
cardToPoints.add(1, "Ace");
cardToPoints.add(11, "Jack");
cardToPoints.add(12, "Queen");
cardToPoints.add(13, "King");
Then if you need to print the text just search for the number in the map and if there is entry print it otherwise print the number you have.
As variation to this you can create class Card containing points for the card and it string representation and fill the map with this cards.
For example:
cardPoints.add(1, new Card(1, "Ace of Spades");
....
cardPoints.add(14, new Card(1, "Ace of Hearts");
cardPoints.add(15, new Card(2, "2 of Hearts");
Then just get the card from the map get the points and sum + print the exact cards. Easy and clean( apart of the 52 entries for the map initilization );
Java's an object-oriented language. You're probably a beginner, but here's an example for you to think about.
package cards;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Exercise07_29
* #author Michael
* #link https://stackoverflow.com/questions/31639964/pick-four-cards-and-compute-their-sum-java
* #since 7/26/2015 1:42 PM
*/
public class Exercise07_29 {
public static final int NUM_CARDS = 4;
public static void main(String[] args) {
Deck deck = new Deck();
List<Card> hand = new ArrayList<>();
int score = 0;
for (int i = 0; i < NUM_CARDS; ++i) {
Card card = deck.deal();
hand.add(card);
score += card.getRank().getValue();
}
System.out.println(hand);
System.out.println(score);
}
}
enum SUIT {
CLUB, DIAMOND, HEART, SPADE;
}
enum RANK {
ACE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(11), QUEEN(12), KING(13);
private final int value;
RANK(int value) { this.value = value; }
public int getValue() {
return value;
}
}
class Card implements Comparable<Card> {
private final SUIT suit;
private final RANK rank;
public Card(SUIT suit, RANK rank) {
if (suit == null) throw new IllegalArgumentException("suit cannot be null");
if (rank == null) throw new IllegalArgumentException("rank cannot be null");
this.suit = suit;
this.rank = rank;
}
public SUIT getSuit() {
return suit;
}
public RANK getRank() {
return rank;
}
#Override
public int compareTo(Card other) {
if (this.getRank().equals(other.getRank())) {
return this.getSuit().compareTo(other.getSuit());
} else {
return this.getRank().getValue() - other.getRank().getValue();
}
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Card card = (Card) o;
return suit == card.suit && rank == card.rank;
}
#Override
public int hashCode() {
int result = suit.hashCode();
result = 31 * result + rank.hashCode();
return result;
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("Card{");
sb.append("suit=").append(suit);
sb.append(", rank=").append(rank);
sb.append('}');
return sb.toString();
}
}
class Deck {
private List<Card> deck;
private Random random;
public Deck() {
this.init();
this.random = new Random();
}
public Deck(long seed) {
this.init();
this.random = new Random(seed);
}
private void init() {
this.deck = new ArrayList<Card>();
for (SUIT suit: SUIT.values()) {
for (RANK rank: RANK.values()) {
this.deck.add(new Card(suit, rank));
}
}
}
public Card deal() { return this.deal(true); }
public Card deal(boolean removeCard) {
int value = this.random.nextInt(this.deck.size());
return removeCard ? this.deck.remove(value) : this.deck.get(value);
}
}
I'm trying to create a deck of cards that shuffles itself and then outputs the cards in random order. I am running into the error ArrayIndexOutOfBoundsException for the lines
return ranks[rank] + " of " + suits[suit];
and
System.out.println( C.toString() );
What am I doing wrong? It outputs the deck size, and then occasionally outputs a card or two before showing the error code. Thanks in advance.
import java.util.Random;
import java.util.ArrayList;
public class Deck
{
private ArrayList<Card> cards;
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 static void main(String[] args)
{
Deck deck = new Deck();
Card C;
System.out.println( deck.getTotalCards() );
while (deck.getTotalCards() != 0)
{
C = deck.drawFromDeck();
System.out.println( C.toString() );
}
}
public class Card
{
private int rank,
suit;
private String[] suits = {"Hearts", "Spades", "Diamonds", "Clubs"};
private String[] ranks = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
Card(int rank, int suit)
{
this.rank=rank;
this.suit=suit;
}
public #Override String toString()
{
return ranks[rank] + " of " + suits[suit];
}
public int getRank()
{
return rank;
}
public int getSuit()
{
return suit;
}
}
public Card drawFromDeck()
{
Random generator = new Random();
int index = generator.nextInt( cards.size() );
return cards.remove(index);
}
public int getTotalCards()
{
return cards.size();
}
}
Everything there is good but you initialize the cards backwards.
Your Card constructor is (rank, suit) and your Deck constructor is creating them (suit, rank).
Just flip the order of the args in your Deck constructor on line 15
cards.add( new Card(a, b) );
should be
cards.add( new Card(b, a) );
Since a ranges from 0 to 3, a is the suit, and should be the second argument in the constructor.
I am having trouble executing my code and unable to pinpoint exactly the source of the error or why and maybe someone might be able to take a look and provide me with some feedback if possible.
Error message:
51
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
3 of Clubs, Diamonds, Hearts, Spades
at javacards.Card.toString(Card.java:15)
at javacards.CardRun.main(CardRun.java:15)
CardRun Class:
public class CardRun {
public static void main(String[] args)
{
Deck deck = new Deck();
Card C;
System.out.println(deck.getTotalCards());
while(deck.getTotalCards() != 0)
{
C = deck.drawFromDeck();
System.out.println(C.toString());
}
}
Card Class
public class Card {
private int card, suit;
private static String[] suits = {"Clubs, Diamonds, Hearts, Spades"};
private static String[] cards = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
Card(int suit, int card)
{
this.card = card;
this.suit = suit;
}
public #Override String toString()
{
return cards[card] + " of " + suits[suit];
}
public int getCard()
{
return card;
}
public int getSuit()
{
return suit;
}
}
Deck Class
public class Deck {
private Card[]cards;
int i;
Deck()
{
i = 51;
cards = new Card[52];
int x = 0;
for(int a=0; a<=3; a++)
{
for(int b=0; b<=12; b++)
{
cards[x] = new Card(a,b);
x++;
}
}
}
public Card drawFromDeck()
{
Random generator = new Random();
int index = 0;
index = generator.nextInt(i);
Card temp = cards[index];
cards[index] = cards[i];
cards[i] = null;
i--;
return temp;
}
public int getTotalCards()
{
return i;
}
}
This array:
private static String[] suits = {"Clubs, Diamonds, Hearts, Spades"};
only contains one item - you probably meant:
private static String[] suits = {"Clubs", "Diamonds", "Hearts", "Spades"};