Java array of object error (cards) - java
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;
}
Related
How do you make an Arraylist of RandomNumber integers? java
So I am relatively new to the programming scene and I am confused as to why my code doesn't work. I am trying to make an arraylist of flowers and then use a random number generator to create a random number of certain flowers, and store them in the array. In my logic, I thought that I created a variable to store the numbers (ex randomRoses) and stored the number in the array so I could easily print out how many of each flower there is by just calling the arraylist and the position. (ex flowerArray[0] would print out 8 Roses) but sadly it does not. public class Flower { private int randomRoses; private int randomTulips; private int randomOrchids; public ArrayList <Integer> flowerArray; public Flower() { r = new Random(); t = new Random(); o = new Random(); int randomRoses = (r.nextInt(10) + 0); int randomTulips = (t.nextInt(10) + 0); int randomOrchids = (o.nextInt(10) + 0); flowerArray = new ArrayList<Integer> } public void add2Array () { flowerArray.add(randomRoses); //flowerArray[0] is the # of roses flowerArray.add(randomTulips); //flowerArray[1] is the # of tulips flowerArray.add(randomOrchids); //flowerArray[2] is the # of orchids } public void printArray() { System.out.println(flowerArray[0]); }
You can use the same random object, no need to create 3 instances of it for the random integer generation, Random r = new Random(); for (int i = 0; i < 3; i++) { flowerArray.add(r.nextInt(10)); } System.out.println(flowerArray); you can not do flowerArray[0] because you have an arrayList and not an array. you can instead do: flowerArray.get(0) for getting the integer at pos zero
Here your array list is associated with a class object. When you initialize your array list you need to add your entries to the array list in the constructor itself. So when you say object.printArray() its actually returning you the empty array list, that's why you are getting 0 every time. Try This. class Flower { private int randomRoses; private int randomTulips; private int randomOrchids; public ArrayList<Integer> flowerArray; public Flower() { Random r = new Random(); Random t = new Random(); Random o = new Random(); int randomRoses = (r.nextInt(10)); int randomTulips = (t.nextInt(10)); int randomOrchids = (o.nextInt(10)); System.out.println(randomRoses); System.out.println(randomTulips); System.out.println(randomOrchids); flowerArray = new ArrayList<Integer>(); flowerArray.add(randomRoses); //flowerArray[0] is the # of roses flowerArray.add(randomTulips); //flowerArray[1] is the # of tulips flowerArray.add(randomOrchids); //flowerArray[2] is the # of orchids } public void printArray() { System.out.println(flowerArray.get(0)); } } public class Test { public static void main(String[] args) { Flower f = new Flower(); f.printArray(); } } And in array list you can get elements by using get(index) method.
This will give the output you expect. public void printArray { System.out.println(flowerArray.get(0)+" Roses"); System.out.println(flowerArray.get(1)+" Tulips"); System.out.println(flowerArray.get(2)+" Orchids"); } Also you missed a semi-colon after the statement defining the arraylist. Make the correction: flowerArray=new ArrayList<Integer>; How did it compile without that semi-colon?
It is not working because your syntax for getting the ith flower is wrong. You're using a java.util.ArrayList so the correct way to get an object from that ArrayList is by calling the get() method. System.out.println(flowerArray.get(0)); Hope that helps.
Iterating through an array and printing each object
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.
Return ArrayList from ArrayList method type
I'm making a little card deck program that uses an ArrayList for the deck. One of the limitations set upon me is that the method in which I "deal" the cards must be an Arraylist type. The problem I'm running into is that I don't know how to return just a specific index value from the ArrayList. See below. public ArrayList deal(int n, boolean up){ Card card0 = new Card(); boolean cardFace = card0.state(up); return al.get(0); //<-- This doesn't work, Netbeans says that it is a string type //not an ArrayList type. The only thing it will actually //allow me to return is: return.al; // But this doesn't work, I don't need to return the whole list, // just the first element, but Netbeans calls that a String type, not // ArrayList So how can I return the first item of the List and still have it be the correct type? The rest of the code doesn't matter, just the Method type and return statement. EDIT: As requested package deckofcards; import java.util.ArrayList; import java.util.Collections; import java.util.Scanner; public class Deck{ ArrayList<String> al = new ArrayList<>(); public void shuffle(){ Collections.shuffle(al); } public String displayDeck(){ String returnDeck = ""; for(int i = 0; i < al.size(); i++){ String printDeck = al.get(i); returnDeck += printDeck; } return returnDeck; } public ArrayList deal(int n, boolean up){ Card card0 = new Card(); boolean cardFace = card0.state(up); return al.get(0); } public void populate(){ al.add(0, "Ace of Spades"); al.add(1, "Two of Spades"); al.add(2, "Three of Spades"); //yadaa yadaa
If you cannot change the signature and it is mandatory to return an arraylist, then you can create an arraylist with just one element and return it. Something like this: ArrayList returnList = new ArrayList(); returnList.add(al.get(0)); return returnList; Does not look great to me :-(
In your specific case, al is an ArrayList<String>. That means al.get(...) returns a String. However, your method is declared as returning an ArrayList, which is not a String. You will either need to change your method return type to String, or you will need to construct a new ArrayList and add your single string to it and return that. Your declared return type needs to match the object you are returning. So for example: ArrayList<String> al = ...; String getSingleItem (int index) { return al.get(index); } ArrayList<String> getSingleItemAsArrayList (int index) { ArrayList<String> single = new ArrayList<String>(); single.add(al.get(index)); return single; } ArrayList<String> getItems () { return al; } By the way, it's generally better to specify the type parameter to ArrayList, e.g. ArrayList<Whatever>, as this can save you a lot of casting things around / unchecked conversions and will give you compile-time checking of types.
Is there a reason that you have to return an ArrayList? Essentially, you are trying to create a method that takes a deck, picks a card, and then returns a deck. You could try and use the subList method someone mentioned above. You could create a new ArrayList containing only the card you want, but that's not very efficient. Or, if your goal is to actually return the whole deck, but with the correct card on top (aka in the first position of the ArrayList), there's lots of info about rearranging values in an ArrayList online. EDIT: Based on your full code, it looks like the goal is to flip the first card face up. You should do that (not gonna do your homework for you!) and then return the ArrayList that the method took in. IRL, imagine handing someone a deck, they flip the first card face up, then hand the deck back to you.
//ADDING AND deleting employees //Displaying employee list public class EployeeDB { static ArrayList e = new ArrayList<>(); public static boolean addEmployee(Employee e1) { e.add(e1); System.out.println("Employee added"); return true; } public static boolean deleteEmployee(int ecode) { int temp = 0; for (int i = 0; i < e.size(); i++) { if (e.get(i).getID() == ecode) { temp = temp + 1; e.remove(i); break; } } if (temp == 1) System.out.println("Emp deleted"); else System.out.println("Deletion unsuccessful, check ecode again"); return true; } public static String showPaySlip(int ecode) { double salary = 0; int temp = 0; for (int i = 0; i < e.size(); i++) { if (e.get(i).getID() == ecode) { temp = temp + 1; salary = e.get(i).getSalary(); break; } } if (temp == 1) return "Salary is" + salary; else return "No employye found with the specified ecode"; } public static ArrayList<Employee> listAll() { return e; } public static void main(String[] args) { Employee e1 = new Employee(); e1.setID(20); e1.setName("sai"); e1.setSalary(150.00); addEmployee(e1); Employee e2 = new Employee(); e2.setID(30); e2.setName("kumar"); e2.setSalary(1500.00); addEmployee(e2); deleteEmployee(30); System.out.println(showPaySlip(30)); for (int i = 0; i < e.size(); i++) System.out.println( listAll().get(i).getID() + " " + listAll().get(i).getName() + " " + listAll().get(i).getSalary()); } }
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.
Arrays, algorithms and elements
I am trying to make a poker game through java. The first thing I wanted to do is distribute 5 cards using arrays. I have done the distribution part, but how can I prevent the same cards being distributed twice. In other words, how can I check if an array already contains an element. I want it to be able to detect if the element already exists in an array, and if it does, I want to be able to change just that card that has been given out twice, help would be much appreciated. My codes down below, import java.util.Random; import java.util.Scanner; import java.util.Arrays; public class Poker { public final static String[] numbers = {"❤","♠","♦","♣"}; public final static String[] sign = {"1","2","3","4","5","6","7","8","10","J","Q","K","A"}; private String[] hand = {"","","","",""}; private boolean found; private Random random; public Poker() { found = false; String hand[] = {"","","","",""}; int tokens = 10; Scanner in = new Scanner(System.in); random = new Random(); } public void handOut() { for (int i = 0; i < 5; i++) { int numberRandom = random.nextInt(numbers.length); int signRandom = random.nextInt(sign.length); String pickedNumber = numbers[numberRandom]; String pickedSign = sign[signRandom]; String combinedSigns = pickedSign + pickedNumber; hand[i] = combinedSigns; System.out.print(hand[i] + " "); } System.out.println("\n"); } }
Your choice of terminology is ... err ... interesting :-) The card value is a "face value", not a sign. And whether it's hearts or diamonds or so on, that's its "suit" rather than its number. But, on to the question. I believe the best way to do this is to construct an entire 52-card deck out of your facevalue and suit arrays and then use a Fisher Yates shuffle to distribute cards. This is a nifty way to randomly choose elements from an array without duplicates. The beauty is that the items in the array don't actually need to be shuffled up front. Details on how it works can be found here.
If you can use the collections framework as opposed to an array, create a Stack and populate it with all the 52 cards. then call Collections.shuffle() on it. finally set hand[i]=(deck name).pop() Once a card is popped from the stack it will be removed from the deck so it can't be dealt again.
What you want to do is break your code into different methods. You should have a method for generating one card, a method for checking whether or not a card is in the hand, and a method to distribute cards to the hand. public String generateCard() { int numberRandom = random.nextInt(numbers.length); int signRandom = random.nextInt(sign.length); String pickedNumber = numbers[numberRandom]; String pickedSign = sign[signRandom]; return pickedSign + pickedNumber; } public static boolean cardIsInHand(String card) { for(int i = 0; i < 5; i++) { if(hand[i] != null && hand[i].contains(card)) { return true; } } return false; } public static void handout() { for (int i = 0; i < 5; i++) { String card = generateCard(); while(cardIsInHand(card)) { card = generateCard(); } hand[i] = card; } }