import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; import java.util.Random; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class EightPuzzle extends JFrame implements ActionListener { private static final String puzzleImage = "img/awesome"; JButton[] buttons; JButton shuffleButton; int blank; public EightPuzzle() { // Provided initialization--you do not need to modify super("8 Puzzle"); ImageIcon[] icons = new ImageIcon[8]; for (int i = 0; i < 8; i++) { String path = puzzleImage + (i/3 + 1) + "" + (i%3 + 1) + ".png"; icons[i] = new ImageIcon(new File(path).getAbsolutePath()); } buttons = new JButton[9]; getContentPane().setLayout(new BorderLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(600, 625); /* * TODO 1: Create a JPanel object that uses a grid layout that is 3x3. * Make the JPanel 600x600 and add it to the center of this * frame. */ /* * TODO 2: Create and add the first 8 JButtons. You should store the * JButton objects in the buttons array declared for you. The * ith JButton should use the ith ImageIcon as the image in the * icons array. You should add "this" as an action listener * to the each button. */ for (int i = 0; i < 8; i++) { } /* * TODO 3: Create the last JButton. This one is different, because it * starts with no icon. It should also be disabled, since it * is not a valid move. It should also add "this" as an * action listener. */ blank = 8; /* * TODO 4: Create a JButton labelled "Shuffle" and add it to the south * of the frame. Be sure to add the appropriate action * listener. */ } /* * TODO 5: Implement the necessary event handlers in the actionPerformed * Method. If one of the tile buttons is clicked, it should call * tryMove with the index of the button (the index in the buttons * array). If the shuffle button is clicked, it should simply call * the shuffle method, which takes no arguments. */ public void actionPerformed(ActionEvent e) { } /* Everything below is complete. Do not modify. */ private void tryMove(int i) { JButton b = buttons[i]; if (b.getIcon() != null) { // north if (i-3 >= 0 && buttons[i-3].getIcon() == null) { swap(i, i-3); } // east if (i/3 == (i+1)/3 && i+1 < 9 && buttons[i+1].getIcon() == null) { swap(i, i+1); } // south if (i+3 < 9 && buttons[i+3].getIcon() == null) { swap(i, i+3); } // west if (i/3 == (i-1)/3 && i-1 >= 0 && buttons[i-1].getIcon() == null) { swap(i, i-1); } } } // Swaps two tiles. Assumes either i or j are blank. private void swap(int i, int j) { Icon tmp = buttons[i].getIcon(); buttons[i].setIcon(buttons[j].getIcon()); buttons[j].setIcon(tmp); if (blank == i) { blank = j; buttons[j].setEnabled(false); buttons[i].setEnabled(true); } else { blank = i; buttons[j].setEnabled(true); buttons[i].setEnabled(false); } } private void shuffle() { ArrayList moves = new ArrayList(); Random r = new Random(); for (int j = 0; j < 20; j++) { if (blank-3 >= 0) { moves.add(blank-3); } // east if (blank/3 == (blank+1)/3 && blank+1 < 9) { moves.add(blank+1); } // south if (blank+3 < 9) { moves.add(blank+3); } // west if (blank/3 == (blank-1)/3 && blank-1 >= 0) { moves.add(blank-1); } swap(blank, moves.get(r.nextInt(moves.size()))); moves.clear(); } } public static void main(String[] args) { try { new EightPuzzle().setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }