This site requires JavaScript, please enable it in your browser!
Greenfoot back
ds06
ds06 wrote ...

2015/2/5

NullPointerException at 2DArray

ds06 ds06

2015/2/5

#
Hi, this is my code:
 public static final int ABSTAND=30;
    public static final int GROESSE=3; 
    public static final int HOEHE=GROESSE*2;
    public Settings sett = new Settings();
    int count =0;
    int einzeln=0;
    public Level1()
    {    
        super(320, 480, 1); 

        addObject(sett, 240,450);
        drawBoard();
        sett.setImage(new GreenfootImage("Score: 0",18,Color.BLACK, Color.WHITE));
    }

    public void drawBoard(){
        Random rand = new Random();
        Field[][] board = new Field[HOEHE][];
        for(int i =0; i<HOEHE;i++){
            board[i] = new Field[GROESSE];
            for(int k =0; k<GROESSE;k++){
                if(rand.nextInt(11)>=5){
                    board[i][k]= new Free();
                    addObject(board[i][k], k*ABSTAND+30, i*ABSTAND+30);
                    count++;

                }
                if(i>=1 && k>=1 && k<GROESSE-1 && i<HOEHE-1){
                    if(board[i][k-1]==null && board[i][k+1]==null && board[i+1][k]==null && board[i-1][k]==null){
                        System.out.println("test");
                    }
                }
            }
        }
it thows a NullPointerException for line 29 what im trying to do is to look if an object at is surrounded by other objects. if its not, print test. I cant figure out what is worng. thx ind advance
danpost danpost

2015/2/5

#
It looks okay to me. Please post the rest of the error message (copy/paste in entirety).
ds06 ds06

2015/2/5

#
This is the whole class:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.*;
import java.io.*;
import java.awt.*;
public class Level1 extends World
{
    public static final int ABSTAND=30;
    public static final int GROESSE=4; 
    public static final int HOEHE=GROESSE*2;
    public Settings sett = new Settings();
    int count =0;
    int einzeln=0;
    public Level1()
    {    
        super(320, 480, 1); 

        addObject(sett, 240,450);
        drawBoard();
        sett.setImage(new GreenfootImage("Score: 0",18,Color.BLACK, Color.WHITE));
    }

    public void drawBoard(){
        Random rand = new Random();
        Field[][] board = new Field[HOEHE][];
        for(int i =0; i<HOEHE;i++){
            board[i] = new Field[GROESSE];
            for(int k =0; k<GROESSE;k++){
                if(rand.nextInt(11)>=5){
                    board[i][k]= new Free();
                    addObject(board[i][k], k*ABSTAND+30, i*ABSTAND+30);
                    count++;

                }
                if(i>=1 && k>=1 && k<GROESSE-1 && i<HOEHE-1){
                    if(board[i][k-1]==null && board[i][k+1]==null && board[i+1][k]==null && board[i-1][k]==null){
                        System.out.println("test");
                    }
                }
            }
        }
        
        for(int i =0;i<count; i++){
            addObject(new Placeable(), 240,30);
       }

    }

}
and this are the error messages:
java.lang.NullPointerException at Level1.drawBoard(Level1.java:35) at Level1.<init>(Level1.java:18) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:408) at greenfoot.core.Simulation.newInstance(Simulation.java:596) at greenfoot.platforms.ide.WorldHandlerDelegateIDE$4.run(WorldHandlerDelegateIDE.java:437) at greenfoot.core.Simulation.runQueuedTasks(Simulation.java:483) at greenfoot.core.Simulation.maybePause(Simulation.java:296) at greenfoot.core.Simulation.runContent(Simulation.java:212) at greenfoot.core.Simulation.run(Simulation.java:205)
danpost danpost

2015/2/5

#
Okay -- I think I know what is going on. You are creating the array as you iterate through the outer loop. So, trying to access an element in the array that has not yet been created will fail. Remove line 26 and change line 24 to this:
Field[][] board = new Field[HOEHE][GROESSE];
ds06 ds06

2015/2/5

#
Great, now it compiles :) still it doesnt work exactly how i want it to work(e.g it prints you 3xtest but there arent 3 blocks that arent surrounded) While we are at it, is there a possibility to test if the object at is from a specific class? like:
if(board[i][k-1]=="Objetc of class Blocked.class"
thanks dan :)
danpost danpost

2015/2/5

#
ds06 wrote...
While we are at it, is there a possibility to test if the object at is from a specific class?
I think you want something like this:
if (board[i][k-1] != null && board[i][k-1] instanceof Blocked)
ds06 ds06

2015/2/5

