I have to do my homework in Greenfoot.
This part means that I have to save the position of Chess and then click reset.
Then, I have to choose load to put back the pieces of chess in the position they had before reset.
Since I don't know the exact size of the array, I know I can use List but it isn't allowed in the homework.
Nothing showed up on the screen but there is no error message.
Assume I have a class called Chess.
static Actor[] allChess;
public void save() // this is the save
{
Actor[] allChess = GWorld.getAllObjects("Chess");
}
public void load() // this is the load
{
if (allChess != null)
{
for (int i=0; i < allChess.length; i++)
{
Chess ch = (Chess) allChess[i];
GWorld.addOneObject(new Chess(ch.color, ch.rank), ch.getX(), ch.getY());
}
}
}
Thanks a lot!
allChess is redeclared as a local variable in save(). Do like this :
public void save() // this is the save
{
allChess = GWorld.getAllObjects("Chess");
}
Related
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 problem with my integer arrays, for example one. I have class with objects, and i have different class, where these objects are incremented after button click, but I got "null" values and NullPointerExpection. I had this all working, when i hade just, for example "int Money;", but my codes was 12000 lines, and i tried to make it easier to read, etc. But now with array they don't work. I got working this thing with For Loops , but how I understand, i can't make it with loops, because i want to later load these values from savefile.
CarMainClass (This one doesn't work) :
package Clicker;
public class MainHolder {
public Integer main[] = new Integer[8];
public MainHolder(){
}
public void MainMaker(int k){
}
public void MakeMain(){
MainMaker(0); // Money
MainMaker(0); // Money Clicks
MainMaker(0); // Boxes
MainMaker(0); // Boxes Clicks
MainMaker(1); // Boxes Level
MainMaker(1); // Player Level
MainMaker(1); // Garage Level
MainMaker(0); // Garage Slots
}
}
CarMainClass (That works, with for loop) :
package Clicker;
public class MainHolder {
public Integer main[];
public MainHolder(){
main = new Integer[8];
for(int i=0; i <8;i ++){
if(i ==4 || i ==5 || i ==6){
MainMaker(1,i);
}else{
MainMaker(0,i);
}
}
}
public void MainMaker(int k,int p){
main[p] = k;
}
public void MakeMain(){
}
}
And button :
//Money Button Click
if(ae.getSource() == jbtnMoney) {
CarMain.main[0] += 1;
MoneyLabel.setText("Money: " + CarMain.main[0]);
CarMain.main[1] += 1;
MoneyClicksLabel.setText("Money Clicks: " + CarMain.main[1]);
}
Application GUI when working : WorkingImage
Application GUI when dosn't work + error : NoWorkingImage
Is it a full code of CarMainClass? It seems that the method MainMaker doesn't contain any executable code so it doesn't do anything when you call it. The button click is ok.
The initialised array is empty - contains only null values and that is why it returns null - when you reference the value on the GUI.
You need to change it to this (I assume that each number describes object):
package Clicker;
public class MainHolder {
public Integer main[] = new Integer[8];
public MainHolder(){
MakeMain();
}
public void MainMaker(int k,int p){
main[p] = k;
}
public void MakeMain(){
MainMaker(0,0); // Money
MainMaker(0,1); // Money Clicks
MainMaker(0,2); // Boxes
MainMaker(0,3); // Boxes Clicks
MainMaker(1,4); // Boxes Level
MainMaker(1,5); // Player Level
MainMaker(1,6); // Garage Level
MainMaker(0,7); // Garage Slots
}
}
But your solution to use loops make actually more sense. Why you can't store it into a file? You should define the the integers which you use to describe the application as constants - final Integer money = 0 and so on.
You can store the values into a file and use the index to map the values to the corresponding values. Or store it as map.
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;
}
this may seem daft i have a class called ship locations which i wish to store all my ships locations, ive extended it from my client class and simply called the set method as follows
sub.local being a multidimensional array from the ship class
sub.local = new int[2][2];
sub.local[0][0] =row;
sub.local[0][1]=col;
sub.local[1][0]=row;
sub.local[1][1] =col+1;
toServer.writeInt(row);
toServer.writeInt(col);
toServer.writeChar('s');
sub.placed=true;
setp1sub(sub.local);
When i print it back through another class it comes back with the location in the memory rather than the numbers i need. What is the reason for this
public class ShipLocations {
static int [][] p1sub;
public ShipLocations()
{
p1sub = new int[2][2];
}
public int[][] getp1sub()
{
return p1sub;
}
public void setp1sub(int[][] local) {
for (int i = 0;i <local.length;i++)
{
for(int j = 0;j<local.length;j++)
{
p1sub [i][j]= local[i][j];
}
}
}
}
would it be that im passing it as sub.local ?
output is [[I#a401c2
Instead of writing
System.out.println(yourArray);
use
// for multidemensional arrays:
System.out.println(Arrays.deepToString(yourArray));
// or for one dimemsional arrays:
System.out.println(Arrays.toString(yourArray));
Here is a link to the relevant JavaDoc.
For an explanation of your output, you can look at this answer.
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 :)