I'm having bad times with creating typical card/deck class in java. I've read some similar questions & answers but either they're not relatable/helpful or I can't simply comprehend it yet.
Here's the code
public class Cards {
boolean isAvailable;
int card_id;
static final int AC = 32;
public Cards [] deck = new Cards[AC];
public void set () {
int a = 0;
for (int i = 0; i < AC; i++) {
if(a == 4) a = 0;
deck[i].isAvailable = true; // <---------
deck[i].card_id = i + (a * 101); // <---------
a++;
}
}
public void read () {
for (int i = 0; i < AC; i++)
System.out.println(deck[i].isAvailable + " " + deck[i].card_id);
}
public static void main (String[] args) {
Cards c = new Cards();
c.set();
c.read();
}
}
Exception in thread "main" java.lang.NullPointerException
at Cards.set(Cards.java:13)
at Cards.main(Cards.java:24)
1.
I've read about similar issues and found that problem can be in initialization of an array and I've tried to do the same with my prog but it went bad anyway.
I marked 13th and 14th lines because they are being pointed (when i comment 13th line just for check, pointer sets to the next line).
2.
Next part of help I would like to get from you is:
Even though there is main (for training purposes), I see other class using this class (which just creates deck) so I guess I won't be needing main... Is everything well set besides probs in first point?
Very simple:
public Cards [] deck = new Cards[AC];
creates an empty array with AC number of slots for Cards objects.
Now you have to put a non-null Cards object into each slot!
But thing is: actually your abstraction is broken.
You wrote code that seems to take one card to be the same as a card set - by adding that array of Cards into your Cards class! And that makes it actually hard to fix your current code. As the "normal" way to fix this would be to add a constructor like
public Cards() {
deck = new Cards[AC];
for (int i=0; i<deck.length;i++) {
deck[i] = new Cards();
}
If you try that ... you immediately run into an endless recursion (creating one new Cards would result in creating AC new Cards (to fill the array); causing a stackoverflow very soon.
Thus the real answer goes somewhere along these lines:
public class Card {
... a class that represents a SINGLE card in your game
and then
public card GameOfCards {
... a class that (for example!) uses an array to hold n objects of class Card!
Finally, as Peter is indicating in his comment: you should learn to use debugging means to work on such problems yourself. One good way: before using any data structure, iterate it and print out its content. Or even better, learn how to use a debugger, and walk through your code step by step! As you should please understand: this is very basic stuff; that you normally should not bring forward here.
Related
Presume we have a class Student and a class Activity.
class Student {
private Activity[] myActivites;
public Activity[] getAct() {
return this.myActivites
}
}
class Activity {
private String name;
public String getName(){
return this.name;
}
private Student[] members;
}
the members array represents all the students that go to this particular activity, while the myActivites array in Student represents all the different activites the particular student is visiting.
How would I go about writing an INT method in the activity class that returns the number of differently named activites that all of the students in this particular activity are visiting (so, two different Activity objects can have the same name!)
EDIT:
Thanks for your concerns guys. It's actually not homework, I'm preparing for a test next week.
Hope you will forgive me for not translating the code into english, as it takes quite some time.
It's a part of a larger program I have to write. So far, I've done something like this:
public int steviloRazlicnihDejavnosti() {
int najboljPriden = this.clani[0].getSteviloKrozkov();
for (int i=1; i<this.clani.length; i++) {
int trenutnaPridnost = this.clani[i].getSteviloKrozkov();
if (trenutnaPridnost > najboljPriden) {
najboljPriden = trenutnaPridnost;
}
}
String[][] krozkiClanov = new String[this.clani.length][najboljPriden];
for (int i=0; i<this.clani.length; i++) {
Ucenec trenutni = this.clani[i];
Krozek[] krozkiTrenutnega = trenutni.getKrozki();
for (int j=0; j<krozkiTrenutnega.length; j++) {
krozkiClanov[i][j] = krozkiTrenutnega[j].getDejavnost();
}
}
int stevec = 0;
return;
"Krozek" is the class Activity.
"Ucenec" is the class Student.
at first, I figure out, which student has the most activites and then set a 2d string array of this length (and the length of all students), which I fill with the names of the activites. Then, I was thinking of checking the 2D array (haven't written that up yet), but believe that this will take too much time - I basically just prolonged the same problem I was facing before.
Hope this shows that I've actually put some work into this.
I've also tried solving it with adding an extra boolean attribute "HasBeenChecked", and would not count any object that "HasBeenChecked", but figured that this did not help with recodnising the duplicates of the names.
This is for homework, and I am becoming a little frustrated with how I can't figure out something so simple.
To simplify my code, I have 3 files right now: one class with an add() method I created among other things, one file that tests it (made by the prof), and one that creates the object (which I won't post, b/c its working). Here's the add() function.
EDIT 2: I'm going to add the method that prints the array, maybe that's the problem?
public class Population {
private Person[] pop = new Person[15];
private int numPop = 0;
public void add(Person c){ // this object is created in another class, it works fine
for(int i = 0; i < pop.length; i++){
if(pop[i] == null) {
pop[i] = c;
numPop++;
} else {}
}
public String listPeople(){
System.out.println("Population with "+numPeople+" people as follows:");
int i = 0;
while (i<numPeople){
System.out.println("A "+pop[i].getAge()+"year old person named "+pop[i].getName());
i++;
//FYI the get methods are working fine and are in another file.
}
return("");
}
Then, I run the program in a test file to ensure it works, which was provided to us. Here's the part that isn't working
public class PopTestProgram{ // FYI the prof created this, I can't change this
public static void main(String[] args){
Population pop = new Population(15);
pop.add(new Person(4, "Bob"));
pop.add(new Person(25, "Kim"));
// then adds 8 more people with different ages and names
// then prints the people
It compiles, but when I run it, it just puts 10 of the last person into the array, then crashes saying there is a problem with the "pop[i] = c;" line. I simply cannot figure out what I need to change here.
I haven't received an email from the prof directly, so I thought I'd ask here.
Edit: Here's what it shows after printing out the last person 10 times. It is showing problems with other methods that I haven't completed yet though...
java.lang.ArrayIndexOutOfBoundsException: -1
at Population.removePerson(Population.java:49)
at PopTestProgram.main(PopTestProgram.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
In add(Person), you are not stopping when you add an item, so the first item you added is put in all cells in the array, then the rest won't go in at all, since there are no more null cells in array. Break the loop when you find an empty location.
public void add(Person c) {
for(int i = 0; i < pop.length; i++){
if(pop[i] == null) {
pop[i] = c;
numPop++;
break;
}
else {
//.....
}
}
}
Could also just use numPop as the next location in the list, like:
public void add(Person c) {
if (numPop < pop.length) {
pop[numPop++] = c;
}
}
The exception is coming in at Population.removePerson(Population.java:49), which is not related to add method. So I assume removePerson is the method to print the person.
While removing you are calling one extra For loop, make sure your iteration is 10 times only.
The java.lang.ArrayIndexOutOfBoundsException: -1clearly tells the removePerson method is calling the index -1 also (which doesnt exist causing ArrayIndexOufofBoundsException). The removePerson method should start from index 9 to index 0 (or viceversa) [10 iteration in total] and then stop out.
Hope this helps
I'm building a Java based game in Swing, which is essentially a grid of Jbuttons
I have an Object called Cell, which is a custom JButton with additional parameters for storing objects. The game grid is represented by Cell[][]
I have an arraylist of type Cell[][] to allow me to store the state of the gamegrid after each move. If I want to undo the move, I need to copy the last element of the ArrayList to the game grid to allow it to be displayed on the UI.
My gamegrid is panelHolder and my arraylist is moveHolder.
So far I've tried Collections.copy(panelHolder, moveHolder.get(moveHolder.size())); which will not compile due to the "arguments not being applicable for the type Cell[][]"
I've also tried System.arraycopy(moveHolder.get(moveHolder.size()-1), 0, panelHolder, 0, panelHolder.length);, which throws and out of bounds exception. Initially I thought this was due to the moveHolder.size()-1, but even just as moveHolder.size() it has the same problem.
I've found numerous questions on StackOverflow and others that both show these two ways of doing it, but I can't seem to get it to work. Is there something more obvious I'm missing? Full class method below:
public class UndoClass implements MoveCommand{
public ArrayList<Cell[][]> moveHolder = new ArrayList<Cell[][]>();
public Cell[][] execute(Cell[][] panelHolder) {
if (moveHolder.size() > 0){
Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));
if (moveHolder.size() > 0){
moveHolder.remove(moveHolder.size());
}
}
System.out.println("Move Undone. Undos available:" + moveHolder.size());
return panelHolder;
}
public void addMove(Cell[][] panelHolder){
moveHolder.add(panelHolder);
}
public ArrayList<Cell[][]> getMoves(){
return moveHolder;
}
}
Cell Class
public class Cell extends JButton {
int co_x = 0;
int co_y = 0;
ArrayList<Players> current = new ArrayList <Players>();
}
Just wanted to point our your execute(...) method accepts the Cell[][] both as a parameter and the return argument. That approach is going to force all of your commands to keep copying your input param arrays to the return statement array. Notice if you don't need to keep the two in sync and you just use the return arg, you don't have to worry about copying at all:
Cell[][] lastState = moveHolder.get(moveHolder.size()-1);
moveHolder.remove(moveHolder.size()-1);
return lastState; // Not updating the panelHolder array, just returning
But of course now the input parm and return are out of sync. Instead you might want to encapsulate that state into a single object to make your life easier. Something like this (note that the execute now returns a void):
public ArrayList<GameState> previousStates = new ArrayList<GameState>();
public void execute(GameState currentState) {
if (previousStates .size() > 0) {
GameState lastState = previousStates.get(previousStates.size()-1);
currentState.restoreFrom(lastState);
previousStates .remove(moveHolder.size()-1);
}
}
Good luck on the game!
if (moveHolder.size() > 0) {
for (int i = 0; i < panelHolder.length; i++) {
panelHolder[i] = moveHolder.get(moveHolder.size()-1)[i].clone();
}
moveHolder.remove(moveHolder.size()-1);
}
Try this. You need to make copies of each internal array when copying 2D arrays.
Try a Linked List
LinkedList<Cell[][]> ll = new LinkedList();
ll.removeLast();
panelHolder = ll.clone();
Okay I have tried to write a simple Java code in BlueJ, that finds and prints the product of all the entries in data such as if data is {1,2,3,4} then the result will be 24.
And my code is below:
public class Product {
public static int[] product(int[] a) {
int [] s = new int[a.length];
for (int i =0; i< a.length; i++)
s[i] = a[i]*a[i];
return s; //the definition of your method...
}
public static void main(String[] args) {
//calling the method to seek if compiles
int[] results = Product.product(new int[] { 1,2,3,4 });
//printing the results
System.out.println(java.util.Arrays.toString(results));
}
}
The above code is giving me the square of each number, which is not what I want to have, somehow I have modify the code that the result will be 24 but I couldn't figure it out, anyone knows how to do it?
First of all, if you are first writing Java it is important to know that variable, function and class names are quite important. Please note that having Product.product() is not a good idea, since the function name is almost the same as the class name. Anyway, regarding your code. Your code is indeed returning the square of your input, what you would want is the following:
public class Product {
public static int getProduct(int[] input) {
int total = 1;
for (int v : input) {
total *= v;
}
return total;
}
}
This will return an integer value with the product of your input array. This also uses a for-each loop instead of a regular for-loop for readability. Also you don't need the index in this case. Good luck with it!
First, your product method needs to return an int rather than an int [].
You need to maintain the product as a variable. You can set it to 1 initially, and then multiply it by each element of the a array in turn; then you just return this value.
I am getting the following error:
Exception in thread "main" java.lang.NullPointerException
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
Line 19 contains:
dramaticGame1.ejectBall();
the Dramatic Game class contains the following:
public class DramaticMachine extends Machine
{
// Constructor is given the person's name.
public DramaticMachine(String name, int length)
{
super(name, length);
}
public Ball ejectBall()
{
if (getNoOfBalls() >= 0)
return null;
else
{
//Math.random() * getNoOfBalls yields a number
//which is >=0 and < number of balls.
int ejectedBallIndex = (int) (Math.random() * getNoOfBalls());
for (int selectedBallIndex = 0; selectedBallIndex < ejectedBallIndex; selectedBallIndex++)
{
Ball selectedBall = getBall(selectedBallIndex);
selectedBall.flash(4, 5);
}
Ball ejectedBall = getBall(ejectedBallIndex);
ejectedBall.flash(4, 5);
swapBalls(ejectedBallIndex, getNoOfBalls() -1);
removeBall();
return ejectedBall;
}//else
}//ejectBall
public String getType()
{
return "Dramatic Lottery Machine";
}//getType
}//dramaticMachine
How can i fix this?
This is the code for the DramaticGame class:
public class DramaticGame extends Game
{
// Constructor is given the person's name.
public DramaticGame(String machineName, int machineSize, String rackName, int
rackSize)
{
super(machineName,machineSize,rackName,rackSize);
}
public Machine makeMachine(String machineName, int machineSize)
{
return new DramaticMachine(machineName, machineSize);
}//makeMachine
}
This is the code for LotteryTestB:
public class LotteryTestB
{
public static void main (String args[])
{
SpeedController speedController
= new SpeedController(SpeedController.HALF_SPEED);
LotteryGUI gui = new LotteryGUI("TV Studio", speedController);
Worker worker = new TraineeWorker("Jim",0);
DramaticGame dramaticGame1 = new DramaticGame("Lott O'Luck Larry", 49,
"Slippery's Mile", 7);
gui.addGame(dramaticGame1);
worker.fillMachine(dramaticGame1);
for (int count = 1; count <=dramaticGame1.getRackSize(); count++)
{
dramaticGame1.ejectBall();
speedController.delay(40);
}//for
}//main
}//LotteryTestB
NullPointerException is one of the easier problems to chase down. It means that some reference wasn't initialized properly. It should be easy to figure out by stepping through your code with a debugger.
If you are incapable of using a debugger, the stack trace makes this easy for you. There are only four places to look, and it says exactly where they are.
at BallContainerImage.update(BallContainerImage.java:101)
at BallContainer.addBall(BallContainer.java:93)
at Game.ejectBall(Game.java:92)
at LotteryTestB.main(LotteryTestB.java:19)
It's not the bottom one. The reference to dramaticGame is the only one on that line, and you call new to initialize it. Go on to the next one. Add a log or print statement to prove where the null reference is, then go and initialize it properly.
I don't think your code is layered properly. You'll never get this working unless you can decompose the problem into smaller chunks, unit test them until they work, and then use that code to build up the complex solution.
Separate UI from the game itself. Get the game working, then worry about display issues.