-3

I have wrote a small tetris clone. Blocks are random, but after 6 or 7 blocks program starts drawing the same block over and over again even when random block is passed to the paintBlock() method.

Class where tetris board is drawn:

       import blocks.AbstractBlock;
    import blocks.BlockController;
    import scores.ScoreController;

    import javax.swing.*;
    import java.awt.*;


    public class GameBoard extends JPanel {
        public static final Integer boardWidth = 10;
        public static final Integer boardHeight = 20;
        public static final Integer cellWidth = 25;
        public static final Integer cellHeight = 25;
        private Cell[][] board = new Cell[boardWidth][boardHeight];
        private Integer iterations;
        private Boolean shutdown;
        private AbstractBlock currentBlock;
        private Long timestamp;

        private Thread movement = new Thread(() -> {
            while (!shutdown) {
                    if((System.currentTimeMillis() - timestamp) > ScoreController.getDelay()) {
                        repaint();
                        moveDown();
                        timestamp = System.currentTimeMillis();
                    }
            }
        });

        public void init() {
            for (int i = 0; i < boardWidth; i++) {
                for (int j = 0; j < boardHeight; j++) {
                    board[i][j] = new Cell(i, j);
                }
            }
            BlockController.init();
            ScoreController.init();
            currentBlock = BlockController.getRandomBlock();
            iterations = 0;
            timestamp = System.currentTimeMillis();
            shutdown = false;
            movement.start();
        }

        public synchronized void moveDown() {
            Point position = BlockController.getBlockPosition();
            if (!findCollisions(position.x, position.y + 1)) {
                BlockController.setBlockPosition(new Cell(position.x, position.y + 1));
                iterations += 1;
                this.repaint();
            } else {
                if (iterations > 0) {
                    secureBlock();
                    clearRows();
                    currentBlock = BlockController.getRandomBlock();
                    iterations = 0;
                } else {
                    shutdown();
                }
            }
        }

        private Boolean findCollisions(Integer x, Integer y) {
            for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
                if (cell.y + y >= boardHeight || cell.x + x >= boardWidth || cell.x + x < 0 ||
                        !(board[cell.x + x][cell.y + y].getColor() == cell.getDefaultColor())) {
                    return true;
                }
            }
            return false;
        }

        public void moveHorizontal(Integer dx) {
            Point position = BlockController.getBlockPosition();
            if (!findCollisions(position.x + dx, position.y)) {
                BlockController.setBlockPosition(new Cell(position.x + dx, position.y));
            }
            repaint();
        }

        private void secureBlock() {
            Cell position = BlockController.getBlockPosition();
            for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
                board[position.x + cell.x][position.y + cell.y].setColor(currentBlock.getColor());
            }
            repaint();
        }

        private void clearRows() {
            Integer rowsCleared = 0;
            Boolean gap;
            for (int j = boardHeight - 1; j >= 0; j--) {
                gap = false;
                for (int i = 0; i < boardWidth; i++) {
                    if (board[i][j].getColor() == board[i][j].getDefaultColor()) {
                        gap = true;
                        break;
                    }
                }
                if (!gap) {
                    deleteRow(j);
                    j = boardHeight - 1;
                    repaint();
                    rowsCleared++;
                }
            }
            if (rowsCleared != 0) {
                ScoreController.rowsCleared(rowsCleared);
            }
        }

        private void deleteRow(Integer y) {
            for (int j = y; j > 0; j--) {
                for (int i = 0; i < boardWidth; i++) {
                    board[i][j].setColor(board[i][j - 1].getColor());
                }
            }
        }

        public void shutdown() {
            shutdown = true;
        }

        public void rotate() {
            BlockController.rotate();
            repaint();
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            paintGameBoard(g);
            paintBlock(g);
        }

        private void paintGameBoard(Graphics g) {
            for (int i = 0; i < boardWidth; i++) {
                for (Cell cell : board[i]) {
                    g.setColor(cell.getColor());
                    g.drawRect(cell.x * cellWidth, cell.y * cellHeight, cellWidth, cellHeight);
                    g.fillRect(cell.x * cellWidth, cell.y * cellHeight, cellWidth, cellHeight);
                }
            }
            g.setColor(Color.WHITE);
            g.drawString("Score: " + ScoreController.getScore(), 10, 20);
            g.drawString("Level: " + ScoreController.getLevel(), 10, 40);
            g.drawString("Rows Cleared: " + ScoreController.getRows(), 10, 60);
        }

        private void paintBlock(Graphics g) {
            Cell position = BlockController.getBlockPosition();
            if (currentBlock != null) {
                for (Cell cell : currentBlock.getShapes()[BlockController.getRotationScale()]) {
                    g.setColor(currentBlock.getColor());
                    g.drawRect((position.x + cell.x) * cellWidth, (position.y + cell.y) * cellHeight, cellWidth, cellHeight);
                    g.fillRect((position.x + cell.x) * cellWidth, (position.y + cell.y) * cellHeight, cellWidth, cellHeight);
                }
            }
        }
    }

