Pergunta

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...

Foi útil?

Solução

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top