#
Great, thats what i was looking for :) i changed the code a bit. so now in the first 2 forloops it creates the board with Free and Blocked objects, and after that another foorloop to look if its surrounded
public void drawBoard(){
        Random rand = new Random();
        Field[][] board = new Field[HOEHE][GROESSE];
        for(int i =0; i<HOEHE;i++){

            for(int k =0; k<GROESSE;k++){
                if(rand.nextInt(11)>=5){
                    board[i][k]= new Free();
                    addObject(board[i][k], k*ABSTAND+30, i*ABSTAND+30);
                    count++;

                }else{
                    board[i][k]= new Blocked();
                    addObject(board[i][k], k*ABSTAND+30, i*ABSTAND+30);
                }
            }
        }

        for(int i =0; i<HOEHE;i++){
            for(int k =0; k<GROESSE;k++){
                if(i>=1 && k>=1 && k<GROESSE-1 && i<HOEHE-1){
                    if(board[i][k] instanceof Free && board[i][k-1] instanceof Blocked  && board[i][k+1] instanceof Blocked && board[i+1][k]instanceof Blocked && board[i-1][k]instanceof Blocked){
                        System.out.println("test");
                    }
                }
            }
        }
        sett.getCount(count);
        for(int i =0;i<count; i++){
            addObject(new Placeable(), 240,30);
        }

    }
seems to work for every block "inside" do you have an idea how to easily do it for the blocks at the sides? Grey is a free block, black is blocked. the ones with a red line arent included in my code yet.
davmac davmac

2015/2/5

#
danpost wrote...
I think you want something like this:
if (board[i][k-1] != null && board[i][k-1] instanceof Blocked)
Handy hint: null always returns false in instanceof checks. So you can shorten the above to:
if (board[i][k-1] instanceof Blocked)
ds06 ds06

2015/2/5

#
Thanks davmac, i figured that :)
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.*;
import java.io.*;
import java.awt.*;
public class Level1 extends World
{
    public static final int ABSTAND=30;
    public static final int GROESSE=5; 
    public static final int HOEHE=GROESSE*2;
    public Settings sett = new Settings();
    int count =0;
    int einzeln=0;
    public Level1()
    {    
        super(320, 480, 1); 

        addObject(sett, 240,450);
        drawBoard();
        sett.setImage(new GreenfootImage("Score: 0",18,Color.BLACK, Color.WHITE));
    }

    public void drawBoard(){
        Random rand = new Random();
        Field[][] board = new Field[HOEHE][GROESSE];
        for(int i =0; i<HOEHE;i++){

            for(int k =0; k<GROESSE;k++){
                if(rand.nextInt(11)>=5){
                    board[i][k]= new Free();
                    addObject(board[i][k], k*ABSTAND+30, i*ABSTAND+30);
                    count++;

                }else{
                    board[i][k]= new Blocked();
                    addObject(board[i][k], k*ABSTAND+30, i*ABSTAND+30);
                }
            }
        }

        for(int i =0; i<HOEHE;i++){
            for(int k =0; k<GROESSE;k++){
                //middle
                if(i>=1 && k>=1 && k<GROESSE-1 && i<HOEHE-1){
                    if(board[i][k] instanceof Free && board[i][k-1] instanceof Blocked  && board[i][k+1] instanceof Blocked && board[i+1][k]instanceof Blocked && board[i-1][k]instanceof Blocked){
                        einzeln++;
                    }
                }
                //left top corner
                if(i==0 && k==0){
                    if(board[i][k] instanceof Free && board[i+1][k] instanceof Blocked && board[i][k+1] instanceof Blocked){
                         einzeln++;
                    }
                }
                
                //right top corner
                if(i==0 && k==GROESSE-1){
                    if(board[i][k] instanceof Free && board[i+1][k] instanceof Blocked && board[i][k-1] instanceof Blocked){
                         einzeln++;
                    }
                }
                
                //left bottom corner
                if(i==HOEHE-1 && k==0){
                    if(board[i][k] instanceof Free && board[i-1][k] instanceof Blocked && board[i][k+1] instanceof Blocked){
                         einzeln++;
                    }
                }
                //right bottom corner
                if(i==HOEHE-1 && k==GROESSE-1){
                    if(board[i][k] instanceof Free && board[i-1][k] instanceof Blocked && board[i][k-1] instanceof Blocked){
                         einzeln++;
                    }
                }
                
                //top row(-corner)
                if(i==0 && k<GROESSE-1 && k>=1){
                    if(board[i][k] instanceof Free && board[i+1][k] instanceof Blocked && board[i][k+1] instanceof Blocked && board[i][k-1] instanceof Blocked){
                         einzeln++;
                    }
                }
                //bottom row(-corner)
                if(i==HOEHE-1 && k<GROESSE-1 && k>=1){
                    if(board[i][k] instanceof Free && board[i-1][k] instanceof Blocked && board[i][k+1] instanceof Blocked && board[i][k-1] instanceof Blocked){
                         einzeln++;
                    }
                }
                
                //left side(-corner)
                if(i>=1 && i<HOEHE-2 && k==0){
                    if(board[i][k] instanceof Free && board[i-1][k] instanceof Blocked && board[i][k+1] instanceof Blocked && board[i+1][k] instanceof Blocked){
                         einzeln++;
                    }
                }
                //rigth side(-corner)
                if(i>=1 && i<HOEHE-2 && k==GROESSE-1){
                    if(board[i][k] instanceof Free && board[i-1][k] instanceof Blocked && board[i][k-1] instanceof Blocked && board[i+1][k] instanceof Blocked){
                         einzeln++;
                    }
                }
                
            }
        }
        
        System.out.println(einzeln);
        
        sett.getCount(count, einzeln);
        for(int i =0;i<einzeln; i++){
            addObject(new EinzelBlock(), 240,30);
        }

    }

}
seems to work. But thats so much code, i wonder if its possible to do with fewer EDIT: Doesnt work 100% but most of the time :D EDIT2: Ok it works evertime now :D had to change i<HOEHE-2 to i<=HOEHE-2
danpost danpost

