java - GridWorld中的俄罗斯方 block 无法编译

标签 java compiler-errors tetris gridworld

我有一份AP计算机科学作业,可以使用GridWorld制作Tetris。我必须制作4个类,TetrisBugTetrisGameTetrisBlockTetrisBlockO
以下是该顺序的代码:

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);
    }
}

我遇到的第一个问题是TetrisGame。准确地说,最后一种方法。 grid.length语句拒绝编译,当我添加Grid grid = new Grid();语句时,它说这是抽象方法,无法实例化。编译其中任何一个都会给我一个编译器警告,

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


第二个问题是rotate中的TetrisBlock方法。由于TetrisGame无法编译,因此我不确定它是否有效。我无法测试,但是我的一个 friend 不断告诉我这是错误的,尽管IDK是否相信他。一些验证会很好。

无论如何,我对此没有实时限制,但是我真的很想这么做。谢谢。

〜基伦

更新:感谢user3580294我解决了网格问题。但是我发现另一种GRID不具有长度方法...我知道我想做的工作,但是除了grid.length之外,找不到其他方法,这是无效的。有人可以为我提供一种可以成功删除完成的行的方法吗?我真的被困在这里...我想转到下一个项目...

最佳答案

对于您的removeCompleteRows()方法,请在if语句中尝试以下操作:

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

我认为World remove()方法可能有效,但通常您无法访问World处于启用状态的Actor,因此使用GridremoveSelfFromGrid()更安全。

另外,我假设您只想删除块而不是墙,所以只想遍历您的块可能占用的Locations,即1getNumCols() - 1

关于java - GridWorld中的俄罗斯方 block 无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23664487/

相关文章:

java - PublishSubject 和 BehaviorSubject 如何退订?

java - 检测同根词

vim - Vim 自动转到下一个编译错误

c++ - 创建面向对象的链表时出现编译问题(编译器错误 C2664)

c - C 中的俄罗斯方 block 函数向右移动

python - 俄罗斯方 block 计时问题

JavaScript 俄罗斯方 block 在移动和旋转后分开

java - 使用 twitter4j 从 twitter 获取视频 url

Java 开发的 Zip 文件在 Windows 7 默认情况下无法打开

c# - 编译器不一致的可访问性错误,将嵌套类作为函数参数传递