2
\$\begingroup\$

I'm currently implementing a Minesweeper clone in Java using Swing. Rather than updating the tiles like so

  @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int row = 0; row < rows; row++ )
        {
            for (int column = 0; column < columns; column++)
            {
                //Update each tile here...
            }
        }
    }

I've created a method that's called when the user clicks a game tile

  public void updatePanel(int r, int c)
    {
        int state = 0;

        //In this case, recursive reveal happens so every tile needs to be checked
        if(frame.getModel().determineAdjacent(r, c) == 0)
        {
            for (int row = 0; row < rows; row++)
            {
                for (int column = 0; column < columns; column++)
                {
                    state = frame.getModel().getState(row, column);
                    updateTileImage(row, column, state);      
                }
            }
        }
        //Otherwise, only one tile needs to be updated
        else 
        {
            updateTileImage(r, c, frame.getModel().getState(r, c));
        }


        //Display all mines if the player loses
        if (frame.getModel().isGameOver() && frame.getModel().getMineCount() > 0)
        {
            for (int row = 0; row < rows; row++ )
            {
                for (int column = 0; column < columns; column++)
                {
                    //If the tile flagged isn't a mine, display the falsely flagged mine image
                    if (!frame.getModel().isMine(row, column) && frame.getModel().getState(row, column) == MineBoard.FLAGGED)
                    {
                        tiles[row][column].setImage(falselyFlagged, IMAGE_SIZE, IMAGE_SIZE); 
                    }

                    //Otherwise, if the tile is a mine and is not flagged, display the mine
                    else if (frame.getModel().isMine(row, column) && frame.getModel().getState(row, column) != MineBoard.FLAGGED)
                    {
                        tiles[row][column].setImage(mine, IMAGE_SIZE, IMAGE_SIZE); 
                    }
                }
            }

            //Update the clicked tile to display that it was the opened mine
            tiles[r][c].setImage(openedMine, IMAGE_SIZE, IMAGE_SIZE);
            JOptionPane.showMessageDialog(null, "Game Over. Mines Remaining: " + frame.getModel().getMineCount());
        }

        //Otherwise, print out a method indicating the player's success
        else if (frame.getModel().isGameOver() && frame.getModel().getMineCount() == 0)
        {
            JOptionPane.showMessageDialog(null, "You Win!");
        } 
        repaint();
    }

This method is called here

public class GameButton extends JButton
{
    private static final long serialVersionUID = 3942095583293438553L;

    public GameButton(MineFrame frame, int row, int col)
    {
        super();
        this.addMouseListener(new MouseAdapter() 
        { 
            public void mouseClicked(MouseEvent e)
            {
                if (!frame.getModel().isGameOver())
                {
                    //Left-Click
                    if (e.getButton() == 1)
                    {
                        frame.getModel().reveal(row, col);
                    }
                    //Right-Click
                    else if (e.getButton() == 3)
                    {
                        switch (frame.getModel().getState(row, col))
                        {
                            case MineBoard.HIDDEN_TILE:
                                frame.getModel().flag(row, col);
                                break;
                            case MineBoard.FLAGGED:
                                frame.getModel().question(row, col);
                                break;
                            case MineBoard.QUESTION:
                                frame.getModel().hide(row, col);
                                break;
                        }
                    }

                    //Update the contents of the panel to reflect changes
                    frame.getPanel().updatePanel(row, col); 
                }
            }
        });
    }

Furthermore, the constructor for MinePanel

public MinePanel(MineFrame frame)
{
        super();
        this.frame = frame;
        rows = frame.getModel().getRows();
        columns = frame.getModel().getColumns();
        tiles = new GameButton[rows][columns];
        iconsList = initalizeImageList();
        grid = new GridLayout(rows,columns);
        setLayout(grid);

        for (int x = 0; x < rows; x++)
        {
            for (int y = 0; y < columns; y++)
            {
                GameButton tile = new GameButton(frame, x, y);
                tiles[x][y] = tile;
                add(tile);
                updateTileImage(x, y, frame.getModel().getState(x, y));
            }
        }
        repaint();
    }

I initially implemented it this way as a means of being efficient and from my point of view it works perfectly, but is there anything inherently wrong with it?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.