I have my primary class running, and I wanted to run a separate class to shuffle numbers, then return the shuffled numbers into my primary class. In my shuffle class I have the return statement... but now what do I do? How do I use the random order of my int array in my primary class?
Here is my shuffle class:
public class Shuffle {
public static int[] getShuffle() {
int[] cards = new int[52];
ArrayList<Integer> cards_objs = new ArrayList<Integer>();
for (int i = 0; i < cards.length; i++) {
cards_objs.add(i);
}
Collections.shuffle(cards_objs);
for (int i = 0; i < cards.length; i++) {
cards[i] = cards_objs.get(i);
}
return cards;
}
}
I am making a card game(if you cant tell);
I wanted to use this shuffle class so that the cards are shuffled... but no card appears more than once.
when I return cards, how do I use them in my game class?
for example if the first number in the array is 1, then the card is Ace of clubs,
if the number is 2, then the card is Ace of diamonds. and so on...
I apologize for not posting enough information... I am new to java (as you can tell)
all help will be greatly appreciated,
-Steve
EDIT:
I found out what my problem was, I don't think I made it clear enough what my question was. Nonetheless thank you all for your help, it gave me ideas on different ways to approach this project.
I think using enum you can implement Card Game in a better way.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
// This is just sample example and it is just to show an approach. I had not enough time to make code perfect but it works fine.
public enum Deck
{
DECK;
enum Rank
{
DEUCE(2), THREE(3), FOUR(4), FIVE(5), SIX(6),
SEVEN(7), EIGHT(8), NINE(9), TEN(10), JACK(10), QUEEN(10), KING(10), ACE(11);
Rank(int rank)
{
this.rank = rank;
}
private final int rank;
}
enum Type
{
SPADES,
HEARTS,
DIAMONDS,
CLUBS;
}
class Card
{
private final Rank rank;
private final Type type;
Card(Rank rank, Type type)
{
this.rank = rank;
this.type = type;
}
#Override
public String toString()
{
return type.name() + rank.name();
}
}
static List<Deck.Card> cards = new ArrayList<Deck.Card>();
static
{
for (Rank rank : Deck.Rank.values())
{
for (Type type : Deck.Type.values())
{
cards.add(DECK.new Card(rank, type));
}
}
}
List<Deck.Card> shuffle()
{
Collections.shuffle(cards);
System.out.println(cards);
System.out.println(cards.size());
return Collections.unmodifiableList(cards);
}
public static void main(String[] args)
{
DECK.shuffle();
}
}
No need to define seperate class i feel, Just create an arraylist of numbers, pass it to Colections class of java
public static void shuffle(List list)
Your list will be shuffled directly
Either you change the array order so you can iterate the normal order in the array in your main class or you return an array back from your shuffle methode which contains the order (index) desired then access these up to this order.
Option A is to change the roder of the elemtns of your main array and Option B is to read the array and decide determin the new order, and return the order as ana rray backt, then access the main array up tot he new order.
You can simply have a method in you main class where you can do the shuffling and return the new set of shuffled numbers as an array.
If you do want to use another class, then you can do that using the instance of the class, and then call that reShuffleNumbers(), whereas reShuffleNumbers() will return array of numbers as you've wanted.
Try this -
public static void shuffleArray(int[] a) {
int n = a.length;
Random random = new Random();
random.nextInt();
for (int i = 0; i < n; i++) {
int change = i + random.nextInt(n - i);
swap(a, i, change);
}
}
private static void swap(int[] a, int i, int change) {
int helper = a[i];
a[i] = a[change];
a[change] = helper;
}
Pass the array to method shuffleArray() and you will get your array elements modified by position.
I hope this is what you are looking for.
Related
I am trying to implement different sorting algorithms on a deck of cards. I've implemented a base card class using enums to build the suits and faces. My class is based on Dietel's & Dietel's Java Book. However, I am struggling in passing the deck of cards into the sorting algorithms I implemented as I am not able to pass in an array which I can sort. I don't know if my approach is correct, I've read many of the posts on stackexchange where some recommend using Comparable (Implementing a Deck of Cards in Java) which I can't see working with my sorting algorithms. See (How to Sort the Cards. (Is my code wrong?)) and (Implementing a Deck of Cards in Java) and (Java Sorting object in ArrayList). By having the DeckOfCards return a sequence of numbers e.g. 1.1, 1.2, 1.3, I think I have a sequence which can be sorted. I also read about ordinals but all the comments on those seemed to oppose the approach. Appreciate any help on this attempt. Kindly note, that I've implemented merge sort and selection sort in the same way and its the same problem - I am clearly missing something here!
Below is my code:
//Card class
class Card
{
//public static enum Face {Ace, Deuce, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King};
public static enum Face {Ace(1), King(2), Queen(3), Jack(4), Ten(5), Nine(6), Eight(7), Seven(8), Six(9), Five(10), Four(11), Three(12), Deuce(13);
int rank;
Face(int r){ rank = r;}
int getRank() {return rank;}
}
//public static enum Suit {Clubs, Diamonds, Hearts, Spades };
public static enum Suit {Spades(1), Hearts(2), Diamonds(3), Clubs(4);
int order;
Suit(int o){ order = o;}
int getOrder() {return order;}
}
private final Face face; // face of card
private final Suit suit; // suit of card
// two-argument constructor
public Card( Face cardFace, Suit cardSuit )
{
face = cardFace; // initialize face of card
suit = cardSuit; // initialize suit of card
}
// return face of the card
public Face getFace() { return face;}
// return suit of Card
public Suit getSuit() { return suit;}
// return String representation of Card
public String toString()
{
//return String.format( "%s.%s", suit.getOrder(), face.getRank() );
return String.format( "%s.%s", suit, face );
}
}
// class DeckOfCards declaration
public class DeckOfCards
{
private List< Card > list; // declare List that will store Cards
// set up deck of Cards and shuffle
public DeckOfCards()
{
Card[] deck = new Card[ 52 ];
int count = 0; // number of cards
// populate deck with Card objects
for ( Card.Suit suit : Card.Suit.values() )
{
for ( Card.Face face : Card.Face.values() )
{
deck[ count ] = new Card( face.getRank(), suit.getOrder() );
count++;
}
}
list = Arrays.asList( deck ); // get List
//Collections.shuffle( list ); // shuffle deck
}
// output deck
public void printCards()
{
// display 52 cards in two columns
for ( int i = 0; i < list.size(); i++ )
System.out.printf( "%-20s%s", list.get( i ),
( ( i + 1 ) % 2 == 0 ) ? "\n" : "" );
}
public static void main( String[] args )
{
DeckOfCards cards = new DeckOfCards();
cards.printCards();
//cards.InsertionSort();
}
}
//Insertion Sort
public static void insertionSort(DeckOfCards[] listToSort)
{
for (int i = 0; i < listToSort.length-1; i++)
{
for (int k = i+1; k>0; k--)
{
if(listToSort[k] < listToSort[k-1]) //Code breaks here
{
swap(listToSort, k, k-1);
}
else
{
break;
}
print(listToSort);
}
}
}
The issue is that listToSort[k] < listToSort[k-1] is attempting to compare two DeckOfCards objects using the < operator, which is not allowed in Java - See: Compare two objects with or operators in Java.
As that post points out, you should instead be using a Comparator for the Card objects.
public class CardComparator implements Comparator<Card> {
#Override
public int compare(Card o1, Card o2) {
// ...
// Use Card.getFace().getRank() and Card.getSuit().getOrder()
// ...
}
}
In your DeckOfCards class, I'd also recommend adding a method such as:
public List<Card> getCards() { ... }
which returns a List of the cards in the deck. Then, in your insertionSort method, instead of listToSort[k], you would have listToSort.getCards().get(k). Also, instead of using < you can use a new instance of your CardComparator to determine whether or not to swap the cards.
public static void insertionSort(DeckOfCards cardsToSort) {
final Comparator cardComparator = new CardComparator();
for (int i = 0; i < cardsToSort.size() - 1; i++) {
for (int k = i + 1; k > 0; k--) {
final Card card1 = cardsToSort.getCards().get(k);
final Card card2 = cardsToSort.getCards().get(k - 1);
if(cardComparator.compare(card1, card2) < 0) {
swap(cardsToSort, k, k-1);
} else {
break;
}
}
}
}
listToSort is an array of DeckOfCards. On the line indicated with //Code breaks here you're trying to compare two DeckOfCards objects, which you just can't do in java (Operator overloading in other languages would allow you do do this).
How about you write a method, such as .getSortValue() to give you a value to sort it by. Alternatively you could write something to compare the values within the card like:
if(listToSort[k].getSuit().getOrder()*13+listToSort[k].getFace().getOrder() < listToSort[k- 1].getSuit().getOrder()*13+listToSort[k-1].getFace().getOrder())
...which is a bit long, but I would assume does what you want.
Note the *13 means that each combination of suit and face is unique
TLDR:
If you want to sort it in any other order, you'll have to come up with a value from each card that you can compare properly
The proper approach would be to split the whole deck into suits and then sort each suite individually. Your version of insertion sort is not working because the sorting is done using the face values i.e aces, 2,3,4 ... And I wouldn't count this as sorting a deck .
private HashMap<Suite,ArrayList<Cards>> deck ;
//scan through the whole deck
for(int i = 0;i < 52; ++i) {
`switch(cards[i]) {`
`case Aces :`
deck.put(Suite.Aces,cards[i]) ;
break;
.....
}
}
//Now sort
sort(deck.get(Suite.Aces)) ;
sort(deck.get(Suite.Diamond)) ;
First i have a class called card with this code
public class Card
{
private int value;
private String suit;
// private int value;
//private String rank;
public Card (int v, String s)
{
value=v;
suit=s;
}
public int random()
{
int randomNum = ((int)(Math.random() * 100) % 13 +1);
return randomNum;
}
public void displayCard()
{
System.out.println(value + " of " + suit);
}
}
then i have a class called deck with this code
import java.util.*;
public class Deck
{
public ArrayList<Card> card;
private ArrayList<String> suits;
private ArrayList<Card> hand;
public Deck()// time to build a deck
{
card=new ArrayList<>();
suits=new ArrayList<>();
suits.add("Hearts");
suits.add("Spades");
suits.add("Clubs");
suits.add("Diamonds");
for (int y=2; y<15; y++)
{
card.add(new Card(y,suits.get(0)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(1)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(2)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(3)));
}
}//end of public deck
public ArrayList deal()// deal method
{
hand=new ArrayList<>();
for(int x = 0; x < 5; ++x)//build 5 card hand
{
hand.add(card.get(x));
System.out.println(card.get(x));
}
return hand;
}//end of public void deal
}// end of public class deck
then i have the main
import java.util.ArrayList;
import java.util.*;
public class gamePlay
{
private static gamePlay player1;
public Deck fullDeck;
private ArrayList<Card> yourHand;
public gamePlay()
{
fullDeck=new Deck();
System.out.println("Your poker hand is a");
yourHand = fullDeck.deal();
//System.out.println(yourHand);
}
public static void main(String[] args)
{
player1 = new gamePlay();
}
}
It is printing out some crazy stuff for the value and suit of the cards in the hand
i think they are either memory locations from the arraylist or hexidecimal values i am not sure need it to print suit and rank any help is appreciated
If your classes implement a proper toString method, it will show up perfectly.
You can easily change your existing method displayCard in the Card class to a toString method. This leads to more flexibility than to let the Card print out itself by calling System.out.println in the card's method.
#Override
public String toString() {
return value + " of " + suit;
}
If you want the card to print to System.out you just do System.out.println(card);
Normal arrays can also be converted to String, using Arrays.toString(array) (if you would have a Card[] variable for example). Most implementations of Lists already implement a proper toString method so it will show you a comma-separated list of the entries.
You have to provide a toString() method in your Card class.
For example:
#Override
public String toString() {
return String.format("Card [value=%s, suit=%s]", value, suit);
}
If you don't provide that method, the default depends on the JDK implementation. Usually, it is the name of the class followed by a # and the object hash code.
I suspect that you have to iterate through the array and print each item individually. One cannot print the entire content of an array by toString() the array itself.
I recently started working on a personal project to test my (lousy) skills in java. It is a basic Java Card game called "Go Fish!". I'm currently only using basic console input/output to make the game. But whenever I compile the class MainClass, the compiler gives me "Unchecked or Unsafe" operations warning. I've been all over the internet looking for solutions, and have tried many, but it keeps giving me that error.
Any ideas on how to get rid of this problem?
Code: Class MainClass
import java.util.*;
public class MainClass
{
//Playing states
public static final int PLAYING = 0;
public static final int OVER = 1;
//Chance states
public static final int PLAY = 0;
public static final int COMP = 1;
//Win conditions.
public static final int PLAY_WIN = 0;
public static final int COMP_WIN = 1;
//Values used in the game, VERY IMPORTANT
public static int currentState, currentPlayer;
public static int winner;
public static ArrayList<String> Player_Cards;
public static ArrayList<String> Comp_Cards;
public static ArrayList<String> Deck_Cards;
public MainClass() {
}
public static void main(String[] args) {
//Start Game. This action is carried out EVERYTIME the game is started.
initGame(); //Serves function for "Initializing" the game i.e. sorting cards, distributing, identifying.
}
public static void initGame() {
//Goto Shuffler, get a shuffled deck, return here.
Shuffler shuffle = new Shuffler();
Deck_Cards = new ArrayList<String>(shuffle.doShuffle()); //For safe usage.
Player_Cards = new ArrayList<String>();
Comp_Cards = new ArrayList<String>();
//Give player cards
for(int i = 0; i < 5; i++) {
int c = Deck_Cards.size() - 1 - i;
Player_Cards.add(Deck_Cards.get(c));
Deck_Cards.remove(c);
}
//Give computer cards
for(int i = 0; i < 5; i++) {
Comp_Cards.add(Deck_Cards.get(i));
Deck_Cards.remove(i);
}
System.out.println("Darp");
}
}
Code: Class Shuffler:
import java.util.*;
public class Shuffler
{
public enum Suits {HEARTS, DIAMONDS, CLUBS, SPADES};
public enum Ranks {ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING};
public Shuffler() {
}
public static ArrayList doShuffle() {
//Initialize cards
int count = 0;
ArrayList<String> deck = new ArrayList<String>();
for(int i = 0; i < 4; i++) {
for(int y = 0; y < 13; y++) {
deck.add("Card is " + Ranks.values()[y] + " of " + Suits.values()[i]);
count++;
}
}
Collections.shuffle(deck);
return deck;
}
}
Additional Information:
I'm using BlueJ for this project
You're using a raw type for the doShuffle method so the compiler complains about the lack of type safety. Replace
public static ArrayList doShuffle() {
with
public static List<String> doShuffle() {
This method is accessed using an instance of Shuffler so the static keyword can be omitted
It's because you're using a raw ArrayList for your doShuffle. The local variable is properly parameterized, so adding <String> to the return type should do the trick.
It is because the doShuffle method returns a generic ArrayList.
In the main you call that method putting the result in an ArrayList so the compiler is advising you that this conversion is unchecked.
You can modify the method making the return ArrayList or use a generic ArraList in the main too.
PS. first answer! xD
I was trying to create a card game golf for fun and to practice my java skills. I'm trying to use enums for my card values and suites. Those values are held in a constructor, named Card, in the Card Class.
The problem I'm running into to is printing my arraylist Deck that holds all my individual cards. This method can be found in the DeckOfCards Class . I want to see if my program is creating a full deck of cards. Thanks in advance for the help!
DeckOfCards Class
package finalProjectGolf;
// Deck class represent a deck of playing cards.
import java.util.ArrayList;
import java.util.Collections;
public class DeckOfCards {
ArrayList<Card> deck = new ArrayList<Card>(); //array of Card objects
private int currentCard; // index of next Card to be dealt (0-51)
private static int numDecks = 1;
public int getCurrentCard() {
return currentCard;
}
public void setCurrentCard(int currentCard) {
this.currentCard = currentCard;
}
private static final int NUMBER_OF_CARDS = 52 * numDecks; //constant # of Cards
//constructor fill deck of Cards
public DeckOfCards(){
currentCard = 0; //set currentCard so first Card dealt is deck[0]
//Card Index
int c = 0;
//for each deck
for (int d = 0; d < numDecks; d++){
//for each suit
for (int s = 0; s < 4; s++){
// for each number
for (int n = 1; n <= 13; n++){
//add a new card to the deck
deck.add(new Card(CardValue.values()[n],Suit.values()[s])); //when using Enums java makes arrays automatically and you can use them by .values()
c++;
}}}//end for loop
}//end DeckOfCards constructor
//shuffle deck of Cards with one-pass algorithm
public void shuffle() {
Collections.shuffle(deck);
}
public int points(){
int value = deck.get(currentCard).getCardValue().getCardValue();
return value;
}
//deal one Card
public Card dealCard(int currentCard) {
//determine whether Cards remain to be dealt
if( currentCard < deck.size() ){
return deck.get(currentCard); //return current Card in array
}
else
return null; // return null to indicate that all Cards were dealt
}//end method dealCard
public void printDeck(){
{
currentCard = 0; //set currentCard so first Card dealt is deck[0]
//Card Index
int c = 0;
//for each deck
for (int d = 0; d < numDecks; d++){
//for each suit
for (int s = 0; s < 4; s++){
// for each number
for (int n = 1; n <= 13; n++){
//add a new card to the deck
System.out.printf(""); //when using Enums java makes arrays automatically and you can use them by .values()
c++;
}}}//end for loop
}//end DeckOfCards constructor
}
}// end class DeckOfCards
Card Class
package finalProjectGolf;
public class Card
{
private Suit suit;
private CardValue cardValue;
public Card (CardValue cardValue, Suit suit) //constructor of Card, holds Card value and it's suit
{
this.cardValue = cardValue;
this.suit = suit;
}
public Suit getSuit()
{
return suit;
}
public void setSuit(Suit suit)
{
this.suit = suit;
}
public CardValue getCardValue()
{
return cardValue;
}
public void setCardValue(CardValue cardValue)
{
this.cardValue = cardValue;
}
public String toString(){
return cardValue + " of " + suit;
}// end method toString
}
CardValue Class
package finalProjectGolf;
public enum CardValue
{
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 int cardValue;
private CardValue (int value)
{
this.cardValue = value;
}
public int getCardValue() {
return cardValue;
}
}
Suit Class
package finalProjectGolf;
public enum Suit
{
HEARTS(1),
SPADES(2),
CLUBS(3),
DIAMONDS(4);
private int suit;
private Suit (int value)
{
this.suit = value;
}
public int getCardSuit() {
return suit;
}
}
To add to AaronB's answer, your printDeck method is in fact wrong, as you have posted it. Currently it prints the empty string 52 times. In addition, you don't need to triple for loop just to print all the items in your deck. A very simple implementation that prints each card on a new line for a single deck would be:
public void printDeck() {
for(Card card : deck) {
System.out.println( card.toString() );
}
}
You also need to override the toString method for your enum values so that they print the name you want. Have a look at https://stackoverflow.com/a/14413605/1425014 for how to do that.
Your main class is called DeckOfCards. That indicates to me that the class represents a single deck of cards. However, judging by for (int d = 0; d < numDecks; d++) and private static int numDecks = 1, it appears that you intend for DeckOfCards to represent one or more decks of cards. It may be clearer to simply uses a collection (such as ArrayList) if you need more than on DeckOfCards instead of complicating the DeckOfCards class.
Finally, you should try to make sure your comments make sense before you post your code here. The comments for your printDeck() function haven't been changed after you copy/pasted from the DeckOfCards constructor.
The problem isn't that your printDeck method doesn't work (I haven't tested it yet, but at first glance it looks reasonable), it's that you never call it. You could place it at the end of the DeckOfCards constructor, if the point is to check that it's all there correctly.
In addition, you really should refactor a bunch of your logic, most notably in the DeckOfCards class. You've got some big blocks of computation -- put that in a method. Also, instead of declaring variables in the class, you should declare them in the constructor. For example:
ArrayList<Card> deck; //array of Card objects
private int currentCard; // index of next Card to be dealt (0-51)
private static int numDecks;
//constructor fill deck of Cards
public DeckOfCards(int numDecks){
deck = new ArrayList<Card>();
currentCard = 0; //set currentCard so first Card dealt is deck[0]
this.numDecks = numDecks;
Correct me if I'm wrong though, you didn't really describe what the issue was...
First i have a class called card with this code
public class Card
{
private int value;
private String suit;
// private int value;
//private String rank;
public Card (int v, String s)
{
value=v;
suit=s;
}
public int random()
{
int randomNum = ((int)(Math.random() * 100) % 13 +1);
return randomNum;
}
public void displayCard()
{
System.out.println(value + " of " + suit);
}
}
then i have a class called deck with this code
import java.util.*;
public class Deck
{
public ArrayList<Card> card;
private ArrayList<String> suits;
private ArrayList<Card> hand;
public Deck()// time to build a deck
{
card=new ArrayList<>();
suits=new ArrayList<>();
suits.add("Hearts");
suits.add("Spades");
suits.add("Clubs");
suits.add("Diamonds");
for (int y=2; y<15; y++)
{
card.add(new Card(y,suits.get(0)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(1)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(2)));
}
for (int y=2; y<15; y++)
{
card.add(new Card((y),suits.get(3)));
}
}//end of public deck
public ArrayList deal()// deal method
{
hand=new ArrayList<>();
for(int x = 0; x < 5; ++x)//build 5 card hand
{
hand.add(card.get(x));
System.out.println(card.get(x));
}
return hand;
}//end of public void deal
}// end of public class deck
then i have the main
import java.util.ArrayList;
import java.util.*;
public class gamePlay
{
private static gamePlay player1;
public Deck fullDeck;
private ArrayList<Card> yourHand;
public gamePlay()
{
fullDeck=new Deck();
System.out.println("Your poker hand is a");
yourHand = fullDeck.deal();
//System.out.println(yourHand);
}
public static void main(String[] args)
{
player1 = new gamePlay();
}
}
It is printing out some crazy stuff for the value and suit of the cards in the hand
i think they are either memory locations from the arraylist or hexidecimal values i am not sure need it to print suit and rank any help is appreciated
If your classes implement a proper toString method, it will show up perfectly.
You can easily change your existing method displayCard in the Card class to a toString method. This leads to more flexibility than to let the Card print out itself by calling System.out.println in the card's method.
#Override
public String toString() {
return value + " of " + suit;
}
If you want the card to print to System.out you just do System.out.println(card);
Normal arrays can also be converted to String, using Arrays.toString(array) (if you would have a Card[] variable for example). Most implementations of Lists already implement a proper toString method so it will show you a comma-separated list of the entries.
You have to provide a toString() method in your Card class.
For example:
#Override
public String toString() {
return String.format("Card [value=%s, suit=%s]", value, suit);
}
If you don't provide that method, the default depends on the JDK implementation. Usually, it is the name of the class followed by a # and the object hash code.
I suspect that you have to iterate through the array and print each item individually. One cannot print the entire content of an array by toString() the array itself.