I am creating a simplistic poker game in Java that will create a deck of cards, let you draw a hand and display what kind of suit you have. Here is what I have so far and have run into a problem.
I have 3 different Array Lists, one for the card values, one for the card suits, and one to hold the actual card objects once the card suit and value is applied. I created a loop that is supposed to add a suit to each value (13 values) and add them into the newCards ArrayList (it is of type CARD, a different class I have that allows the objects to have both an integer and a string). After I try to print out newCards to see if it works properly. I get quite a few exception errors.
I'm not sure how to efficiently create a loop like this so any help is appreciated.
import java.util.*;
public class pokerMain {
public static void main (String [] args){
ArrayList<String> suits = new ArrayList<String>();//array list for the card suits
ArrayList<Integer> val = new ArrayList<Integer>();//array list for card values
ArrayList<CARDS> newCards = new ArrayList<CARDS>();//array list for cards with assigned val/suits
suits.add("Clubs");//These are the suits, added to the suits ArrayList
suits.add("Hearts");
suits.add("Diamonds");
suits.add("Spades");
System.out.println("suits contains: " + suits );//Testing for suit
for(int i = 1; i <= 13; i ++){//loop that adds all 13 values to to the val ArrayList
val.add(i);
}
System.out.println("val contains " + val);//Testing for val
This is the loop
for(int i = 0; i <= val.size(); i ++){//This loop will be used to add a suit to every card value
newCards.add(new CARDS(suits.get(0), val.get(i)));//assigns hearts
newCards.add(new CARDS(suits.get(1), val.get(i)));//assigns hearts
newCards.add(new CARDS(suits.get(2), val.get(i)));//assigns diamonds
newCards.add(new CARDS(suits.get(3), val.get(i)));//assigns spades
}
-------------------------------------------------------------------------
System.out.println(newCards.toString());//prints newCards arrayList
//newCards.add(card);// puts card object into array list newCards
To prevent code duplication you could try two loops and use for each
for(String s : suits) {
for(Integer i : val) {
newCards.add(new CARDS(s, i));
}
}
Firstly, as John Mercier said, for:each is the way to go here.
Secondly, and this isn't causing your problem, but CARDS is not exactly a conventional class name. Something like Card or Cards (or wrap the Card in a Deck class...).
Thirdly, and most importantly, the main() doesn't seem to be your problem, as far as I can tell. Check your CARDS class.
Related
Ok so, I have a fillhand method that is supposed to get cards from a shuffled deck and add the cards one by one through the top method while also sorting them by suits. The top method saves the card at shuffledDeck at index 0 to a variable, removes the index at 0, and then returns the card. So i added the first card, then its suppose to check if the next card that top returns is of a different suit, if it is then add it to the array list, if it is of the same suit then add it to the arraylist but, in order of ranks within that suit. As of now, where it is supposed to check if the handArray contains the upcoming card's suit == false is not working.
public ArrayList fillHand(ArrayList Array, int handSize)
{
ArrayList<Card> shuffledDeck = Array;
handArray.add(deck.top(shuffledDeck));
for (int i = 0; i < handSize + 1; i++)
{
if (handArray.contains(shuffledDeck.get(i).getSuit()) == false)
{
handArray.add(deck.top(shuffledDeck));
}
}
return handArray;
}
Since you didn't post any code, I'll assume that Deck is a class with two attributes(rank and suit).
You'll want to create a method for this class that makes it print itself(i.e. "Ace of Spades" or "Jack of Hearts")
You'll also need a method that returns the suit.
From there you iterate over your arraylist and call that method on each node that satisfies the required suit
Edit, since code was posted:
The logic itself seems flawed, you're iterating over the handSize, checking if the suit number is in the handArray. This is a major issue, as handArray is an array of Card, not an array of int.
There are multiple ways to fix this, the simpler ones are:
Simplest: iterate over the handArray manually, checking if the suit matches with any of the card's
Faster: creating an array of size 4, with all values initialized as false, representing whether or not a suit is in the handArray.
Now that the if statement is dealt with, we must fix it's code. As of now, you're checking if the i suit is in the Array, and adding the top card to it.
The best course of action here would be ditching the for loop, replacing it with something like this:
while(ArrayList.size()){
/* code */
}
This will loop the array due to the way that top works, since it removes the top card
I have a lab for class (we are allowed to seek outside help) creating klondike solitaire. I am a total noob when it comes to programming (this is my first ever class in programming). We just learned about enums, and I have to build a deck using them (I've reviewed other questions about this, but I haven't found a solution that matches what I need yet). We have two enums (rank and suit):
public enum Rank {
ACE,
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN,
JACK,
QUEEN,
KING;}
and
public enum Suit {
CLUBS,
SPADES,
HEARTS,
DIAMONDS;}
Now, I need to combine them into an array called Deck, which stands as such:
public Deck() {
cards = new Card[52];
}
To put the cards into the deck, I've been trying to use the ".values" but I can't get it right. There is a testing code with this lab and it says I'm not getting any of the points for this. What am I doing wrong?
public void fill() {
for (int i = 0; i<52;i++){
for (Suit s : Suit.values()) {
for (Rank r : Rank.values()) {
cards[i]= new Card(r,s);
}
}
}
}
Any help is much appreciated. Thanks!
You state,
Now, I need to combine them into an array called Deck, which stands as such:
No, you need to create a class Card that has one field of each of the enums. Only after doing that can you create a Deck of your Cards. So do that -- create a Card class, give it at least two fields, one for each enum, plus an appropriate constructor, plus getters, plus a decent toString() and then you're set.
Also, this is wrong:
public void fill() {
for (int i = 0; i<52;i++){ // get rid of this loop
for (Suit s : Suit.values()) {
for (Rank r : Rank.values()) {
cards[i]= new Card(r,s);
}
The code above will try to stuff 52 cards into each index spot. For instance, it will try to stuff all 52 cards into the cards[0] spot, same for the cards[1] item, and only the last Card will be added. You'll have an array of 52 King of Diamonds -- not what you want.
Instead, get rid of the outer loop, and instead increment the i inside your loop:
public void fill() {
int i = 0;
for (Suit s : Suit.values()) {
for (Rank r : Rank.values()) {
cards[i]= new Card(r,s);
i++; // increment i here
}
}
}
I'm trying to deal a card (the object) from my deck (the arraylist) and I'm having trouble trying to get the first object in the arraylist.
I've used a shuffle method (which is working and prints out the total number of cards in the newly shuffled pack) but I have no idea how to get the first object from the array (ie dealing a card from the top).
Can anyone point me in the right direction please?
Thanks.
Take a look at the ArrayList.get(int index) method. It'll return the object at the given position (index).
In your case, it'd be the yourList.get(0).
List#remove() will help:
List<String> cards = new ArrayList<>();
for (char suit : "♥♦♠♣".toCharArray())
for (char rank : "23456789TJQKA".toCharArray())
cards.add(String.valueOf(rank) + String.valueOf(suit));
Collections.shuffle(cards);
System.out.println(cards.remove(0)); // Q♥ //
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Hey im trying to make a card of deck
the deck should contain 52 cards,
ofc with spade,diamonds,heart,clubs
with ranks ,
this is my code so far i havent gotten any longer
Thanks for help in advance.
get the deck to shuffle cards ,Create a class that represents a deck containing 52 cards, When a new object
of this class is created, the deck is initialized with the cards that it will contain.
public class Card {
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"};
Card() {
for (int i = 0; i < deck.length; i++) {
deck[i] = i;
}
}
}
A Card is a not a Deck of Cards. A Card has attributes (i.e. member variables) like suit and rank (although for comparing it is usually useful to use integers - or enums - for the rank and then change how they are displayed).
A Deck of Cards is many cards; usually with restrictions established when the deck is created. In this case the suits[] and ranks[] can be used to build the many Cards in the deck (giving each Card a particular suit and rank when it is created). The easiest way to do this in Java is to use nested loops - once for each dimension.
The "color" of each card is derived from the suit and does not need to be stored as it can be determined given a suit. If enums are used this can be merely assigned as an attribute.
Going by the above logic, here is a sample set of classes:
class Card {
final public String suit;
final public String rank;
public Card(String suit, String rank) {
// Assign suit/rank from arguments
}
String getColor() {
// Return the color based on suit (effectively "for free" if
// using an enumeration)
}
}
class DeckOfCards {
String[] suits = {..};
String[] ranks = {..};
// Arrays are icky to deal with; favor Lists/Collections.
List<Card> cards = new ArrayList<Card>();
public DeckOfCards () {
// For each suit/rank pair, create a Card and add it
// to the cards collection.
// You'll want nested loops, as shown by another answer.
}
public List<Card> getCards () {
// Return cards, perhaps
}
// Other methods relating to the Deck of Cards
public void shuffle () {
}
}
While I would recommend looking into enums, the above should indicate the difference between the two distinct "things" - Cards and a Deck (or Collection) of Cards. The other answer contains code showing how to generate cards from the cross product of the two input arrays.
First of all, make suits[] and ranks[] into int arrays. Make deck an array of cards, and make deck and the constructor you are using in a different calss (Called deck) The change the constructor to Card(int suit, int name)Just do this:
for(int i = 0; i < 4; i++) for(int j = 0; j < 13; j++){
Cards[13*i + j] = new Card(i, j);
}
Create a Card Object which has a suit and value property.
Create a method to create a List of all 52 Cards.
For your deck, I suggest using a Deque, Often pronounced "Deck" and has likeness to a deck of cards.
Then to create shuffled deck
//Create a List of cards
List<Card> deckList = ... //A method to create your 52 cards
Collections.shuffle(deckList);
Deque<Card> deck = new ArrayDeque<Card>(deckList);
I am a complete beginner with Java and am having trouble understanding how to pass objects around between classes and methods. I have made some progress, however my app now fails when I try to create playing cards inside a for loop. It works fine if I remove the loop. Here is the first part of the class that contains the error:
public class Testing
{
public static void main(String[] args)
{
int Deal = 1;
for(int Hand = 0; Hand < Deal; ++Hand)
{
//instantiate and derive values for Player
Card card1 = new Card();
card1.setSuit(); //assign card 1's suit
card1.setValue(); //asign card 1's value
//instantiate and derive values for Computer
Card card2 = new Card();
card2.setSuit(); //assign card 2's suit
card2.setValue(); //assign card 2's suit
//compare the two cards and make sure they are different
cardCompare(card1,card2);
}
//output the two cards to the screen
output(card1,card2);
}
This is the error I get:
Testing.java:26: error: cannot find symbol
output(card1,card2);
^
symbol: variable card1
location: class Testing
Testing.java:26: error: cannot find symbol
output(card1,card2);
^
symbol: variable card2
location: class Testing
2 errors
Since the code works if I remove the for loop, I'm assuming that somehow the names card1 and card2 are not visible outside the loop? If I wanted to create ten or twenty cards, I'd want to do that in a loop, so I must be missing something about instantiating new objects and using them elsewhere in the program.
Thanks for your help.
**Update: thanks for the initial feedback. I see now that if I move my instantiate statements outside the for loop, I could theoretically assign new values for those objects over and over again using a loop, which is all I need to complete this particular task.
I'm still curious though, is it not possible to instantiate new objects inside a loop, but still use them outside the loop? It seems like this must be possible somehow.
public class Testing
{
public static void main(String[] args)
{
int Deal = 1;
//instantiate and derive values for Player
Card card1 = new Card();
//instantiate and derive values for Computer
Card card2 = new Card();
for(int Hand = 0; Hand < Deal; ++Hand)
{
card1.setSuit(); //assign card 1's suit
card1.setValue(); //asign card 1's value
card2.setSuit(); //assign card 2's suit
card2.setValue(); //assign card 2's value
//compare the two cards and make sure they are different
cardCompare(card1,card2);
}
//output the two cards to the screen
output(card1,card2);
}
The card1 and card variables are declared inside the for loop and is thus only visible inside of the loop. To use it outside of the loop, you must declare it before the loop. Please read up on Java scoping rules.
Both card1 and card2 are in scope of the for loop, not the rest of main(). Move your initialization to before the for.
Well, as it stands, its going to keep trying to overwrite card1 and card2 since you'll both declare and initialize them "deal" times. Additionally, and more importantly, they'll be out of scope. Instead, declare it beforehand and only initialize them inside the loop.
What you probably want here is:
public class Testing
{
public static void main(String[] args)
{
int Deal = 1;
ArrayList<Card> playerCards = new ArrayList<Card>();
ArrayList<Card> computerCards = new ArrayList<Card>();
//instantiate and derive values for Player
Card card1;
//instantiate and derive values for Computer
Card card2;
for(int Hand = 0; Hand < Deal; ++Hand)
{
card1 = new Card();
card1.setSuit(); //assign card 1's suit
card1.setValue(); //asign card 1's value
card2 = new Card();
card2.setSuit(); //assign card 2's suit
card2.setValue(); //assign card 2's value
//compare the two cards and make sure they are different
cardCompare(card1,card2);
playerCards.Add(card1);
computerCards.Add(card2);
}
//output the two cards to the screen
output(card1,card2);
}
Haven't tested it, but it should work.
You also need to rethink your use of your Output method, too. Since you're going to have ~20 cards per person, when do you think you need to show them to the user? Currently, you have it outside of the for loop, so it's only going to display the LAST value assigned to each one. If you want to show them each card they're getting, put the output call inside the for loop, and maybe use Thread.Sleep() to pause the program for a half second or so so that they can see each card they get. That, or write an overload of output that accepts an ArrayList of cards, and prints all of them at the same time. Once again, if you need help with that, ask me.
By the way, im not sure what cardcompare() is really doing behind the scenes, but you probably want to make it return a bool representing whether or not they were different. something like:
bool areCardsDistinct = cardcompare(card1,card2);
That way, you can use the result to decide whether or not to get random new cards again