// SlidePuzzle.java - Puzzle to slide pieces to correct position.
// Fred Swartz, 2003-May, 2004-May
// The SlidePuzzle program consists of three files:
// SlidePuzzle.java - this file with main to create window.
// SlidePuzzleGUI.java - implements the GUI interface.
// SlidePuzzleModel.java - the logical functioning.
import javax.swing.JFrame;
///////////////////////////////////////////// class SlidePuzzle
class SlidePuzzle {
//============================================= method main
public static void main(String[] args) {
JFrame window = new JFrame("Slide Puzzle");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setContentPane(new SlidePuzzleGUI());
window.pack(); // finalize layout
window.show(); // make window visible
window.setResizable(false);
}//end main
}//endclass SlidePuzzle
-------------------------------------------------
// SlidePuzzleGUI.java - GUI for SlidePuzzle
// Fred Swartz, 2003-May-10, 2004-May-3
//
// The SlidePuzzleGUI class creates a panel which
// contains two subpanels.
// 1. In the north is a subpanel for controls (just a button now).
// 2. In the center a graphics
// This needs a few improvements.
// Both the GUI and Model define the number or rows and columns.
// How would you set both from one place?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/////////////////////////////////////////////////// class SlidePuzzleGUI
// This class contains all the parts of the GUI interface
class SlidePuzzleGUI extends JPanel {
//=============================================== instance variables
private GraphicsPanel _puzzleGraphics;
private SlidePuzzleModel _puzzleModel = new SlidePuzzleModel();
//end instance variables
//====================================================== constructor
public SlidePuzzleGUI() {
//--- Create a button. Add a listener to it.
JButton newGameButton = new JButton("New Game");
newGameButton.addActionListener(new NewGameAction());
//--- Create control panel
JPanel controlPanel = new JPanel();
controlPanel.setLayout(new FlowLayout());
controlPanel.add(newGameButton);
//--- Create graphics panel
_puzzleGraphics = new GraphicsPanel();
//--- Set the layout and add the components
this.setLayout(new BorderLayout());
this.add(controlPanel, BorderLayout.NORTH);
this.add(_puzzleGraphics, BorderLayout.CENTER);
}//end constructor
//////////////////////////////////////////////// class GraphicsPanel
// This is defined inside the outer class so that
// it can use the outer class instance variables.
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; // Pixels
private Font _biggerFont;
//================================================== constructor
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); // Listen own mouse events.
}//end constructor
//=======================================x method paintComponent
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);
}
}
}
}//end paintComponent
//======================================== listener mousePressed
public void mousePressed(MouseEvent e) {
//--- map x,y coordinates into a row and col.
int col = e.getX()/CELL_SIZE;
int row = e.getY()/CELL_SIZE;
if (!_puzzleModel.moveTile(row, col)) {
// moveTile moves tile if legal, else returns false.
Toolkit.getDefaultToolkit().beep();
}
this.repaint(); // Show any updates to model.
}//end mousePressed
//========================================== ignore these events
public void mouseClicked (MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered (MouseEvent e) {}
public void mouseExited (MouseEvent e) {}
}//end class GraphicsPanel
////////////////////////////////////////// inner class NewGameAction
public class NewGameAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
_puzzleModel.reset();
_puzzleGraphics.repaint();
}
}//end inner class NewGameAction
}//end class SlidePuzzleGUI
--------------------------------------------------------
// SlidePuzzleModel.java - Slide pieces to correct position.
// Fred Swartz, 2003-May-10
/////////////////////////////////////////// class SlidePuzzleModel
class SlidePuzzleModel {
private static final int ROWS = 3;
private static final int COLS = 3;
private Tile[][] _contents; // All tiles.
private Tile _emptyTile; // The empty space.
//================================================= constructor
public SlidePuzzleModel() {
_contents = new Tile[ROWS][COLS];
reset(); // Initialize and shuffle tiles.
}//end constructor
//===================================================== getFace
// Return the string to display at given row, col.
String getFace(int row, int col) {
return _contents[row][col].getFace();
}//end getFace
//======================================================= reset
// Initialize and shuffle the tiles.
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));
}
}
//--- Set last tile face to null to mark empty space
_emptyTile = _contents[ROWS-1][COLS-1];
_emptyTile.setFace(null);
//-- Shuffle - Exchange each tile with random tile.
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));
}
}
}//end reset
//==================================================== moveTile
// Move a tile to empty position beside it, if possible.
// Return true if it was moved, false if not legal.
public boolean moveTile(int r, int c) {
//--- It's a legal move if the empty cell is next to it.
return checkEmpty(r, c, -1, 0) || checkEmpty(r, c, 1, 0)
|| checkEmpty(r, c, 0, -1) || checkEmpty(r, c, 0, 1);
}//end moveTile
//================================================== checkEmpty
// Check to see if there is an empty position beside tile.
// Return true and exchange if possible, else return false.
private boolean checkEmpty(int r, int c, int rdelta, int cdelta) {
int rNeighbor = r + rdelta;
int cNeighbor = c + cdelta;
//--- Check to see if this neighbor is on board and is empty.
if (isLegalRowCol(rNeighbor, cNeighbor)
&& _contents[rNeighbor][cNeighbor] == _emptyTile) {
exchangeTiles(r, c, rNeighbor, cNeighbor);
return true;
}
return false;
}//end checkEmpty
//=============================================== isLegalRowCol
// Check for legal row, col
public boolean isLegalRowCol(int r, int c) {
return r>=0 && r<ROWS && c>=0 && c<COLS;
}//end isLegalRowCol
//=============================================== exchangeTiles
// Exchange two tiles.
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;
}//end exchangeTiles
//=================================================== isGameOver
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);
}
}
//--- Falling thru loop means nothing out of place.
return true;
}//end isGameOver
}//end class SlidePuzzleModel
////////////////////////////////////////////////////////// class Tile
// Represents the individual "tiles" that slide in puzzle.
class Tile {
//============================================ instance variables
private int _row; // row of final position
private int _col; // col of final position
private String _face; // string to display
//end instance variables
//==================================================== constructor
public Tile(int row, int col, String face) {
_row = row;
_col = col;
_face = face;
}//end constructor
//======================================================== setFace
public void setFace(String newFace) {
_face = newFace;
}//end getFace
//======================================================== getFace
public String getFace() {
return _face;
}//end getFace
//=============================================== isInFinalPosition
public boolean isInFinalPosition(int r, int c) {
return r==_row && c==_col;
}//end isInFinalPosition
}//end class Tile
No comments:
Post a Comment