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
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.
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 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 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.