-1

Structure of greenfoot https://www.dropbox.com/s/t4pau2mk3mh9npu/structure.JPG I did initiate the var gameState

public class MineBoard extends GWorld
{
    int gameState = 0; 

and when i try to access it from a sub class call "Block" under Actor like this

case 2:
                {
                    //two bombs
                    known=true;
                    setImage("Bomb[2].png");
                    JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
                    GWorld.gameState = 2;

It keeps telling me that cannot find symbol - variable gameState Please help

The whole code of MineBoard

import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.Scanner;
import java.io.*;
import javax.swing.JOptionPane;
import javax.swing.JInternalFrame;

public class MineBoard extends GWorld
{
int gameState;
// 0 for playing, 1 for win, 2 for lose, 3 for game ended
int nBomb = 0;
//The number of bombs on the MineBoard

/**
 * Constructor for objects of class MineBoard.
 * Hint:
 *      width, height: the size of mine board
 *      nBombs: the total number of bombs in the mine board
 */
public MineBoard(int width, int height, int nBombs)
{
    // Create greenfoot world with width and height
    super(width, height, 25);

    // initialize minefield
    initialize();
}

/**
 * Initialize the world
 */
public void initialize() {
    // Create blocks by world width & height
    setnBomb();
    createBlocks();
    gameState = 0;
    // Place bombs randomly on board
    placeBombs();
}

public void setnBomb ()
{
    int sizeOfBoard = GWorld.width();
    switch (sizeOfBoard)
    {
        case 5 : nBomb=3;
        break;
        case 8 : nBomb=10;
        break;
        case 10: nBomb=15;
        break;
        default: break;
    }
}

/**
 * Create blocks  
 * Done
 */
public void createBlocks() {
    // create "Block" objects according to the difficult user choose
    int maxL = GWorld.width();
    for (int i=0; i<maxL; i++)
    {
        for (int u=0; u<maxL; u++)
        {
            Block block = new Block();
            GWorld.addOneObject(block, i,u);
            //create blocks from left to right, from top to bottom
        }        
    }
}

/**
 * Place bombs randomly on the board
 * Hint:
 *      int random(int lowerLimit, int upperLimit)
 *          Use this function to generate a randome number between 
 *          lowerLimit(inlusive) and upperLimit(inclusive)
 *      Block.MAX_BOMB: the max number of bombs per block
 *      Block block = (Block)getOneObjectAt(x, y, "Block");
 *      Place exactly the specified number of bombs. No more!
 * TODO: Part 1
 */
public void placeBombs() {
    //This method place bombs randomly on the MineBoard
    int BombPlanted=0;
    //initialize that the bombs placed is zero
    while (BombPlanted < nBomb)
    {
        int i = random(0,Block.MAX_BOMB+1);
        //random the amount of bombs will be place in the next block
        int u = random (0, GWorld.width()-1);
        int y = random (0, GWorld.height()-1); 
        //random the place to place the bomb(s)
        Block b = (Block) getOneObjectAt(u, y, "Block");
        //access that specific block
        if ((BombPlanted+i < nBomb) && (b.BombInside ==0))
        {
            b.BombInside = i;
            //place the numbers of bombs
            BombPlanted = BombPlanted+i;
            //count the amount of bombs placed
        }
        if ((BombPlanted+i > nBomb) && (b.BombInside ==0))
        {  
            b.BombInside = nBomb-BombPlanted;
            //place bombs until reaching the maximum value
            BombPlanted=nBomb;
            //allow the loop to end without breaking it instantly
        }
    }
}

/**
 *  Reveal all blocks
 *  Hint:
 *      If flagged, reveal it anyway
 *      If it's not a bomb,
 *          For Part 1, show BlockClicked[0].png
 *          For Part 2, show image with correct number.
 *  TODO: Part 1 & Part 2
 */
public void revealAllBlocks() {
    //receal all the blocks
    for (int i=0; i<GWorld.width(); i++)
    {
         for(int u=0; u<GWorld.height(); u++)
         {
             Block b = (Block) getOneObjectAt(i, u, "Block");
             //access blocks one by one
             b.reveal();
             //use the reveal method to reveal blocks one by one
         }
    }
}

/**
 *  Check game win.
 *  Hint:
 *      Correct per block bombs
 *      Correct total bombs
 *      Block should be either Flagged or Revealed
 *      if win, set gameState = 1, return true;
 *  TODO: Part 2
 */
public boolean checkGameWin() {
    int BombsRemain = nBomb;
    int clickedBlock = 0;
    int TotalBlocks = 0;
    TotalBlocks = GWorld.width()*GWorld.width();
    for (int i = 0; i<GWorld.width(); i++)
    {
        for (int u = 0; u<GWorld.height();u++)
        {
            Block b = (Block) getOneObjectAt(i, u, "Block");
            if (b.BombInside == b.flagged)
            {
                BombsRemain = BombsRemain - b.BombInside;
            }
            if (b.known == true || b.flagged>0)
            {
                clickedBlock=clickedBlock+1;
            }
        }
    }
    if (BombsRemain == 0 && TotalBlocks == clickedBlock)
    {
        gameState = 1;
        return true;
    }
    return false;
}

/**
 *  Save board to "filename"
 *      Per block states {
 *          Number of bombs: 0,1,2
 *          Number of flags: 0,1,2
 *          reveal state: true/false
 *      }
 *  TODO: Part 2
 */
protected void saveBoard(String filename) throws Exception {
    if ( gameState != 0 ) {
        showMessage ("Not allowed. Game is finished.");
        return ;
    }
    else
    {
        File saving = new File(filename);
        PrintWriter output = new PrintWriter(saving);
        for (int i = 0; i<GWorld.width(); i++)
        {
            for (int u = 0; u<GWorld.height(); u++)
            {
                //get Block
                Block b = (Block) getOneObjectAt(u, i, "Block");
                //num of bombs
                output.print(b.BombInside + " ");
                //num of flags
                output.print(b.flagged + " ");
                //known or not
                output.print(b.known + " ");
            }
            output.println("");
        }
        output.close();
        //Close file
    }

}

/**
 *  Load board from "filename"
 *  Hint:
 *      First load all blocks
 *      Then show correct images
 *  TODO: Part 2
 */
protected void loadBoard(String filename) throws Exception {
    clearBoard();
    gameState = 0;
    File saving = new File(filename);
    Scanner input = new Scanner(saving);
    for (int i = 0; i<GWorld.width(); i++)
    {
        for (int u = 0; u<GWorld.height(); u++)
        {
            //get Block
            Block b = (Block) getOneObjectAt(u, i, "Block");
            int inputint=0;
            String inputStr = "false";
            inputint = Integer.parseInt(input.next());
            b.BombInside = inputint;
            inputint = Integer.parseInt(input.next());
            b.BombInside = inputint;
            inputStr = input.next();
            b.known = Boolean.getBoolean(inputStr);
        }
    }
    input.close();
    //Close file
    // Add your codes here
}

/**
 *  Gathers all blocks and disposes of them.
 */
public void clearBoard() {
    Actor [] blocks = getAllObjects("Block");
    removeObjectsFromWorld(blocks); 
}

/**
 *  Game lose.
 */
public void gameLose() {
    gameState = 2;
    revealAllBlocks();
}

/**
 *  Check game states
 */
public void act() {
    if ( gameState == 2 ) {
        showMessage ( "Sorry, you lose!" );
        gameState = 3; // Game finished
    }
    if ( gameState == 1 ) {
        showMessage ( "Congratulations! You win!" );
        gameState = 3; // Game finished
    }
}
}

The whole code of Block

import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JInternalFrame;
import java.util.Scanner;
import java.io.*;

public class Block extends Actor
![enter image description here][2]{
static String defaultBlockImg = "Block.png";
static int MAX_BOMB = 2;
int flagged=0;
//how many flags was placed on the block
boolean known = false;
//revealed or not
int BombInside = 0;
//how many bomb inside that block

/**
 * Constructor for objects of class Block.
 * 
 */
public Block() {
    setImage(defaultBlockImg); 
}

public void reveal() 
{
    //reveal the current block and show the correspondent picture
    switch(BombInside)
        {
            case 1:
            {
                //one bomb
                //GWorld.gameState = 2;
                known=true;
                setImage("Bomb[1].png");
                JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
            }    
            break;
            case 2:
            {
                //two bombs
                known=true;
                setImage("Bomb[2].png");
                JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
                //GWorld.gameState = 2;
            }    
            break;
            case 3:
            {
                //three bombs
                known=true;
                setImage("Bomb[3].png");
                JOptionPane.showMessageDialog(new JInternalFrame(), "You Lose!","Mine Sweeper", JOptionPane.INFORMATION_MESSAGE);
                //GWorld.gameState=2;
            }    
            break;
            default:
            {
                //no bombs
                known=true;
                int b=getNumOfNearbyBombs();
                //that block is revealed
                String NumOfBombsInsideStr = "BlockClicked[" + b + "].png";
                setImage(NumOfBombsInsideStr);
                //show the image of nearby bombs
                if (b == 0)
                {
                    propagate();
                    //expand the nearby bomb-free & nearby-bomb-free area
                }
            }
            break;
        }
}

//set the amount of flags on the block
public void flag() {
    if (known == false)
    {
        switch(flagged)
        {
            case 0:
            {
                //if no flag nor revealed, give it one flag
                flagged++;
                setImage("BlockFlagged[1].png");
            }    
            break;
            case 1:
            {
                //if it have one flag and not revealed, give it two flags
                flagged++;
                setImage("BlockFlagged[2].png");
            }    
            break;
            case 2:
            {
                //if it have two flags and not revealed, give it three flags
                flagged++;
                setImage("BlockFlagged[3].png");
            }    
            break;
            default:
            {
                //if three flags and not revealed, remove all flags
                flagged=0;
                setImage("Block.png");
            }
            break;
        }
    }
    else
    {
        //since it was revealed, denied the request
        System.out.println("Revealed already!");
    }
}

protected void leftClick() {
    reveal();
}

protected void rightClick() {
    flag();
}

public int getNumOfNearbyBombs() {
    int BombsNearby = 0;
    //ini the var BombsNearby
    int XPos = getX();
    //X position
    int YPos = getY();
    //Y Position
    //if the block is not on the edge of the board
    if (XPos>0 && XPos <GWorld.width()-1 && YPos>0 && YPos < GWorld.height()-1)
    {
        for (int i = XPos - 1 ; i<XPos+2; i++)
        {
            //Count the bombs on the above colume
            Block b = (Block) GWorld.getOneObjectAt(i, YPos-1, "Block");
            BombsNearby = BombsNearby+b.BombInside;
        }
        for (int i = XPos - 1 ; i<XPos+2; i++)
        {
            //count the bombs on the below colume
            Block bl = (Block) GWorld.getOneObjectAt(i, YPos+1, "Block");
            BombsNearby = BombsNearby+bl.BombInside;
        }
        //bombs in LHS block
        Block blo = (Block) GWorld.getOneObjectAt(XPos-1, YPos, "Block");
        BombsNearby = BombsNearby+blo.BombInside;
        //bombs in RHS block
        Block bloc = (Block) GWorld.getOneObjectAt(XPos+1, YPos, "Block");
        BombsNearby = BombsNearby+bloc.BombInside;
    }
    else
    {
        //Top row
        if (YPos==0 && XPos!=0 && XPos!=GWorld.width()-1)
        {
            //second row, the row right below the first
            for (int i=XPos-1; i<XPos+2; i++)
            {
                Block block = (Block) GWorld.getOneObjectAt(i, 1, "Block");
                BombsNearby = BombsNearby+block.BombInside;
            }
            Block blockL = (Block) GWorld.getOneObjectAt(XPos-1, 0, "Block");
            Block blockR = (Block) GWorld.getOneObjectAt(XPos+1, 0, "Block");
            BombsNearby = BombsNearby+blockL.BombInside;
            BombsNearby = BombsNearby+blockR.BombInside;
            //bombs on the left
            //bombs on the right
        }
        else
        //bottom row
        if (YPos==GWorld.height()-1 && XPos!=0 && XPos!=GWorld.width()-1)
        {
            for (int i=XPos-1; i<XPos+2; i++)
            {
                Block block = (Block) GWorld.getOneObjectAt(i, YPos-1, "Block");
                BombsNearby = BombsNearby+block.BombInside;
            }
            Block blockL = (Block) GWorld.getOneObjectAt(XPos-1, YPos, "Block");
            Block blockR = (Block) GWorld.getOneObjectAt(XPos+1, YPos, "Block");
            BombsNearby = BombsNearby+blockL.BombInside;
            BombsNearby = BombsNearby+blockR.BombInside;
            //bombs on top
            //bombs on left
            //bombs on right
        }
        else
        //Right colume
        if (XPos==GWorld.width()-1 && YPos!=0 && YPos!=GWorld.height()-1)
        {
            for (int i=YPos-1; i<YPos+2; i++)
            {
                Block block = (Block) GWorld.getOneObjectAt(XPos-1, i, "Block");
                BombsNearby = BombsNearby+block.BombInside;
            }
            Block blockU = (Block) GWorld.getOneObjectAt(XPos, YPos-1, "Block");
            Block blockL = (Block) GWorld.getOneObjectAt(XPos, YPos+1, "Block");
            BombsNearby = BombsNearby+blockU.BombInside;
            BombsNearby = BombsNearby+blockL.BombInside;
        }
        else
        //Left colume
        if (XPos==0 && YPos!=0 && YPos!=GWorld.height()-1)
        {
            for (int i=YPos-1; i<YPos+2; i++)
            {
                Block block = (Block) GWorld.getOneObjectAt(1, i, "Block");
                BombsNearby = BombsNearby+block.BombInside;
            }
            Block blockU = (Block) GWorld.getOneObjectAt(0, YPos-1, "Block");
            Block blockL = (Block) GWorld.getOneObjectAt(0, YPos+1, "Block");
            BombsNearby = BombsNearby+blockU.BombInside;
            BombsNearby = BombsNearby+blockL.BombInside;
        }
        else
        //Top left
        if (XPos==0 && YPos==0)
        {
            Block block1 = (Block) GWorld.getOneObjectAt(0, 1, "Block");
            Block block2 = (Block) GWorld.getOneObjectAt(1, 0, "Block");
            Block block3 = (Block) GWorld.getOneObjectAt(1, 1, "Block");
            BombsNearby = BombsNearby+block1.BombInside;
            BombsNearby = BombsNearby+block2.BombInside;
            BombsNearby = BombsNearby+block3.BombInside;
            //3 statements for 3 blocks
        }
        else
        //Bottom left
        if (XPos==0 && YPos==GWorld.height()-1)
        {
            Block block1 = (Block) GWorld.getOneObjectAt(0, YPos-1, "Block");
            Block block2 = (Block) GWorld.getOneObjectAt(1, YPos, "Block");
            Block block3 = (Block) GWorld.getOneObjectAt(1, YPos-1, "Block");
            BombsNearby = BombsNearby+block1.BombInside;
            BombsNearby = BombsNearby+block2.BombInside;
            BombsNearby = BombsNearby+block3.BombInside;
            //3 statements for 3 blocks
        }
        else
        //Top right
        if (XPos==GWorld.width()-1 && YPos==0)
        {
            Block block1 = (Block) GWorld.getOneObjectAt(XPos, 1, "Block");
            Block block2 = (Block) GWorld.getOneObjectAt(XPos-1, 1, "Block");
            Block block3 = (Block) GWorld.getOneObjectAt(XPos-1, 0, "Block");
            BombsNearby = BombsNearby+block1.BombInside;
            BombsNearby = BombsNearby+block2.BombInside;
            BombsNearby = BombsNearby+block3.BombInside;
            //3 statements for 3 blocks
        }
        else
        //Bottom right
        if (XPos==GWorld.width()-1 && YPos==GWorld.height()-1)
        {
            Block block1 = (Block) GWorld.getOneObjectAt(XPos, YPos-1, "Block");
            Block block2 = (Block) GWorld.getOneObjectAt(XPos-1, YPos, "Block");
            Block block3 = (Block) GWorld.getOneObjectAt(XPos-1, YPos-1, "Block");
            BombsNearby = BombsNearby+block1.BombInside;
            BombsNearby = BombsNearby+block2.BombInside;
            BombsNearby = BombsNearby+block3.BombInside;
            //3 statements for 3 blocks
        }
    }
    return BombsNearby;
}

/**
 * Propagate empty block
 * TODO: Part 2
 */
public void propagate()  
{
    //too long for this website, skipped
}

/**
 * Act - do whatever the Block wants to do. This method is called whenever
 * the 'Act' or 'Run' button gets pressed in the environment.
 */
public void act() {
    // Handle mouse message
    handleMouseClick();
}

/**
 * Handle mouse message
 */
protected void handleMouseClick() {
    if ( ((MineBoard)getWorld()).gameState != 0 )
        return;

    if( Greenfoot.mouseClicked(this) ) {
        if ( Greenfoot.getMouseInfo().getButton() == 1 )
            leftClick();
        else if ( Greenfoot.getMouseInfo().getButton() == 3 )
            rightClick();
        if ( ((MineBoard)getWorld()).gameState == 0 )
            ((MineBoard)getWorld()).checkGameWin();
    }
}

/**
 * Get nearby blocks
 */
public Block[] getNearbyBlocks() {
    List<Block> blocks = getNeighbours(1,true,Block.class);
    return blocks.toArray(new Block[blocks.size()]);
}
}
Louis Tsai
  • 1,587
  • 3
  • 20
  • 33

4 Answers4

0

Change GWorld.gameState = 2; to this.gameState = 2; if you are accessing it from a subclass (and since it is not a static variable).

According to the "Inheritance" section of the Java Tutotial

A subclass inherits all of the public and protected members of its parent, 
no matter what package the subclass is in. If the subclass is in the same package 
as its parent, it also inherits the package-private members of the parent.

NOTE:
Since the gameState variable is package-private, in order for it to be inherited by a subclass, the two classes have to be in the same package.

gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • It might help to see the compelte code (at least for MineBoard). Or even better a **[SSCCE](http://sscce.org/)**. Is `gameState` also declared in `GWorld` class ? – gkalpak May 15 '13 at 09:09
  • This makes it a whole new :) See my [second answer](http://stackoverflow.com/questions/16560220/why-cannot-find-symbol-variable-gamestate/16561823#16561823). – gkalpak May 15 '13 at 09:54
0

If your gameState variable local defined in your MineBoard class ( I see it from your code in question) and it the other part of the code is inside a non-static method in same class, then you can access gameState variable directly like :

gameState = 2;

Also, if your GWorld class doesn't have gameState static variable, then it will keep
saying cannot find symbol

Abubakkar
  • 15,488
  • 8
  • 55
  • 83
  • it still happens. it still says the same thing. I declear gameState in a sub class of GWorld. I tried changing GWorld to MineBoard, but it does not allow me to do so. – Louis Tsai May 15 '13 at 08:59
  • where it the second part of the code that you have mentioned in the question? Is it in a method inside `MineBoard`? – Abubakkar May 15 '13 at 09:02
  • i guess not. it is the setting of greenfoot. there are two class, World and Actor, MineBoard in a subclass of GWorld, which is a subclass of World; Block is a subclass of Block – Louis Tsai May 15 '13 at 09:10
  • how can you access gameState in Block class like Gworld.gameState , its not static variable , got it make it static , because gameState remains same for whole game , so it gets updated , – anshulkatta May 15 '13 at 09:30
  • remove that `int gameState = 0;` and write in inside `GWorld` class as `public static int gameState = 0;` – Abubakkar May 15 '13 at 09:32
  • and does Actor class extend GWorld , because Block extends Actor , so Actor should extend GWorld too – anshulkatta May 15 '13 at 09:34
  • the greenfoot software do not allow me to access GWorld class, only it's subclasses are accessable – Louis Tsai May 15 '13 at 09:36
  • structure of those classes: World>>GWorld>>MineBlock and then there is another class call Actor>>Block – Louis Tsai May 15 '13 at 09:41
  • ok , MineBoard is subclass of Gworld , that you want to use in Block class , then do one thing , make setter , getter in MineBoard class for gameState variable and with MineBoard instance set the gameState to 2 or 3 – anshulkatta May 15 '13 at 09:42
0

If GWorld is classname then it is not allowed to call variable gameState like this , because it is not static variable.

You have to make instance either of Superclass or Subclass to access gameState variable.

GWorld gw=new Gworld();
gw.gameState=2;

or

MineBoard  mb=new MineBoard();
mw.gameState=2;

or

this.gameState=2;

EDIT

in MineBoard class make setter and getter method for gameState variable like this

public int getGamestate() {
        return gamestate;
    }

    public void setGamestate(int gamestate) {
        this.gamestate = gamestate;
    }

then in Block class set gameState like this , but you need reference of current MineBoard class to set the variable gameState

// but this is new object not the one which currently game is running , you need to get current instance ,
MineBoard mb=new MineBoard();   

mbsetGamestate(2);

and i remind you again that since you have re declared the variable gameState in MineBoard class , it is not nothing to do with Gworld gameState variable, you have hidden it by re-declaring it.

anshulkatta
  • 2,044
  • 22
  • 30
0

Based on the new code you posted:
You want to access a variable (namely gameState) of a MineBoard instance that is the "parent"[*] of a certain Block instance. One way to achieve that, is the following:

In the Block Class

// 1. Add a final, protected variable referencing the "parent" MineBoard instance
final protected MineBoard parentBoard;

// 2. Initialize it in the constructor. Change the constructor to:
public Block(MineBoard parentBoard) {
    this.parentBoard = parentBoard;
    setImage(defaultBlockImg); 
}

// 3. Access the parent-board's 'gameState' variable
case 2:
    ...
    this.parentBoard.gameState = 2;
    // or even 'this.parentBoard.gameLose();'
    ...

In the MineBoard Class:

// 1. Change all occurrences of 
... = new Block();
// to pass the parent-board as parameter
... = new Block(this);

That should do it...

[*] In this context, "parent board" designates the board that a certain Block is a part of and should not be confused with "parent class" (in the context of Java inheritance).

gkalpak
  • 47,844
  • 8
  • 105
  • 118