I could not find a solution for this issue, so any suggestions are welcome. Thank you in advance.

Edit1: BlockController class - used to return random block and some other stuff.

    import board.Cell;
    import com.google.common.collect.Iterables;

    import java.util.*;
    import java.util.List;

    public class BlockController {

        private static List<String> blockNames = Arrays.asList("I", "J", "L", "O", "S", "T", "Z");
        private static Integer rotationScale;
        private static Cell blockPosition;
        private static final List<Integer> rotations = Arrays.asList(0, 1, 2, 3);
        private static Iterator<Integer> rotationCycle = Iterables.cycle(rotations).iterator();

        private BlockController(){}

        private static AbstractBlock getBlock(String name) {
            switch(name) {
                case "I" : return I_block.getInstance();
                case "J" : return J_block.getInstance();
                case "L" : return L_block.getInstance();
                case "O" : return O_block.getInstance();
                case "S" : return S_block.getInstance();
                case "T" : return T_block.getInstance();
                case "Z" : return Z_block.getInstance();
                default : return null;
            }
        }

        public static void init() {
            setBlockPosition(new Cell(3,0));
            setRotationScale(0);
        }

        public static Cell getBlockPosition() {
            return blockPosition;
        }

        public static void setBlockPosition(Cell blockPosition) {
            BlockController.blockPosition = blockPosition;
        }

        public static Integer getRotationScale() {
            return rotationScale;
        }

        private static void setRotationScale(Integer rotationScale) {
            BlockController.rotationScale = rotationScale;
        }

        public static AbstractBlock getRandomBlock() {
            setBlockPosition(new Cell(3, 0));
            setRotationScale(0);
            rotationCycle = Iterables.cycle(rotations).iterator();
            Collections.shuffle(blockNames);
            return getBlock(blockNames.get(0));
        }

        public static void rotate() {
            setRotationScale(rotationCycle.next());
        }
    }
Vadim.D
  • 1
  • 2
  • 1
    Can you show the `BlockController` code ? You use it to generate the block. The problem may be there. – davidxxx Jul 13 '17 at 19:18
  • 1
    You might try paring down the code to see where it's broken. See [mcve]. – CDahn Jul 13 '17 at 19:22
  • I was going through the code execution with debug and saw that the BlockController returned random block each time, but it drew the same block over and over again anyway. Is there any catch to drawing it perhaps? – Vadim.D Jul 13 '17 at 19:33
  • `return I_block.getInstance() return J_block.getInstance(); ...` Can you show the code ? The object comes from there. – davidxxx Jul 13 '17 at 20:08
  • I have uploaded all source code here - https://codedump.io/share/YnzXOLBVXo8S/1/mainjava Should have done this in the first place. – Vadim.D Jul 13 '17 at 20:28
  • *"I have uploaded all source code here .. Should have done this in the first place."* No, what you **should** have done was follow the advice of @CDahn & prepare a [mcve] to post as an [edit] to the question. People worth listening to, typically do not have the time to trawl though long code in multiple source files. Many people either will not or cannot visit external links. Voting to close. – Andrew Thompson Jul 13 '17 at 22:30

1 Answers1

0

It was caused by the way i was getting my blocks somehow. Simple Map of blocks instead of bunch of singletones helped me solve this. Thank you davidxxx for the tip in this direction.

Vadim.D
  • 1
  • 2