2015/2/6

#
I have come up with this (using only Free objects -- no Blocked objects):
// the for loop
for (int y=0; y<HOEHE; y++) for (int x=0; x<GROESSE; x++)
    if (board[y][x] != null && isSurrounded(x, y))
         einzeln++;
// with this method
private boolean isSurrounded(int x, int y)
{
    for (int dy=-1; dy<2; dy++) for (int dx=-1; dx<2; dx++)
        if ((dx != 0 || dy != 0) && x+dx>=0 && x+dx<GROESSE && y+dy>=0 && y+dy<HOEHE && board[y+dy][x+dx] != null)
            return false;
    return true;
}
I believe you can change both occurrences of '!= null' (lines 3 and 9) to 'instanceof Free' without changing anything (while keeping your Blocked objects on the board).
ds06 ds06

2015/2/6

#
Thanks danpost, worked well :) I tried some differrent stuff and changed the way the Board is drawed entirely :D First it will create objects of Free for the blocks i want to be able to place. (line 27-85)
  • Dreieck
  • Viereck
  • Doppel
  • EinzelBlock
After that, the other fields of the board will be filled with blocked blocks.(line 87-95) At the end it would add the rigth amount of my placeable blocks to the field.(line 99-122)
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.*;
import java.io.*;
import java.awt.*;
public class Level extends World
{
    public static final int ABSTAND=30;
    public static final int GROESSE=9; 
    public static final int HOEHE=GROESSE+2;
    public Settings sett = new Settings();
    public Timer time = new Timer();
    int einzeln=0;
    int dreieck=0;
    int viereck=0;
    int c =10;
    int doppel=0;
    public Level()
    {    
        super(320, 480, 1);
        drawBoard();
    }

