2

This is my slider puzzle game. So far it can only do 3x3 games. When I try and pass the variables l and w (length and width) of the board it doesn't work. It only works when i set the variables ROWS and COLS as finals. When I try and change it I get errors. I'm not sure what to do, any help would be appreciated.

Currently the user can input values that can't do anything at the moment. When the game is started, a 3x3 board is generated. The user can restart the game with a different scrambled board but the buttons that solve the board and the buttons that reset the board to the original state do not work yet.

public class SlidePuzzle {

public static void main(String[] args) 
{

    JFrame window = new JFrame("Slide Puzzle");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    String length = JOptionPane.showInputDialog("Length");
    String width = JOptionPane.showInputDialog("Width");
    int l = Integer.parseInt(length);
    int w = Integer.parseInt(width);
    window.setContentPane(new SlidePuzzleGUI());
    window.pack();  
    window.show();  
    window.setResizable(false);

}
}

public class SlidePuzzleGUI extends JPanel
{

private GraphicsPanel    _puzzleGraphics;
private SlidePuzzleModel _puzzleModel = new SlidePuzzleModel();

This class contains the GUI for the Slider Puzzle

public SlidePuzzleGUI() {

    JButton newGameButton = new JButton("New Game");
    JButton resetButton = new JButton("Reset");
    JButton solveButton = new JButton("I GIVE UP :(");

    resetButton.addActionListener(new ResetAction());
    newGameButton.addActionListener(new NewGameAction());


    JPanel controlPanel = new JPanel();
    controlPanel.setLayout(new FlowLayout());
    controlPanel.add(newGameButton);
    controlPanel.add(resetButton);
    controlPanel.add(solveButton);


    _puzzleGraphics = new GraphicsPanel();

    this.setLayout(new BorderLayout());
    this.add(controlPanel, BorderLayout.NORTH);
    this.add(_puzzleGraphics, BorderLayout.CENTER);
}

This is the graphics panel

class GraphicsPanel extends JPanel implements MouseListener {
    private static final int ROWS = 3;
    private static final int COLS = 3;

    private static final int CELL_SIZE = 80; 
    private Font _biggerFont;



    public GraphicsPanel() {
        _biggerFont = new Font("SansSerif", Font.BOLD, CELL_SIZE/2);
        this.setPreferredSize(
               new Dimension(CELL_SIZE * COLS, CELL_SIZE*ROWS));
        this.setBackground(Color.black);
        this.addMouseListener(this); 
    }



    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int r=0; r<ROWS; r++) {
            for (int c=0; c<COLS; c++) {
                int x = c * CELL_SIZE;
                int y = r * CELL_SIZE;
                String text = _puzzleModel.getFace(r, c);
                if (text != null) {
                    g.setColor(Color.gray);
                    g.fillRect(x+2, y+2, CELL_SIZE-4, CELL_SIZE-4);
                    g.setColor(Color.black);
                    g.setFont(_biggerFont);
                    g.drawString(text, x+20, y+(3*CELL_SIZE)/4);
                }
            }
        }
    }



    public void mousePressed(MouseEvent e) {

        int col = e.getX()/CELL_SIZE;
        int row = e.getY()/CELL_SIZE;

        if (!_puzzleModel.moveTile(row, col)) {

            Toolkit.getDefaultToolkit().beep();
        }

        this.repaint();
    }



    public void mouseClicked (MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered (MouseEvent e) {}
    public void mouseExited  (MouseEvent e) {}
}

public class NewGameAction implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        _puzzleModel.reset();
        _puzzleGraphics.repaint();
    }
}
public class ResetAction implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        _puzzleModel.tryAgain();
        _puzzleGraphics.repaint();

    }

}

public class solveAction implements ActionListener
{

