How to swap the position of two cards in the deck of ArrayList<Card>?
public class Deck
{
private ArrayList<Card> deck;
public Deck()
{
deck = new ArrayList<Card>();
}
public void addCard(Card cardToAdd)
{
deck.add(cardToAdd);
}
}
The supplied code is Java, so we'll go with Java.
Add a method, called swapCards like so:
public void swapCards (int indexA, int indexB)
{
Card temp = deck.get (indexA);
deck.set(indexA, deck.get (indexB));
deck.set(indexB, temp);
}
Now, some thing to think about:
What happens if indexA and indexB are beyond the size of the deck, how should the class behave?
Is there a better way to design the class? Are card indicies the best parameters to use here, could we do something else?
Related
I do not get how to put the Card class into the Deck. Would you please explain how I can fix this?
Here are the instructions:
You need to rewrite the constructor so that all 52 cards of a normal card deck are assigned to the cards array. Keep in mind that card information needs to be stored inside the Deck class and is not passed by parameter. Additionally, you need to re-define the toString method for the Deck class so that it can be used to display the attribute values in a convenient manner. Make sure to take advantage of the toString method that already exists in the Card class.
(You also need to add a shuffle method, which is called from the constructor. The shuffle method is a private helper method in the Deck class. For this version you need to shuffle the deck by swapping the cards. Generate two random numbers in the [0..51] number range that will represent the indexes of the cards array and swap the cards. Make 1000 swaps and then display the cards. Use Math.random to generate random numbers.) <-This is a part of the instructions, but I don't think it matters in this situation because I what I want to know is how to do put the Card class in to the Deck.(but i still put it in just in case)
public class Lab11bvst
{
public static void main(String[] args)
{
Deck deck = new Deck();
System.out.println(deck);
}
}
class Deck
{
private Card[] cards;
private int size;
private String[ ] suits = {"Clubs","Diamonds","Hearts","Spades"};
public Deck()
{
size = 52;
cards = new Card[size];
}
private shuffle(){
}
}
the Card class:
public class Card
{
private String suit;
private String rank;
private int value;
public Card(String s, String r, int v)
{
suit = s;
rank = r;
value = v;
}
public String getSuit() { return suit; }
public String getRank() { return rank; }
public int getValue() { return value; }
public void setSuit(String s) { suit = s; }
public void setRank(String r) { rank = r; }
public void setValue(int v) { value = v; }
public String toString()
{
return "[" + suit + ", " + rank + ", " + value + "]";
}
public boolean matches(Card otherCard)
{
return otherCard.getSuit().equals(this.suit)
&& otherCard.getRank().equals(this.rank)
&& otherCard.getValue() == this.value;
}
}
"rewrite the constructor so that all 52 cards of a normal card deck are assigned to the cards array"
Right now, the constructor is setting the size of the deck to 52 cards, and then it initializes an array to hold 52 elements. You'll need to populate the cards array by creating cards for all 52 cards normally found in a deck. The constructor of your Card class helps you do this.
For example, you could start by adding an Ace of Diamonds and adding it to the cards array:
Card aceD = new Card("Diamonds", "Ace", 1);
cards[0] = aceD;
and then add all 52 cards to your cards array.
package decks;
import java.util.ArrayList;
public class hand {
private ArrayList<card> hand;
private card test;
public hand(){
hand = null;
}
public void clear(){
for (int x = hand.size() - 1; x >= 0; x--)
hand.remove(x);
}
public void addCard(card c){
hand.add(c);
}
public void removeCard(card c){
if (hand.contains(c))
hand.remove(c);
}
public void removeCard(int pos){
hand.remove(pos);
}
public int getCardCount(){
return hand.size();
}
public String toString(){
String toReturn = "";
for (card n : hand)
toReturn += n + "\n";
return toReturn;
}
}
Alright so I have to make a card game for homework at my school, and so far we've made a card, deck, and hand class plus a runner. We built the decks and hands using Array Lists. I was trying to test it out by adding a card to the deck by using:
pOne.addCard(test);
The only thing in the addCard class is:
public void addCard(card c){
hand.add(c);
}
This however, only returns an error, it never actually adds a card to the ArrayList hand. Any ways to fix this? PLease help
You initialize the List to null in the constructor. Instantiate the List instead. Something like,
public hand(){
// hand = null;
hand = new ArrayList<>();
}
Also, by convention, Java class names start with a capital letter. So, I would prefer classes Hand and Card (instead of hand and card). Finally, for clear, you can call List.clear() instead of using a loop.
import java.util.*;
public class Deck {
public int deckSize = 52;
public ArrayList<Card> deck1 = new ArrayList<Card>(deckSize);
public Deck() {
for (CardEnum card : CardEnum.values()) {
for (SuitEnum suit: SuitEnum.values()) {
Card newCard = new Card(card, suit);
this.deck1.add(newCard);
}
}
}
int size() { return this.deck1.size(); }
String draw() {
Iterator<Card> itrCard = deck1.iterator();
if (!itrCard.hasNext()) {
throw new IndexOutOfBoundsException("Deck is empty!");
}
Card next = itrCard.next();
String name = next.getName();
this.deck1.remove(next);
return name;
}
void shuffle() {
Collections.shuffle(this.deck1);
}
public static void main(String[] args) {
Deck deck1 = new Deck();
deck1.shuffle();
System.out.println("The first five cards drawn are:");
for (int i = 0; i<5; i++) {
System.out.print(deck1.draw() + " ");
}
System.out.println("\n");
for (int i = 0; i<5; i++) {
System.out.print(deck1.draw() + " ");
}
System.out.println(deck1.get(1));
System.out.println("\nHow many cards do you want to replace? (Max of 4)");
Scanner in = new Scanner(System.in);
int v;
v = in.nextInt();
}
//System.out.println(deck2.get(4));
}
For this segment of code it says the method get is undefined for the type Deck? How can I make the get method work? Also I am trying to be able to create a function to replace up to 4 of the cards. I can deal out old cards, but how can I keep the old ones. I also need to be able to evaluate the hand and tell what it is (full house, pair, etc). I am finding this to be quite difficult, so even if you can only answer one of my questions, I would greatly appreciate it.
The Deck class itself has no get(int) method, however, you attempt to call this method on an Object of type Deck in your main() method. In order for this code to compile, you will need to write a method called get that takes an int as its argument.
Although the Deck class has an internal variable named deck1 that is an ArrayList, the scope of this method is limited to code within the Deck class. When you create a Deck named deck1 in main, this is a different object from the ArrayList named deck1 that is defined in the Deck class. Although they have the same name, these are two different objects, so this deck1 is not an ArrayList and cannot access the methods that ArrayList offers.
You just need to add a get method somewhere in your Deck class that forwards to the get method of your backing ArrayList. For example:
public class Deck {
public int deckSize = 52;
public ArrayList<Card> deck1 = new ArrayList<Card>(deckSize);
public Card get(int i) {
return deck1.get(i);
}
Alternatively, just use the public field:
System.out.println(deck1.deck1.get(1).getName());
^ ^
| └-- public field
└--local variable
It's a bit confusing because you've given your local Deck variable the same name as your ArrayList field in the Deck class.
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";
}
I'm trying to create a really simple game of war. User and computer draws 1 card per turn, they either win, tie, or lose. Game is over when cards are out. I have 4 classes. My war class I was mostly just testing out if things were working for the deck. What I need to do is split the deck in half so each player draws 1 card each turn (A total of 26 by the end of the game) and I don't know how to do that. I'm guessing I need a for loop, but other than that I don't know how I would give each player a card. Ignore the user input in Class War, like I said, I was just testing things out. I have 3 classes displayed here, my last one is a JApplet which isn't need here so I haven't included it.
EDIT: Thanks for the help guys. I have one last problem and then I should be good. I want to display Card.toString inside my JApplet class but when I call Card card = new Card(); it refuses to work. I'm guessing this is because of the constructor. How would I go about getting that toString to display, or bypass the constructor.
Edit: Figure everything out, Thanks for the help guys.
import java.util.ArrayList;
import java.util.Random;
public class Card {
private int suit, number;
String [] suits = {"Heart" , "Diamond" , "Spade" , "Club"}; //suits
String [] numbers = { "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" ,
"Jack" , "Queen" , "King" , "Ace" }; //card values
String card = "";
public Card(int suits, int numbers)
{
suit = suits;
number = numbers;
}
public String toString() //displays card suit/value
{
String finalCard = numbers[number] + " of " + suits[suit];
return finalCard;
}
}
import java.util.ArrayList;
import java.util.Random;
public class FullDeck {
private ArrayList<Card> cards = new ArrayList<Card>();//card array list
public FullDeck()
{
for(int a =0; a<=3; a++) //loops through suits
{
for(int b =0; b<=12;b++) //loops through values
{
cards.add(new Card(a,b)); //creates adds cards to list
}
}
}
public Card drawRandomCard()
{
Random generator = new Random(); //picks random card
int index = generator.nextInt(cards.size());
return cards.remove(index); //removes card from list
}
public String toString()
{
String result = "Cards remaining in deck: " + cards; //not currently used
return result;
}
}
import java.util.Scanner;
public class War {
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
Card C;
FullDeck hand1 = new FullDeck();
FullDeck hand2 = new FullDeck();
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 = hand1.drawRandomCard();
System.out.println(C.toString());
}
}
}
Create two ArrayList<Card>s, then make a for loop that goes through 52 times.
for(int i=0;i<52;i++){
Card tempCard = hand1.getCards().remove(hand1.getCards().indexOf(hand1.drawRandomCard()));
if(i%2 == 1){
firstPlayersCards.add(tempCard);
}else{
secondPlayersCards.add(tempCard);
}
}
Make sure to add a getCards() method in FullDeck which just returns cards.
And this way all of the cards are randomized in each player's hands, so you can just get them in order.
Edit: though, the simplest solution is what Daniel Gabriel said and to just call drawRandomCard() twice in a row.
It'd make sense to rename your FullDeck class to just Deck...
Then, include a constructor for Deck that takes an ArrayList as a parameter. Include a method for Deck that returns a Deck object and is called something like splitDeck.
Internally, the splitDeck takes half the cards in Deck, removes them from cards on that object, and adds them to a new, temporary ArrayList. Then, it creates and returns an a deck object built using this temporary ArrayList.
public Deck(ArrayList<Card> deck) {
cards = deck;
}
public Deck splitDeck() {
ArrayList<Card> temp = new ArrayList<>();
for(int i = cards.length() - 1; i >= cards.length()/2; --i) {
temp.add(cards.get(i));
cards.remove(i);
}
return new Deck(temp);
}
Now the Deck object on which you called the method contains half a deck, and the Deck object returned contains the other half.
Assuming you rename the class to Deck (just because it'd make more sense) and kept the same default constructor:
Deck playerOneDeck = new Deck();
// playerOne now has a full deck of cards
Deck playerTwoDeck = playerOneDeck.splitDeck();
// playerOne and playerTwo now each have half of playerOne's original full deck