    public void drawBoard(){
        Random rand = new Random();
        Field[][] board = new Field[HOEHE][GROESSE];

        //Dreiecke
        for(int i=0; i<4;i++){
            int a=rand.nextInt(HOEHE-1);
            int b=rand.nextInt(GROESSE-1);
            if(!(board[a][b] instanceof Free)&&!(board[a][b+1] instanceof Free) &&!(board[a+1][b+1] instanceof Free)){
                dreieck++;
                board[a][b]= new Free();
                board[a][b+1]= new Free();
                board[a+1][b+1]= new Free();
                addObject(board[a][b], b*ABSTAND+40, a*ABSTAND+40+c);
                addObject(board[a][b+1], b*ABSTAND+70, a*ABSTAND+40+c);
                addObject(board[a+1][b+1], b*ABSTAND+70, a*ABSTAND+70+c);
            }
        }
        System.out.println("Dreiecke: "+dreieck);

        //Viereck
        for(int i=0; i<4;i++){
            int a=rand.nextInt(HOEHE-1);
            int b=rand.nextInt(GROESSE-1);
            if(!(board[a][b] instanceof Free)&&!(board[a][b+1] instanceof Free) &&!(board[a+1][b+1] instanceof Free)&&!(board[a+1][b] instanceof Free)){
                viereck++;
                board[a][b]= new Free();
                board[a][b+1]= new Free();
                board[a+1][b+1]= new Free();
                board[a+1][b]= new Free();
                addObject(board[a][b], b*ABSTAND+40, a*ABSTAND+40+c);
                addObject(board[a][b+1], b*ABSTAND+70, a*ABSTAND+40+c);
                addObject(board[a+1][b+1], b*ABSTAND+70, a*ABSTAND+70+c);
                addObject(board[a+1][b], b*ABSTAND+40, a*ABSTAND+70+c);
            }
        }
        System.out.println("Vierecke: "+viereck);

        //Doppel
        for(int i=0; i<4;i++){
            int a=rand.nextInt(HOEHE-1);
            int b=rand.nextInt(GROESSE-1);
            if(!(board[a][b] instanceof Free)&&!(board[a+1][b] instanceof Free)){
                doppel++;
                board[a][b]= new Free();
                board[a+1][b]= new Free();
                addObject(board[a][b], b*ABSTAND+40, a*ABSTAND+40+c);
                addObject(board[a+1][b], b*ABSTAND+40, a*ABSTAND+70+c);
            }
        }
        System.out.println("Doppel: "+doppel);
        //EinzelBlock
        for(int i=0; i<2;i++){
            int a=rand.nextInt(HOEHE);
            int b=rand.nextInt(GROESSE);
            if(!(board[a][b] instanceof Free)){
                einzeln++;
                board[a][b]= new Free();
                addObject(board[a][b], b*ABSTAND+40, a*ABSTAND+40+c);
            }
        }
        System.out.println("Einzelblöcke: "+einzeln);
        System.out.println("");

        //fill Field with Blocked Blocks
        for(int i =0; i<HOEHE;i++){
            for(int k =0; k<GROESSE;k++){
                if(!(board[i][k] instanceof Free)){
                    board[i][k]= new Blocked();
                    addObject(board[i][k], k*ABSTAND+40, i*ABSTAND+40+c);
                }
            }
        }

        
        //add placeable Blocks
        //viereck
        for(int i=0; i<viereck;i++){
            addObject(new Viereck(), board[HOEHE-1][0].getX()+15 , board[HOEHE-1][0].getY()+69);
            //             addObject(new Viereck(), board[HOEHE-1][0].getX() , board[HOEHE-1][0].getY()+54);
            //             addObject(new Viereck(), board[HOEHE-1][0].getX() , board[HOEHE-1][0].getY()+84);
            //             addObject(new Viereck(), board[HOEHE-1][0].getX()+30 , board[HOEHE-1][0].getY()+84);
            //             addObject(new Viereck(), board[HOEHE-1][0].getX()+30 , board[HOEHE-1][0].getY()+54);
        }

        //Dreieck
        for(int i=0; i<dreieck;i++){
            addObject(new Dreieck(), board[HOEHE-1][3].getX()+15 , board[HOEHE-1][0].getY()+69);
        }

        //Einzelne
        for(int i=0; i<einzeln;i++){
            addObject(new EinzelBlock(), board[HOEHE-1][6].getX() , board[HOEHE-1][0].getY()+54);
        }

        //Doppel
        for(int i=0; i<doppel;i++){
            addObject(new Doppel(), board[HOEHE-1][GROESSE-1].getX() , board[HOEHE-1][0].getY()+69);
        }

        
        //Score
        sett.setImage(new GreenfootImage("Score: 0",18,Color.BLACK, Color.WHITE));
        addObject(sett, board[0][0].getX()+sett.getImage().getWidth()/4,sett.getImage().getHeight());
        //timer
        time.setImage(new GreenfootImage("Time: 0",18,Color.BLACK, Color.WHITE));
        addObject(time, board[0][GROESSE-1].getX()-time.getImage().getWidth()/4, time.getImage().getHeight());

        sett.getInfos(einzeln,dreieck,viereck,doppel);

    }
}
Now the problem I have is to write code to check ob the blocks are allowed to place. For the EinzelBlock its kinda easy:
public class EinzelBlock extends Blocks
{
    boolean drag = false; 
    boolean placed = false;
    boolean pointAdded=false;

    public void act() 
    {
        if(!drag&&!placed&&this.getOneIntersectingObject(Free.class)!=null &&this.getOneIntersectingObject(Blocked.class)==null && this.getOneIntersectingObject(Blocks.class)==null){
            Actor place = this.getOneIntersectingObject(Free.class);
            this.setLocation(place.getX(),place.getY());
            if(!pointAdded){
                Settings f =((Level)getWorld()).sett;
                f.addPoint(1);
            }
            placed = true;
            pointAdded=true;
        }else if( (!pointAdded && this.getOneIntersectingObject(Blocks.class)!=null) ||(!drag && (this.getOneIntersectingObject(Free.class)==null || this.getOneIntersectingObject(Blocked.class)!=null))){
            this.setLocation(220, 404);
        }
        if(Greenfoot.mousePressed(this)) {
            drag = true;
            placed = false;
        }
        if(Greenfoot.mouseClicked(null)) drag = false;
        if(drag) {
            MouseInfo mi = Greenfoot.getMouseInfo();
            this.setLocation(mi.getX()-20, mi.getY()-20);
        } 
    }    
}
if i place the block it would check if there is a Free block in its near and place it at that location. But i just cant think of a way how to do it for the other ones(dreieck, viereck, doppel). I thougth about to do it somehow with the array. e.g if i place a viereck at board it should check if board, board and board are free so that it can "fit in".
You need to login to post a reply.