    @Override
    public void actionPerformed(ActionEvent e)
        {
            _puzzleModel.solve();
            _puzzleGraphics.repaint();

        }

    }
}
public class SlidePuzzleModel {
private static final int ROWS = 3;
private static final int COLS = 3;

private Tile[][] _contents;  
private Tile[][] _solved;
private Tile     _emptyTile; 



public SlidePuzzleModel() {
    _contents = new Tile[ROWS][COLS];
    reset();
}



String getFace(int row, int col) {
    return _contents[row][col].getFace();
}



public void reset() {
    for (int r=0; r<ROWS; r++) {
        for (int c=0; c<COLS; c++) {
            _contents[r][c] = new Tile(r, c, "" + (r*COLS+c+1));
        }
    }

    _emptyTile = _contents[ROWS-1][COLS-1];
    _emptyTile.setFace(null);


    for (int r=0; r<ROWS; r++) {
        for (int c=0; c<COLS; c++) {
            exchangeTiles(r, c, (int)(Math.random()*ROWS)
                              , (int)(Math.random()*COLS));
        }
    }
}

public void tryAgain()
{

}

public void solve()
{
    for (int i = 1; i < ROWS+1;i++)
    {
        for(int j = 1; j < COLS+1;j++)
        {
            exchangeTiles(i, j, i, j);
        }
    }
}


public boolean moveTile(int r, int c) {

    return checkEmpty(r, c, -1, 0) || checkEmpty(r, c, 1, 0)
        || checkEmpty(r, c, 0, -1) || checkEmpty(r, c, 0, 1);
}

private boolean checkEmpty(int r, int c, int rdelta, int cdelta) {
    int rNeighbor = r + rdelta;
    int cNeighbor = c + cdelta;

    if (isLegalRowCol(rNeighbor, cNeighbor) 
              && _contents[rNeighbor][cNeighbor] == _emptyTile) {
        exchangeTiles(r, c, rNeighbor, cNeighbor);
        return true;
    }
    return false;
}

public boolean isLegalRowCol(int r, int c) {
    return r>=0 && r<ROWS && c>=0 && c<COLS;
}



private void exchangeTiles(int r1, int c1, int r2, int c2) {
    Tile temp = _contents[r1][c1];
    _contents[r1][c1] = _contents[r2][c2];
    _contents[r2][c2] = temp;
}

public boolean isGameOver() {
    for (int r=0; r<ROWS; r++) {
        for (int c=0; c<ROWS; c++) {
            Tile trc = _contents[r][c];
            return trc.isInFinalPosition(r, c);
        }
    }


    return true;
}
}

class Tile {

private int _row;     
private int _col;     
private String _face;  

public Tile(int row, int col, String face) {
    _row = row;
    _col = col;
    _face = face;
}
public void setFace(String newFace) {
    _face = newFace;
}
public String getFace() {
    return _face;
}
public boolean isInFinalPosition(int r, int c) {
    return r==_row && c==_col;
}
}

How would I make it so that the user can specify dimensions of the game board?

