Iterating through an array and printing each object - java

My array is being loaded and is printing the cards out as planned (in the order they appear in the file). When I try to cycle back through the arraylist in a separate method to check whether or not the data is there, it only prints the last object rather than each of them. Can anybody tell me why?
The load method
public class
TestFrame {
//VARIABLES
private static Deck deck;
private static Card card;
private static Scanner scan;
private final static String fileName = "cards.txt";
static ArrayList<Card> cards = new ArrayList<>();
private static void Load(){
deck = new Deck();
card = new Card();
// Load in the card file so that we can work with the data from cards.txt internally rather than from the file constantly.
try(FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
Scanner infile = new Scanner(br)){
int numOfCards = infile.nextInt();
infile.nextLine(); // Do we need this? Yes we do. Illuminati confirmed.
for(int i=0; i < numOfCards; i++){
String value = infile.nextLine();
String suit = infile.nextLine();
Card newCard = new Card(value, suit);
card.addCard(newCard);
System.out.print(newCard.getValue());
System.out.print(newCard.getSuit());
System.out.println(" ");
//Print out the object before cycling through again so we can see if it's working
//We can use this to add then cards to the shuffle array at a later date
}
}
Which prints out this when ran:
ah
2h
3h
4h
5h
6h
7h
8h
etc etc. This is the order they're in the .txt file.
I then use these methods to display all of the cards to make sure I can manipulate the data elsewhere
private static void displayAllCards(){
Card[] cards = Card.getAll();
for(Card c : cards){
System.out.print(Card.getValue());
System.out.print(Card.getSuit());
System.out.println(" ");
}
}
and the getAll() method
public static Card[] getAll(){
Card[] brb = new Card[cards.size()];
int tempCount = -1;
for(Card c : cards){
tempCount++;
brb[tempCount] = c;
}
return brb;
}
When getAll() is ran, it only prints out "ks" (king of spades) which is the last card in the .txt file. Can anybody tell me why this is happening?
Thanks
EDIT: CARD CLASS
package uk.ac.aber.dcs.cs12320.cards;
import java.util.ArrayList;
public class Card {
protected static String value;
protected static String suit;
static ArrayList<Card> cardsList = new ArrayList<>();
public Card(String v, String s){
this.value = v;
this.suit = s;
}
public Card() {
}
public static Card[] getAll(){
Card[] brb = new Card[cardsList.size()];
int tempCount = -1;
for(Card c : cardsList){
tempCount++;
brb[tempCount] = c;
}
return brb;
}
public static void deleteAll(){
cardsList.clear();
}
public static String getValue() {
return value;
}
public void setValue(String value) {
Deck.value = value;
}
public static String getSuit() {
return suit;
}
public void setSuit(String suit) {
Deck.suit = suit;
}
public void addCard(Card card){
cardsList.add(card);
}
}

card.addCard(newCard);
I think this should be cards.addCard(newCard); instead

Your card class is not implemented well. The reason you are getting only the last value is because your getters and String variables are static. There is only one copy of static variable per class. You need to make those instance variables/methods and change your print loop to
for(Card c : cards){
System.out.print(c.getValue());
System.out.print(c.getSuit());
System.out.println(" ");
}
See this answer for an elaboration on static vs instance

In Card the variables suit and value are declared static. This means that there is only one variable, shared between all cards.
When you load, you create a card. You set suit and value So they get h and a respectively. And then you print them.
Then you load the next two lines. You create a new card. But the variables are static, not part of the state of the new object, but the same suit and value that contain h and a. The new value is 2. And it replaces the a. Then you print it. The old value is gone.
So your print in the load shows the momentary value of suit and value, but in truth, there is only one value - the last value you loaded from the file.
These variables should be part of the card's state, thus, not static!
Note: your IDE notices when you try to use an instance variable from a static context. For example, your getValue method is static. So it can't access instance variables. However, the correction is not to set the variable to static, but rather to change the method, which logically is supposed to be an instance method, to not static. It may complain again because you are calling the method from static context. Then you have to carefully look why: you are not supposed to use this method statically - you should create an instance of Card and call the method using the variable you created.
So, IDE suggestions to "make it static" are not the correct solution! You should make all instance-related variables and methods not static, and solve "static context" issues by checking why you didn't create an instance and decided to call an instance-related method statically instead.

card.addCard(newCard); looks like it could be cards.add(newCard); and also a tip, changing your indexing looks a bit nicer when you start at zero for the getAll function
public static Card[] getAll(){
Card[] brb = new Card[cards.size()];
int tempCount = -1;
for(Card c : cards){
tempCount++;
brb[tempCount] = c;
}
return brb;
}
change it to
public static Card[] getAll(){
Card[] brb = new Card[cards.size()];
int tempCount = 0;
for(Card c : cards){
brb[tempCount] = c;
tempCount++;
}
return brb;
}

You are calling getAll() on a specific card, however before when you had card.addCard, you would only be adding one card to the list since every Card has its own ArrayList. This is why it only would print ONE CARD. You need to use getAll() on the ArrayList you made in the file.
Make a getAll() method in the main file that uses static ArrayList<Card> cards = new ArrayList<>();
public static Card[] getAll(){
Card[] brb = new Card[cards.size()];
int tempCount = 0;
for(Card c : cards){
brb[tempCount] = c;
tempCount++;
}
return brb;
This will work.

Related

Java array of object error (cards)

Let's start, 3 classes (Card,Start,Deckofcards)
1º Card:
public class Card {
private String type;
private int value;
private String number;
public Card(String number,String type,int value) {
this.type=type;
this.value=value;
this.number=number;
}
public String gettype() {
return type;
}
public String getNumber() {
return number;
}
public int getValue() {
return value;
}
#Override
public String toString() {
return getNumber() + " de " + gettype() + " --> VALUE " + getValue() ;
}
}
2º Start
public class Start {
public static void main(String[] args) {
Deckofcards deckofcards = new Deckofcards();
Card c = deckofcards.newCard();
String s =c.toString();
System.out.println(s);
Card c2 = deckofcards.newCard();
String s2 =c2.toString();
System.out.println(s2);
}
}
Then, the problem is here
Deckofcards:
public class Deckofcards {
private Card CardsR[];
private final Card[] Cards = {
new Card("A","heart",1),
new Card("2","heart",2),
new Card("3","heart",3),
new Card("4","heart",4),
new Card("5","heart",5),
new Card("6","heart",6),
new Card("7","heart",7),
new Card("8","heart",8),
new Card("9","heart",9),
new Card("10","heart",10),
new Card("J","heart",10),
new Card("Q","heart",10),
new Card("K","heart",10),
new Card("As","Diamond",1),
new Card("2","Diamond",2),
new Card("3","Diamond",3),
new Card("4","Diamond",4),
new Card("5","Diamond",5),
new Card("6","Diamond",6),
new Card("7","Diamond",7),
new Card("8","Diamond",8),
new Card("9","Diamond",9),
new Card("10","Diamond",10),
new Card("J","Diamond",10),
new Card("Q","Diamond",10),
new Card("K","Diamond",10),
new Card("A","clover",1),
new Card("2","clover",2),
new Card("3","clover",3),
new Card("4","clover",4),
new Card("5","clover",5),
new Card("6","clover",6),
new Card("7","clover",7),
new Card("8","clover",8),
new Card("9","clover",9),
new Card("10","clover",10),
new Card("J","clover",10),
new Card("Q","clover",10),
new Card("K","clover",10),
new Card("A","Spades",1),
new Card("2","Spades",2),
new Card("3","Spades",3),
new Card("4","Spades",4),
new Card("5","Spades",5),
new Card("6","Spades",6),
new Card("7","Spades",7),
new Card("8","Spades",8),
new Card("9","Spades",9),
new Card("10","Spades",10),
new Card("J","Spades",10),
new Card("Q","Spades",10),
new Card("K","Spades",10),
};
//Sorry if the translation its not correct, this is only a little part of a
//big code.
public Deckofcards() {
Collections.shuffle(Arrays.asList(Cards)); //SHUFFLE
CardsR=Cards.clone(); //COPY
}
public Card newCard(){
boolean while1 = true;
Card take=null;
for(int i = 0; i < CardsR.length; i++){
while(while1){
if(CardsR[i]!=null){
take=Cards[i];
//CardsR[i]=null;
while1=false;
}
}
}
return take;
}
}
Let's explain.
I have an array of cards, that i mix.
OK. ALL CORRECT
Then i call to recive a card (Class: start).
OK. ALL CORRECT
--- THEN ---
when i call another time, the card returns the same value...
I tried to set a null... but then it starts a infinite loop by no reason?.
Any possible solution?
Thanks
when i call another time, the card returns the same value
Because
for(int i = 0; i < CardsR.length; i++){ // i = 0
while(while1){ // true
if(CardsR[i]!=null){ // true
take=Cards[i]; //
while1=false; // so no more while loop execution
// first card will always returned
I tried to set a null... but then it starts a infinite loop by no
reason?
during first call Card c = deckofcards.newCard(); the CardsR[0] was set to null so during second call Card c2 = deckofcards.newCard(); your if condition if(CardsR[i]!=null) will never be executed and now you are stuck in an infinite while loop
boolean while1 = true;
Card take=null;
for(int i = 0; i < CardsR.length; i++){
while(while1){
if(CardsR[i]!=null){
take=Cards[i];
//CardsR[i]=null;
while1=false;
}
}
}
Solution : simply you can use Random instance to pick and return random cards from array .
How to randomly pick an element from an array
You're not really doing anything with the shuffled list of cards; the instance is essentially transient and therefore garbage-collected. Note that shuffling the list you created out of the array, does not shuffle the array. Instead, you could do this:
List<Card> cardList = Arrays.asList(Cards);
Collections.shuffle(cardList);
CardsR = cardList.toArray(new Card[cardList.size()]);
Your newCard method doesn't need to be this complicated. I assume you just want to return a card from the shuffled array. One way to do this is to maintain an index of the last card taken; you can initialize it to -1 in your constructor. In newCard, you will increment this index and return the card at that index as long as you are not out of bounds. If you are, you might want to print a message saying there are no cards left (for example).
Some other pointers:
Make sure you follow Java naming-conventions; field and variable names should not be capitalized.
Consider using a List<Card> of cards instead of an array; that way you can simply shuffle instead of needlessly converting back and forth between an array and a list.
The value of take will always be the first card in the array.
The while loop never terminates when you set the value equal to null because while2 is only set to false when a non-null entry is found. Once a null is found, then nothing happens and the while loop runs forever because there is no way for while2 to be set to false.
A break statement should do the trick here
public Card newCard(){
Card take=null;
for(int i = 0; i < CardsR.length; i++){
if(CardsR[i]!=null){
take=Cards[i];
CardsR[i]=null;
break;
}
}
}
return take;
}
A break statement will exit whatever loop it is in.
Alternatively, you can use a List<Card> instead of an array, with which you can remove entries from your shuffled list and return them, removing the need to set and check for null.
private List<Card> cardList;
public Deckofcards() {
cardList = Collections.shuffle(Arrays.asList(Cards)); //SHUFFLE
}
public Card newCard(){
if(!cardList.isEmpty()){
return cardList.remove(0);
}
return null;
}

Java: Initializing a new LinkedList Collection

I am trying to build a simple card game as a personal exercise. I have a collection Cards that should contain my deck. To initialize it, I want to pass it a map of what the deck should look like - an integer array (1 to n, 1 to 2) with (n, 1) containing a card type which is resolved within the card class, and (n, 2) containing the number of cards that type I want in the deck. I'm having difficulties with a NullPointer exception, however. Here is my Cards class:
import java.util.LinkedList;
public class Cards{
private LinkedList<Card> CardDeck;
...
public boolean MakeDeck(int[][] DeckMap){
/*feed the function a 2D int array (0 to n, 0 to 1)
#Param - DeckMap[][] - [n][0] to contain card type
[n][1] to contain DupeCount*/
//search the array for duplicates
for (int i = 0; i < DeckMap.length; i++){
int hold = DeckMap[i][0];
DeckMap[i][0] = -10;
for (int j = 0; j< DeckMap.length; j++){
if (DeckMap[j][0] == hold){
DeckMap[i][0] = hold;
return false;
}
}
DeckMap[i][0] = hold;
}
//Add the cards
// tried variations on this: CardDeck = new LinkedList<Card>;
for (int i = 0; i< DeckMap.length; i++){
Card cC = new Card();
cC.initializeCard(DeckMap[i][0], DeckMap[i][1]);
CardDeck.addLast(cC);
}
return true;
}
}
The NullPointer error occurs at the cC.addLast line - since I have initialized the Card class, the Null Pointer should refer to the CardDeck LinkedList I want to add the Card to, I think. But I can't work out how to initialize the list. Or is the .initializeCard call the problem (code below)? Thanks in advance for your help and apologies if I've missed something obvious.
Error:
java.lang.NullPointerException
at towergame.Cards.MakeDeck(Cards.java:75)
public class Card {
private static String cName;
private static int cDuplicateCount;
public static cEffect myEffects;
public final void initializeCard(int inEffect, int DupeCount){
myEffects = new cEffect();
myEffects.setEffect(inEffect);
cName = myEffects.getCardType();
cDuplicateCount = DupeCount;
}
...
}
Instead of this private LinkedList<Card> CardDeck;
use this private LinkedList<Card> CardDeck = new LinkedList<Card>();
it is throwing NPE because cardDeckhas not been initialized.

Can't seem to print an arraylist full of objects/enums

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

Return array in Java

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.

How to access an array index of an Object instance

Good day!
I am wondering How can I access an array index of an Object instance.
My code is as follows:
public class PokerPlayer {
private String name = null;
private Card [] cardsOnHand = new Card[5];
//getter and setter
}
What i want is to access the cardsOnHandArray[index] so that i can call it on another class and set the values per index...
public class PokerGame {
public static void main (String [] Args){
PokerPlayer players []= new PokerPlayer[4];
for(PokerPlayer player : players){
for(int i =0; i<5; i++){
//ACCESS cardsOnHand index i and store something on it...
}
}
}
}
Any advice would be highly appreciated. How can i also improve my OO design? Thank you in advance
public class PokerPlayer {
...
public Card getCard(int index) {
return this.cardsOnHand[index];
}
public void setCard(int index, Card card) {
this.cardsOnHand[index] = card;
}
...
}
then use:
player.getCard(i);
player.setCard(i,new Card());
You almost have it. Just call this inside your inner loop:
cardsOnHand[i] = new Card();
Of course, change what is being assigned to the array according to your requirements.
you can do as:
for(PokerPlayer player : players){
for(int i =0; i<5; i++){
Card[] cards= player[i].getCardsOnHand();
cards[i] = new Card();
}
}
This should work:
public class PokerGame {
public static void main (String [] Args){
PokerPlayer players []= new PokerPlayer[4];
for(PokerPlayer player : players){
for(int i =0; i<5; i++){
Card card = player.cardsOnHand[i];
}
}
}
}
Since your cardsOnHand array is private, you have to use your (unprovided) setter function.
Which could be something like
public void setCard(int index, Card value){
cardsOnHand[index] = value;
}
And in used in your loop as
player.setCard(i, something)
Assuming that your PokerPlayer has a getter for the cardsOnHand array:
public class PokerGame {
public static void main (String [] Args){
PokerPlayer players []= new PokerPlayer[4];
for(PokerPlayer player : players){
for(int i =0; i<5; i++){
player.getCardsOnHand()[i] = new Card();
}
}
}
}
However, I think that a better solution is to add a method
public void setCard(Card card, int index) {
assert index < 5;
cardOnHands[index] = card
}
to your PokerPlayer.

Categories