import java.awt.*; import java.awt.event.*; import java.awt.image.CropImageFilter; import java.awt.image.FilteredImageSource; import java.net.MalformedURLException; import java.net.URL; import java.util.*; import javax.swing.*; //Picture Puzzle 1.0 //Copyright 2003 Bobby Williams //www.JoyAndBobby.com //spike2131@hotmail.com //This code may be freely used and modified for non-commercial purposes. public class Puzzle extends JApplet { public void init() { String imageName = this.getParameter("Image"); String squareSize = this.getParameter("SquareSize"); if (squareSize == null) squareSize = "60"; PuzzlePanel puzPanel = PuzzlePanel.getPuzzlePanel( imageName,Integer.parseInt(squareSize)); this.setContentPane(puzPanel); this.setVisible(true); puzPanel.scramble(500); } } class PuzzlePanel extends JPanel implements LayoutManager, ActionListener { private int m_Cols; private int m_Rows; private int m_Size; private PuzzlePiece[][] m_Pieces; private Point m_EmptySpot; private Image m_Image; public PuzzlePanel(int cols, int rows, int squareSize, Image image) { m_Cols = cols; m_Rows = rows; m_Size = squareSize; m_Image = image; this.setLayout(this); m_Pieces = new PuzzlePiece[m_Cols][m_Rows]; for (int row = 0; row < m_Rows; row++) { for (int col = 0; col < m_Cols; col++) { Point spot = new Point(col, row); int value = row * m_Cols + col + 1; if (value == m_Rows * m_Cols) { m_EmptySpot = spot; break; } PuzzlePiece piece = null; if (m_Image == null) piece = new PuzzlePiece(Integer.toString(value), spot); else { Image subImage = createImage(new FilteredImageSource(m_Image.getSource(), new CropImageFilter(col*m_Size, row*m_Size, m_Size, m_Size))); piece = new PuzzlePiece(new ImageIcon(subImage), spot); } m_Pieces[col][row] = piece; this.add(piece); piece.addActionListener(this); } } this.setBackground(Color.blue); this.validate(); } public void addLayoutComponent(String name, Component comp) { //no-op } public void removeLayoutComponent(Component comp) { //no-op } public Dimension preferredLayoutSize(Container parent) { return new Dimension(m_Cols * m_Size, m_Rows * m_Size); } public Dimension minimumLayoutSize(Container parent) { return new Dimension(m_Cols * m_Size, m_Rows * m_Size); } public void layoutContainer(Container parent) { for (int row = 0; row < m_Rows; row++) { for (int col = 0; col < m_Cols; col++) { if (col == m_EmptySpot.x && row == m_EmptySpot.y) continue; int x = col * m_Size; int y = row * m_Size; Rectangle bounds = new Rectangle(x, y, m_Size, m_Size); m_Pieces[col][row].setBounds(bounds); } } } public void actionPerformed(ActionEvent e) { PuzzlePiece piece = (PuzzlePiece) e.getSource(); movePiece(piece); } public boolean movePiece(PuzzlePiece piece) { if (piece == null) return false; boolean horzAlign = piece.getSpot().y - m_EmptySpot.y == 0; boolean vertAlign = piece.getSpot().x - m_EmptySpot.x == 0; if (! horzAlign && ! vertAlign) return false; if (horzAlign && Math.abs(piece.getSpot().x - m_EmptySpot.x) != 1) { if (piece.getSpot().x > m_EmptySpot.x) movePiece(m_Pieces[piece.getSpot().x - 1][piece.getSpot().y]); else movePiece(m_Pieces[piece.getSpot().x + 1][piece.getSpot().y]); } if (vertAlign && Math.abs(piece.getSpot().y - m_EmptySpot.y) != 1) { if (piece.getSpot().y > m_EmptySpot.y) movePiece(m_Pieces[piece.getSpot().x][piece.getSpot().y - 1]); else movePiece(m_Pieces[piece.getSpot().x][piece.getSpot().y + 1]); } m_Pieces[m_EmptySpot.x][m_EmptySpot.y] = piece; Point swap = piece.getSpot(); piece.setSpot(m_EmptySpot); m_EmptySpot = swap; m_Pieces[m_EmptySpot.x][m_EmptySpot.y] = null; this.revalidate(); return true; } public void scramble(int moves) { Random random = new Random(System.currentTimeMillis()); for (int i = 0; i < moves; i++) { int row; int col; do { col = random.nextInt(m_Cols); row = random.nextInt(m_Rows); } while (!movePiece(m_Pieces[col][row])); } this.validate(); } public static PuzzlePanel getPuzzlePanel(String imageName, int squareSize) { Image image = null; int cols = 4; //default int rows = 4; if (imageName != null) { System.out.println("Loading image: " + imageName); if (imageName.startsWith("http://")) { try { image = new ImageIcon(new URL(imageName)).getImage(); } catch (MalformedURLException e) { e.printStackTrace(); } } else image = new ImageIcon(imageName).getImage(); if (image.getWidth(null) < 0) { System.out.println("Image '" + imageName + "' did not load."); image = null; } else { System.out.println("Image loaded."); cols = image.getWidth(null) / squareSize; rows = image.getHeight(null) / squareSize; } } return new PuzzlePanel(cols,rows,squareSize,image); } public static void main(String[] args) { PuzzlePanel puzPanel = getPuzzlePanel(args[0], Integer.parseInt(args[1])); JFrame frame = new JFrame("Puzzle"); frame.setContentPane(puzPanel); Dimension screen = frame.getToolkit().getScreenSize(); frame.setLocation((screen.width - frame.getWidth())/2, (screen.height - frame.getHeight())/2); frame.setResizable(false); frame.pack(); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); puzPanel.scramble(500); } } class PuzzlePiece extends JButton { static Color BGCOLOR = Color.white; static Color FGCOLOR = Color.black; private Point m_Spot; public PuzzlePiece(Object value, Point spot) { if (value instanceof String) this.setText((String)value); else if (value instanceof Icon) this.setIcon((Icon) value); this.setBackground(BGCOLOR); this.setForeground(FGCOLOR); this.setFocusPainted(false); this.setFont(new Font("Dialog",Font.BOLD, 22)); this.setBorder(BorderFactory.createLineBorder(FGCOLOR,1)); setSpot(spot); } public void setSpot(Point spot) { m_Spot = spot; } public Point getSpot() { return m_Spot; } }