EDIT public class SlidePuzzle {

public static void main(String[] args) 
{

    JFrame window = new JFrame("Slide Puzzle");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    String length = JOptionPane.showInputDialog("Length");
    String width = JOptionPane.showInputDialog("Width");
    int l = Integer.parseInt(length);
    int w = Integer.parseInt(width);
    window.setContentPane(new SlidePuzzleGUI());
    window.pack();  
    window.show();  
    window.setResizable(false);

}

} public class SlidePuzzleGUI extends JPanel {

private GraphicsPanel    _puzzleGraphics;
private SlidePuzzleModel _puzzleModel = new SlidePuzzleModel();




public SlidePuzzleGUI(int l, int w) {

    JButton newGameButton = new JButton("New Game");
    JButton resetButton = new JButton("Reset");
    JButton solveButton = new JButton("I GIVE UP :(");

    resetButton.addActionListener(new ResetAction());
    newGameButton.addActionListener(new NewGameAction());


    JPanel controlPanel = new JPanel();
    controlPanel.setLayout(new FlowLayout());
    controlPanel.add(newGameButton);
    controlPanel.add(resetButton);
    controlPanel.add(solveButton);


    _puzzleGraphics = new GraphicsPanel(l,w);

    this.setLayout(new BorderLayout());
    this.add(controlPanel, BorderLayout.NORTH);
    this.add(_puzzleGraphics, BorderLayout.CENTER);
}

class GraphicsPanel extends JPanel implements MouseListener {
    private int ROWS;
    private int COLS;

    private static final int CELL_SIZE = 80; 
    private Font _biggerFont;



    public GraphicsPanel(int l, int w) {
        _biggerFont = new Font("SansSerif", Font.BOLD, CELL_SIZE/2);
        this.setPreferredSize(
               new Dimension(CELL_SIZE * COLS, CELL_SIZE*ROWS));
        this.setBackground(Color.black);
        this.addMouseListener(this); 
        ROWS = l;
        COLS = w;
    }



    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int r=0; r<ROWS; r++) {
            for (int c=0; c<COLS; c++) {
                int x = c * CELL_SIZE;
                int y = r * CELL_SIZE;
                String text = _puzzleModel.getFace(r, c);
                if (text != null) {
                    g.setColor(Color.gray);
                    g.fillRect(x+2, y+2, CELL_SIZE-4, CELL_SIZE-4);
                    g.setColor(Color.black);
                    g.setFont(_biggerFont);
                    g.drawString(text, x+20, y+(3*CELL_SIZE)/4);
                }
            }
        }
    }



    public void mousePressed(MouseEvent e) {

        int col = e.getX()/CELL_SIZE;
        int row = e.getY()/CELL_SIZE;

        if (!_puzzleModel.moveTile(row, col)) {

            Toolkit.getDefaultToolkit().beep();
        }

        this.repaint();
    }



    public void mouseClicked (MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered (MouseEvent e) {}
    public void mouseExited  (MouseEvent e) {}
}

public class NewGameAction implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        _puzzleModel.reset();
        _puzzleGraphics.repaint();
    }
}
public class ResetAction implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        _puzzleModel.tryAgain();
        _puzzleGraphics.repaint();

    }

}

public class solveAction implements ActionListener
{

    @Override
    public void actionPerformed(ActionEvent e)
        {
            _puzzleModel.solve();
            _puzzleGraphics.repaint();

        }

    }
}
2
  • You get what errors, where? Commented Oct 2, 2013 at 1:59
  • Well, right now you're inputting the length and width but not doing anything with them, and using constants for the rows and columns in GraphicsPanel. Probably add length and width parameters to both the SlidePuzzleGUI constructor and the GraphicsPanel constructor? Then the main program uses them when constructing SlidePuzzleGUI, and SlidePuzzleGUI turns around and uses them when constructing GraphicsPanel ... Or is there some other problem?
    – ajb
    Commented Oct 2, 2013 at 2:07

1 Answer 1

3

Your key classes have no setter methods or constructor parameters that allow you to pass the length and width to them. If you want to change this aspect of their states, then they have to have a mechanism to do this. Currently your GraphicsPanel is hard-coded to use the ROWS and COLS constants, and this will be very hard to change. Instead replace all those hard-codings to variables, and sure have them default to the ROWS and COLS constants in your default constructor, but also provide a non-default constructor that will allow the programmer to pass in a different row and col setting.


Edit
You've got to

  • Use the constructor parameters to set class fields so that the entire class can use these values, not just the constructor.
  • Call the proper constructor, the one that requires the parameters!

i.e.,

public MyConstructor(int x, int y) {
   this.x = x;
   this.y = y;
}
9
  • I tried putting them in the parameters of the constructors but that gave me errors, if you give me a minute I can retype what I tried earlier Commented Oct 2, 2013 at 2:04
  • @user2776808: add the changed code to the bottom of your current post, but leave your current code in place also. Commented Oct 2, 2013 at 2:05
  • @user2776808: see my edit. This is really nothing more than fundamental Java and has little to do with Swing or advanced concepts. Commented Oct 2, 2013 at 2:16
  • It's still not working, I'm getting a board which i think has the right dimensions, but the window isn't right Commented Oct 2, 2013 at 2:20
  • @user2776808: If you have errors, show them. What do you mean by "the window isn't right"? Commented Oct 2, 2013 at 2:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.