0

I have an AP Computer Science assignment to make Tetris using GridWorld. I have to make 4 classes, TetrisBug, TetrisGame, TetrisBlock, and TetrisBlockO.
Here are the codes in that order:

TetrisBug.java

import info.gridworld.actor.*;
import info.gridworld.grid.*;
import java.util.ArrayList;
import java.awt.Color;

public class TetrisBug extends Bug
{
    public TetrisBug(Color color)
    {
        super(color);
        setDirection(180);
    }

    public void move()
    {

        Grid<Actor> gr = getGrid();
        if (gr == null)
            return;
        Location loc = getLocation();
        Location next = loc.getAdjacentLocation(getDirection());
        if (gr.isValid(next))
            moveTo(next);
        else
            removeSelfFromGrid();
    }

    public void act()
    {
        //this is empty for a reason.
    }
}

TetrisGame.java

import info.gridworld.actor.*;
import info.gridworld.grid.*;
import java.util.ArrayList;
import java.awt.Color;
import info.gridworld.*;

public class TetrisGame {

    public static ActorWorld world = new ActorWorld(new BoundedGrid<Actor>(19, 17));

    public static TetrisBlock currentBlock;

    public static int score;

    public static void main(String[] args) {
        //set up world
        for (int i = 0; i < 19; i++) {
            world.add(new Location(i,11),new Rock());
            world.add(new Location(i,0),new Rock());
        }
        nextTetrisBlock();
        //needed code for keyboard event handling
    java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new java.awt.KeyEventDispatcher() {
        public boolean dispatchKeyEvent(java.awt.event.KeyEvent event) {
            String key = javax.swing.KeyStroke.getKeyStrokeForEvent(event).toString();
            if (key.equals("pressed UP"))
                currentBlock.rotate();
            if (key.equals("pressed RIGHT"))
                currentBlock.moveRight();
            if (key.equals("pressed DOWN"))
                currentBlock.act();
            if (key.equals("pressed LEFT"))
                currentBlock.moveLeft();
            world.show();
            return true;
        }
    });
        world.show();
    }
    /**
    * Calls removeCompleteRows and chooses a new TetrisBlock at random
    */
    public static void nextTetrisBlock() {
        removeCompleteRows();
        TetrisBlock randomBlock = new TetrisBlock();//default 2block piece
        //choose random block
        int randNum = (int)(Math.random()*7)+1;//random number between 1 and 7
        //if(randNum == 1)
            // randomBlock = new TetrisBlockO();
        //if(randNum == 2)
            // randomBlock = new TetrisBlockI();
        //if(randNum == 3)
            // randomBlock = new TetrisBlockT();
        //if(randNum == 4)
            // randomBlock = new TetrisBlockL();
        //if(randNum == 5)
            // randomBlock = new TetrisBlock_L();
        //if(randNum == 6)
            // randomBlock = new TetrisBlockZ();
        //if(randNum == 7)
            // randomBlock = new TetrisBlock_Z();
        currentBlock = randomBlock;
    }
    /**
    * checks each row 1 through 18 (skip row 0) for full rows
    * if a row is full, then remove the actor from each cell in that row
    * and ask each actor located above the just deleted row to act and
    * update the score++
    */
    public static void removeCompleteRows() {
        int columnsFilled = 0;
        Grid grid = world.getGrid();
        int row = 0;
        //loops through rows only after each column has finished
        for(row = grid.getNumRows()-1; row >= 0; row--) {        //needed >=
            columnsFilled = 0;             //need to reinitialize this every iteration
            for(int col = 0; col <= grid.getNumCols() - 1; col++) { //needed <=

                if (grid.get(new Location(row,col)) != null) {
                    columnsFilled++;
                }
            }
            if (columnsFilled == 10) {
                for(int col = 0; col <= grid.getNumCols(); col++){
                    world.remove(new Location(row,col));
                }
                columnsFilled =0;
            }
        }
    }
}

TetrisBlock.java

import info.gridworld.actor.*;
import info.gridworld.grid.*;
import java.util.ArrayList;
import java.awt.Color;
/**
 * TetrisBlock is a type of Bug. It will act in GridWorld by moving down
 * (direction 180) if it can, otherwise it will ask TetrisGame to make a new
 * TetrisBlock for the game.
 */
public class TetrisBlock extends TetrisBug {
    /**
     * value of the current rotation position {0,1,2 or 3}
     */
    protected int rotationPos;
    /**
     * blocks will have three TetrisBug objects in it... they will be added in the
     * constructor
     */
    protected ArrayList<TetrisBug> blocks;
    /**
     * used as a convenient reference to the Grid
     */
    protected Grid<Actor> gr;
    /**
     * default constructor
     */
    public TetrisBlock() {
        super(Color.blue);
        rotationPos = 0;
        gr = TetrisGame.world.getGrid();
        // ==> LAMEST GAME OVER EVER !!! <==
        // if the Grid does not have room for the TetrisBlock.. GameOver
        if (gr.get(new Location(0, 5)) != null
        || gr.get(new Location(1, 5)) != null) {
            javax.swing.JOptionPane.showMessageDialog(null, "Score: "
                + TetrisGame.score, "GAME OVER!", 0);
            System.exit(0);
        }
        putSelfInGrid(gr, new Location(1, 5));
        blocks = new ArrayList<TetrisBug>();
        TetrisBug a;
        // create TetrisBugs for ArrayList blocks and put them in Grid gr
        a = new TetrisBug(Color.blue);
        a.putSelfInGrid(gr, new Location(0, 5));
        blocks.add(a);
        // TetrisBlock subclasses will add two more TetrisBug objects to blocks
    }

