How do I add a card to my hand when it says "addCardToHand" I tried card++; and hand++; neither worked. Is there a problem with my code, or did I just left something out? I feel like I need to add something but, I don't know what.
private AbstractCard[] hand;
private int winCount;
public AbstractPlayer() {
hand = new AbstractCard[0];
}
public AbstractPlayer(int score) {
}
public void addCardToHand( AbstractCard card ) {
AbstractCard[] NewHand = new AbstractCard[hand.length+1];
for ( int i = 0; i < NewHand.length; i++) {
NewHand[i] = hand[i];
}
}
public void resetHand() {
hand = new AbstractCard[0];
}
I think it's probably because hand[] has nothing in it. It gets created as an array with size 0, (no elements), and then when you add a card, you pull from the hand[] at index 0, but since the hand[] has no elements, it's not pulling from anywhere.
Basically, nowhere in your code does hand[] ever get to be an array with any elements in it, so when you take from hand[0] there's nothing there, because in hand = new AbstractCard[0];, [0] is the size of the array.
EDIT:
You might want to look into using an ArrayList (Oracle documentation) (Stack Overflow post), because they don't have a pre-defined size. In your case, you're adding elements as you go, so an ArrayList be very helpful. With an ArrayList, you won't have to constantly create new arrays.
You probably want to keep track of the next insert position for cards with some state like private int insertCursor = 0;
Your addCardToHand(AbstractCard) method can then simply be
public void addCardToHand(AbstractCard card) {
hand[insertCursor++] = card;
}
Related
I am a beginner programmer and i've gotten stuck.
I've set up an array here which has worked how I want it to.
Although now I need a way to check the very last slot (data[5]) to see if any value has been placed within it since there is no guarantee in my code that each array slot will be assigned a value.
Below is my working array setup:
public final int[] data;
//Constructor
public MyArrayList() {
this.data = new int[6];
}
And here is what I've tried:
if(data[5] == null){
data[5] = value;
truth = true;
} else {
truth = false;
}
Note that this code is trying to detect if anything is in there, and place another value in if it can see there hasn't been any code written there.
Any help appreciated :)
int is a primitive type in Java, so it will never be null. If you want to keep track of how much of the array you've "used", you can add a second field to the class to keep up with it.
public class MyArrayList {
private final int[] data;
private int index;
public MyArrayList() {
data = new int[6];
index = 0;
}
...
}
Then whenever you "push" something new to the list, you put it at the index position and increment index. If index is ever equal to the length of the list, then you've exhausted the space you allocated.
Use the Integer class instead of the primitive type. It allows to assign a value or a null value. With this you can apply the logic that you described.
data = new Integer[6];
if (data[5] == null)
data[5] = value;
I know everyone gets skeptical whenever people put homework on here but I've run out of options and could really use some direction. I have a project where I have to create a deck of cards and allow the user to pick the size of the hand and then fill that hand with random cards and display that to the user. I've found plenty of answers using ArrayLists but mine requires an array and I've tried everything I know and my code is either completely wrong or throws a bunch of errors.
So here are the problems I have:
1) The addCard method in the Hand class can be used to add one Card object at a time to the hand array until it is full. It should increment the cardsInHand counter each time a Card object is added to the Hand as long as there is room for the Card to fit into the Hand.
Here is the code for the Hand class:
public class Hand
{
private int handSize; //Holds the size of the hand
private int cardsInHand; //Holds the number of cards allowed in the hand
private Card[] hand; //Array of card objects
public Hand()
{
this.handSize = 5;
this.cardsInHand = 0;
this.hand = new Card[52];
}//end Default Constructor
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
public void addCard(Card card)
{
hand[card]; //--> throws a type mismatch exception (change card param to an int)
}//end addCard()
public int getHandSize()
{
return handSize;
}
public void setHandSize(int handSize)
{
this.handSize = handSize;
}
public int getCardsInHand()
{
return cardsInHand;
}
public void setCardsInHand(int cardsInHand)
{
this.cardsInHand = cardsInHand;
}
public Card[] getHand()
{
return hand;
}
public void setHand(Card[] hand)
{
this.hand = hand;
}
public String toString()
{
String msg = "";
return msg;
}//end toString()
}//end class
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated!
My addCard method is just all janky and I could really use some help trying to fill it so my program works. Any help or even a pointing in the right direction would be appreciated
Sometimes the best thing to do is stop, turn the screen off, get a pen and piece of paper and just nut it out without any code. Try to understand the problem and get the logic straight in your head.
Basically, you have a series of buckets into which you can put a Card. Before you can put a Card in a bucket, you need to know if you have any free buckets available.
If there are, you need to add the Card to the next available bucket (which should be pointed to by cardsInHand) and increment cardsInHand
Your error is because you're trying reference a "bucket" using a Card, but you can only reference a "bucket" by an index (number) so...
hand[card];
should be more like...
hand[cardsInHand] = card;
but only after you've determined if there is a free "bucket" available, and you should increment cardsInHand AFTER this statement
I'd also be worried about your constructors
public Hand(int handSize)
{
this.handSize = handSize;
}//end Parameterized Constructor
isn't initialising hand, so that's going to be null. A better solution might be to use existing constructors where possible to build a common "initialisation" path
public Hand() {
this(5);
}//end Default Constructor
public Hand(int handSize) {
this.handSize = handSize;
this.cardsInHand = cardsInHand;
this.hand = new Card[handSize];
}//end Parameterized Constructor
Also
public Hand(Hand handIn)
{
this.handSize = handIn.handSize;
this.cardsInHand = handIn.cardsInHand;
this.hand = handIn.hand;
}//end Copy Constructor
is worrying, as it's possible for some external class to make a change to handIn's hand and that change will be reflected by this instance as well (as they are pointing to the same array).
A "copy" constructor should be making a "copy" of the data. Realistically, this should probably be a "deep" copy, so any changes to Card don't mess with the Hand as well, but I'll start with a simple "shallow" copy to get you started
public Hand(Hand handIn) {
this.handSize = handIn.handSize;
this.cardsInHand = 0;
this.hand = new Card[this.handSize];
// Yes, I know there is a better way to do this, but
// I want the OP to learn something
for (int index = 0; index < handIn.hand.length; index++) {
Card card = handIn.hand[index];
if (card != null) {
hand[cardsInHand] = card;
cardsInHand++;
}
}
}//end Copy Constructor
#MadProgrammer already give better answer, I only want to chime a little. Knowing the OP project assignment using Java I want to comment a little about the Hand class design.
The task clearly said that user can pick hand with custom size, then the user will add card into the hand until the hand is full. Thus, I would propose the Hand class design like below.
public class Hand {
private int size; // Hold the amount of card can be hold by hand.
private int counter; // Count how many card added.
private Card[] cards; // The card on hand.
public Hand(int size) {
this.counter = 0;
this.size = size;
this.cards = new Card[size];
}
public void addCard(Card card) {
if (this.counter > this.size) {
throw new IllegalStateArgument("The hand is full of card!");
}
this.cards[this.counter] = card;
this.counter++;
}
public String show() {
StringBuilder result = new StringBuilder("The card on hand is: \n");
for (int i=0; i<this.size; i++) {
result.append(this.cards[i].toString()).append("\n");
}
return result.toString();
}
}
In my opinion the Hand class more easy to understand and achieve the goals of the Hand purpose from the task. However, just use this as reference and write code that you understand well.
I have a repeating structure in my Java class and wanted to present the data as follows:
Peter Black
John Red
I do not know if the structure is right, because if I leave to show the color only, the data is overwritten
public class Test {
public static void main(String[] args) {
List<Person> persons = new ArrayList<>();
String[] names= {"Peter", "John"};
String[] colors= {"Black", "Red"};
for (String name: names) {
Person d = new Person();
d.setName(name);
for (String color: colors) {
d.setColor(color);
}
persons.add(d);
}
for (Person a : persons) {
System.out.println(a.getName() + "-" + a.getColor());
}
}
}
Console:
Peter-Red
John-Red
Instead of using a nested for loop, which is not what you are trying to accomplish, loop through both arrays at the same time.
if (names.length != colors.length) {
// error! not a 1:1 relationship
return;
}
for (int i = 0; i < names.length && i < colors.length; i++) {
String name = names[i], color = colors[i];
Person d = new Person();
d.setName(name);
d.setColor(color);
persons.add(d);
}
I could just do i < names.length, however that will break if both arrays are different sizes, so i < names.length && i < colors.length will make sure i never exceeds either of the two arrays' lengths.
Edit:
I think the real problem here is how you are storing your info. Why are you using two string arrays, instead of a collection containing Person objects?
Stop looping on colors array inside your names loop. A traditional index based loop should help you get the same name and color from each array:
public class Test {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
List<Person> persons = new ArrayList<>();
String[] names= {"Peter", "John"};
String[] colors= {"Black", "Red"};
for (int i=0; i<names.length; i++) {
Person d = new Person();
d.setName(names[i]);
d.setColor(colors[i]);
persons.add(d);
}
for (Person a : persons) {
System.out.println(a.getName() + "-" + a.getColor());
}
}
}
You can use the Enum like
enum Entity {
Peter("Black"),
John("Red");
private final String color;
Entity(String color) {
this.color = color;
}
Notice that your color loop is INSIDE your name loop. So for each name you are setting it's color to the first color then the second color and then you are moving on to the next name.
Your biggest problem is probably the use of the advanced for loop, it doesn't give you an index. If you start with:
for(int i=0;i<names.length;i++)
the solution will probably be obvious (and simplify your code)
(I'd give more but it looks like something you are trying to learn with so I'll try to avoid spoilers)
Re your comment--if you wish to simply create only completely filled out objects, use
for(int i=0;i<Math.min(names.length, colors.length);i++)
If you wish to create partial objects, use Math.max and handle the case inside where either array's length is less than i. It's all business logic code... define what you want to do and do it.
How to handle bad data (Not part of the original problem):
If you want to handle the cases where the arrays are unequal, if you use the "Math.max" solution above, then adding the inside of the loop could look like this:
if(names.length < i)
d.setName(names[i])
if(colors.length < i)
d.setColor(colors[i])
This way there is no exception and you are safely setting values.
But since that leaves your objects invalid, you might be better off not allowing a different number of colors and names from your user. If he enters 3 names, then throw away blank colors and keep re-prompting until you have 3 colors--then stop prompting. It's always safest to catch problems like this as soon as possible.
Another good solution, start with:
if(names.length != colors.length)
throw new IllegalArgumentException("createUsers method must have the same number of names as colors but was called with "+names.length+" names and "+colors.length+" colors")
Ensuring your parameters are correct and throwing an exception if they are not simplifies your code a LOT and is generally a very good practice.
So, adding stuff to my custom linked list is causing a NullPointerException, and I cannot, for the life of me, figure out why. The purpose of the program is to simulate a chest of drawers, with a list that has the drawers as nodes. The drawers each have a list that includes household objects as nodes.
Here's the relevant bits of code. The error happens when I create a: new ChestOfDrawers(3); in my UI class:
public class ChestOfDrawers{
private static OwnList chest;
private static int[] parametres;
public ChestOfDrawers (int drawers){
chest = new OwnList();
create();
}
public static void create(){
for (int i = 0; i < parametres.length; i++) {
Object drawer = new Drawer(i, parametres[i]);
chest.add(i, drawer); //This is causing the error
}
}
}
The Drawer class being referred to here is the class for the drawers. It requires int i as an ID and int parametres as drawer capacity. The parametres[] array gets filled before the additions to the list are made and it includes info for drawer capacity. The linked list in the question (OwnList) is functioning 100% correctly as it is part of a provided course material, it's near identical to Java's own. I tested the class in another test class and it worked fine, I've just made a mistake here somewhere. Please help!
The problem is that you are not initializing the parametres array. This field will be null by default. You need to either initialize it where it is declared, or in a static initializer block. Additionally, why are the two fields and the create method static? Those certainly seem like instance state...
Here's a better version:
public final class ChestOfDrawers{
private final OwnList chest = new OwnList();
private final int[] parametres;
public ChestOfDrawers (int drawers){
if (drawers < 0) throw new IllegalArgumentException("Drawers may not be negative");
chest = new OwnList();
parametres = new int[drawers]; // <-- I'm assuming that's the intended meaning
initialize();
}
private void initialize(){
for(int i = 0; i < parametres.length; i++){
Object drawer = new Drawer(i, parametres[i]); // <-- parametres[i] will always be 0
chest.add(i, drawer);
}
}
}
I'm not sure what you need the parametres array to actually contain (a new array of int will be filled with zero values) - but I'll leave that as an exercise to the reader :-)
Ok, here is the code and then the discussion follows:
public class FlatArrayList {
private static ArrayList<TestWrapperObject> probModel = new ArrayList<TestWrapperObject>();
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] currentRow = new int[10];
int counter = 0;
while (true) {
for (int i = 0; i < 10; i++) {
currentRow[i] = probModel.size();
}
TestWrapperObject currentWO = new TestWrapperObject(currentRow);
probModel.add(counter, currentWO);
TestWrapperObject testWO = probModel.get(counter);
// System.out.println(testWO);
counter++;
if (probModel.size() == 10) break;
}
// Output the whole ArrayList
for (TestWrapperObject wo:probModel) {
int [] currentTestRow = wo.getCurrentRow();
}
}
}
public class TestWrapperObject {
private int [] currentRow;
public void setCurrentRow(int [] currentRow) {
this.currentRow = currentRow;
}
public int [] getCurrentRow() {
return this.currentRow;
}
public TestWrapperObject(int [] currentRow) {
this.currentRow = currentRow;
}
}
What is the above code supposed to do? What I am trying to do is load an array as a member of some wrapper object (TestWrapperObject in our case). When I get out of the loop,
the probModel ArrayList has the number of elements it is supposed to have but all have the same value of the last element (an array of size 10 with each item equal to 9). This is not the case inside the loop. If you perform the same "experiment" with a primitive int value everything works fine. Am I missing something myself regarding arrays as object members? Or did I just encounter a Java bug? I am using Java 6.
You are only creating one instance of the currentRow array. Move that inside the row loop and it should behave more like you expect.
Specifically, the assignment in setCurrentRow does not create a copy of the object, but only assigns the reference. So each copy of your wrapper object will hold a reference to the same int[] array. Changing the values in that array will make the values appear to change for all other wrapper objects that hold a reference to the same instance of the array.
i don' t want to sound condescending, but always try to remember tip #26 from the excellent pragmatic programmer book
select isn't broken
it is very rare to find a java bug. keeping this in mind often helps me to look over my code again, turn it around, and shake out the loose bits until i finally discover where i was wrong. of course asking for help early enough is very encouraged, too :)