    /**
     * TetrisBlock and its TetrisBugs must face down (direction 180) If they can
     * move down, they will. Otherwise, it will ask TetrisGame to create a new
     * TetrisBlock since this one is stuck at the bottom.
     */
    public void act() {
        setDirection(180);
        for (TetrisBug tb : blocks)
            tb.setDirection(180);
        if (canMoveDown())
            moveDown();
        else {
            if (!TetrisGame.currentBlock.canMoveDown())
                TetrisGame.nextTetrisBlock();
        }
    }

    /**
     * Move the TetrisBlock and its TetrisBugs one cell. (they should already be
     * facing down) Note: The order in which all the TetrisBugs move is important
     * and depends on the current rotationPos.
     */
    public void moveDown() {
        if (rotationPos == 0) {
            move();
            blocks.get(0).move();
        } else if (rotationPos == 1) {
            blocks.get(0).move();
            move();
        }
    }

    /**
     * Returns true if the TetrisBlock and its TetrisBugs can move (they should
     * already be facing down) Otherwise, returns false.
     */
    public boolean canMoveDown() {
        if (rotationPos == 0)
            return canMove();
        else if (rotationPos == 1)
            return canMove() && blocks.get(0).canMove();
        else
            return true;
    }

    /**
     * Sets the direction of the TetrisBlock and its TetrisBugs to 90 (right) If
     * they can move, they will move one cell (to the right)
     */
    public void moveRight() {
        setDirection(90);
        for (TetrisBug tb : blocks)
            tb.setDirection(90);
        if (rotationPos == 0) {
            if (canMove() && blocks.get(0).canMove()) {
                blocks.get(0).move();
                move();
            }
        } else if (rotationPos == 1) {
            if (canMove()) {
                move();
                blocks.get(0).move();
            }
        }
    }

    /**
     * Sets the direction of the TetrisBlock and its TetrisBugs to 90 (right) If
     * they can move, they will move one cell (to the right)
     */
    public void moveLeft() {
        setDirection(270);
        for (TetrisBug tb : blocks)
            tb.setDirection(270);
        if (rotationPos == 0) {
            if (canMove() && blocks.get(0).canMove()) {
                blocks.get(0).move();
                move();
            }
        } else if (rotationPos == 1) {
            if (canMove() && blocks.get(0).canMove()) {
                blocks.get(0).move();
                move();
            }
        }
    }

    /**
     * If the TetrisBlock and its TetrisBugs can rotate, then they will all move
     * to their proper location for the given rotation designated by
     * rotationPos... Update rotationPos.
     */
    public void rotate() {
        Location nextLoc;
        if (rotationPos == 0) {
            // only one block must move
            nextLoc = new Location(getLocation().getRow() - 1,
                getLocation().getCol() + 1);
            if (gr.isValid(nextLoc) && gr.get(nextLoc) == null) {
                moveTo(nextLoc);
                rotationPos = (rotationPos + 1) % 2;// will be % 4 with 4 blocks
            }
        } else if (rotationPos == 1) {
            nextLoc = new Location(getLocation().getRow() + 1,
                getLocation().getCol() - 1);
            if (gr.isValid(nextLoc) && gr.get(nextLoc) == null) {
                moveTo(nextLoc);
                rotationPos = (rotationPos - 1) % 2;// will be % 4 with 4 blocks
            }
        }
    }
}

TetrisBlockO.java

public class TetrisBlockO{
public TetrisBlockO() {
        rotationPos = 0;
        gr = TetrisGame.world.getGrid();

        //GAME OVER!
        if (gr.get(new Location(0, 5)) != null
         || gr.get(new Location(1, 5)) != null
         || gr.get(new Location(0, 6)) != null
         || gr.get(new Location(1, 6)) != null) {
            javax.swing.JOptionPane.showMessageDialog(null, "Score: " + TetrisGame.score, "GAME OVER!", 0);
            System.exit(0);
        }

        putSelfInGrid(gr, new Location(1, 5));

        blocks = new ArrayList<TetrisBrick>();

        TetrisBrick a;
        a = new TetrisBrick(Color.blue);
        a.putSelfInGrid(gr, new Location(0, 5));
        blocks.add(a);

        TetrisBrick b;
        b = new TetrisBrick(Color.blue);
        b.putSelfInGrid(gr, new Location(1, 6));
        blocks.add(b);

        TetrisBrick c;
        c = new TetrisBrick(Color.blue);
        c.putSelfInGrid(gr, new Location(0, 6));
        blocks.add(c);
    }
}

The first problem I'm having is in TetrisGame. The last method, to be precise. The grid.length statement is refusing to compile, and when I added a Grid grid = new Grid(); statement, it said it was abstract method and couldn't be instantiated. And compiling any of them give me a compiler warning,

\GridworldTetris\TetrisGame.java uses unchecked or unsafe operations.  
Recompile with -Xlint:unchecked for details

The second problem is with the rotate method in TetrisBlock. I am not sure whether it works or not since the TetrisGame wont compile. I cant test it, but a friend of mine keeps telling me it's wrong, though IDK whether to believe him. Some validation would be nice.

Anyway, I have no real time limit on this, but I'd really like to be done with it. Thanks.

~Keelen

UPDATE: Thanks to user3580294 I solved the grid problem. But I found another, GRID DOESNT HAVE A LENGTH METHOD... I know what I was trying to do WOULD work, but cant find a way to do it, besides grid.length, which is invalid. Could someone make me a method that'd successfully remove completed rows? I really am stuck here... And I want to move to the next project...

HMR
  • 37,593
  • 24
  • 91
  • 160
BMK600
  • 19
  • 1
  • 8
  • If `Grid` is an abstract class, you can't instantiate it by definition. And you should really follow the advice given by `javac` and recompile with additional warnings to see what exactly's going on – awksp May 14 '14 at 20:31
  • Also, I'm guessing `grid.length` doesn't compile because `grid` is never defined in that class – awksp May 14 '14 at 20:33
  • Ok. I'm new at this, new enough to not know the definitions of abstract classes by heart. Also, IDK what you mean by recompile with additional warnings. I'm really new to this, less than a year, so... I don't know what javac is. – BMK600 May 14 '14 at 20:34
  • And I stated when I defined grid, it gave me the abstract warning. – BMK600 May 14 '14 at 20:34
  • I took AP Comp Sci a few years ago. My memory is faulty, but Grid was an interface. You cannot instantiate an interface, you need to choose an implementation. For example, you can say Grid g = new BoundedGrid(parameters here); – Solace May 14 '14 at 20:40
  • @KeelenBerkenkotter Solace got it there. I thought APCS taught you abstract classes though... As for additional warnings, I was going off of the compiler warning said. How are you compiling your code? – awksp May 14 '14 at 20:42
  • @user3580294 Yeah, APCS teaches SOME abstract classes, I was just being a space cadet and forgetting the basics (Derp). I am just compiling through Bluej's compile button. That's the only way to do it in BlueJ (I think). – BMK600 May 14 '14 at 20:50
  • @KeelenBerkenkotter Ah, interesting. Looks like `BlueJ` uses `javac` (the compiler that comes with the JDK) to do its work. It's difficult to say what unchecked/unsafe warnings BlueJ was talking about with enabling those flags... BlueJ's website suggests altering the "bluej.defs" file, but having never used that particular IDE I don't know where that is or how to alter it... Do you happen to know what that file is? – awksp May 14 '14 at 20:57
  • @user3580294 No. I think it'd be in the program files (duh) but the school tries to limit us out of those (but since it's a school, they don't have enough cash to get some decent blocking software), but I don't want to get in trouble. I'll just monkey around a bit with it. I still need help with the grid.length thing. I realized... grid doesn't have a length method. DERP. I know what I was trying to do, but I'm not sure how to do it. Any help is appreciated. – BMK600 May 14 '14 at 21:04
  • Oh I see... Can't use a different IDE like Eclipse either? You never defined `grid` in TetrisGame.java, from what I can see... What are you trying to do? – awksp May 14 '14 at 21:09
  • Make tetris. Using TetrisBug as the blocks. I updated the code now. – BMK600 May 14 '14 at 21:30
  • I still don't see where you defined `grid` in TetrisGame... – awksp May 14 '14 at 21:33
  • I changed it. It's the "Grid grid = world.getGrid();" line. – BMK600 May 14 '14 at 21:37
  • It should be `Grid grid = world.getGrid();`. The TetrisBlockO is not helpful to post because it won't compile anyways, its missing variable declarations. – Ferret9 May 14 '14 at 23:50

1 Answers1

0

For your removeCompleteRows() method try this in your if statement:

if (columnsFilled == 10) {
    for(int col = 1; col < grid.getNumCols() - 1; col++){
        grid.get(new Location( row,col )).removeSelfFromGrid();
    }
    columnsFilled = 0;
}

I think the World remove() method might work, but generally you won't have access to the World your Actor is on, so using Grid's removeSelfFromGrid() is safer.

Also, I assume you only want to remove the Blocks not your walls so you only want to iterate through Locations your Blocks might occupy, 1 through getNumCols() - 1.

Ferret9
  • 101
  • 1
  • 12