简体   繁体   中英

Java sliding puzzle, know when finished?

I am making a java sliding puzzle for class, and so far, I am able to get the picture to be cropped, and I have found a way to slide all the buttons via the action listener. At this point, however, I cannot fathom as to how to check to see if all of the buttons are in the correct position in order to congratulate the user upon completion. Furthermore, knowing how to do that will allow me to be able to randomize and shuffle the image as well - which I have yet to implement.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class JEightPuzzleFrame extends JFrame implements ActionListener{

    private int width;
    private int height;

    int position[][];
    private Image image1;
    private JPanel centerPanel;
    private JButton[][] listOfBtn = new JButton[3][3];

    public JEightPuzzleFrame(String Title, String Source){

         position = new int[][] {
                 {0, 1, 2}, 
                 {3, 4, 5}, 
                 {6, 7, 8}};    

         centerPanel = new JPanel();
         centerPanel.setLayout(new GridLayout(3, 3, 0, 0)); // 3x3 grid
         add(centerPanel, BorderLayout.CENTER);

         // Read the image from folder
        BufferedImage image=null;
        try{
            image = ImageIO.read(new File(Source));
        }catch(IOException e){
            System.err.println("Image not found");
            System.exit(1);
        }       
        // get the height and width of the image for the window size
         width = image.getWidth();
         height = image.getHeight();

         for ( int i = 0; i < 3; i++) {
             for ( int j = 0; j < 3; j++) {
                 if ( i == 2 && j == 1) {
                     listOfBtn[2][1] = new JButton();
                     centerPanel.add(listOfBtn[2][1]);
                 } else {
                     listOfBtn[i][j] = new JButton();
                     listOfBtn[i][j].addActionListener(this);
                     centerPanel.add(listOfBtn[i][j]);
                     Image source = (Image) image;
                      image1 = createImage(new FilteredImageSource(source.getSource(),
                             new CropImageFilter(j*width/3, i*height/3, 
                                 (width/3)+1, height/3)));
                     listOfBtn[i][j].setIcon(new ImageIcon(image1));
                     listOfBtn[i][j].setVisible(true);
                 }
             }
         }     
        validate();
        setSize(width, height);
        setTitle(Title);
        setResizable(false);
        setLocationRelativeTo(null); // center the image
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);   
    }
    public void shuffle(){

    }
    public static void main(String[] args) {

            new JEightPuzzleFrame("puzzle", "picture.png");
    }
    @Override
    public void actionPerformed(ActionEvent e){

     JButton button = (JButton) e.getSource();
        Dimension size = button.getSize();

        int labelX = listOfBtn[2][1].getX();
        int labelY = listOfBtn[2][1].getY();
        int buttonX = button.getX();
        int buttonY = button.getY();
        int buttonPosX = buttonX / size.width;
        int buttonPosY = buttonY / size.height;
        int buttonIndex = position[buttonPosY][buttonPosX];

        if (labelX == buttonX && (labelY - buttonY) == size.height ) {

             int labelIndex = buttonIndex + 3;

             centerPanel.remove(buttonIndex);
             centerPanel.add(listOfBtn[2][1], buttonIndex);
             centerPanel.add(button,labelIndex);
             centerPanel.validate();
        }

        if (labelX == buttonX && (labelY - buttonY) == -size.height ) {

             int labelIndex = buttonIndex - 3;
             centerPanel.remove(labelIndex);
             centerPanel.add(button,labelIndex);
             centerPanel.add(listOfBtn[2][1], buttonIndex);
             centerPanel.validate();
        }

        if (labelY == buttonY && (labelX - buttonX) == size.width ) {

             int labelIndex = buttonIndex + 1;

             centerPanel.remove(buttonIndex);
             centerPanel.add(listOfBtn[2][1], buttonIndex);
             centerPanel.add(button,labelIndex);
             centerPanel.validate();
        }

        if (labelY == buttonY && (labelX - buttonX) == -size.width ) {

             int labelIndex = buttonIndex - 1;

             centerPanel.remove(buttonIndex);
             centerPanel.add(listOfBtn[2][1], labelIndex);
             centerPanel.add(button,labelIndex);
             centerPanel.validate();
        }
        if(labelY == buttonY && labelX == buttonX) {
            System.out.println("Congrats");
        }
 }
     }

Instead of cropping the Image and pasting it on buttons in the constructor, have an array of images which would contain list of cropped images, in (a pre-defined) order. Also remember to associate a name/number to the Image (can be done by creating a different class having Image and its original position in the full image as member variables of that class).

Now, at the end of your action performed, iterate through all your buttons and get the name of the image attached to it. If all the images are set correctly (as per the original full image), a concatenation of all their names (in order) would always be the same (independent of the Image used), and hence can be used to determine the final 'winning' condition.

随机排序之前,按钮的编号会调用容器getComponents存储数组,以便在每次移动后进行比较

Have an array of cropped images and array of equal number of buttons.

BufferedImage image[] = new BufferedImage[noOfImages];
JButton buttons[] = new JButton[image.length];

Now using java.util.Random class, generate random index for images and set it to the button at that index.

// Randomizing algorithm. I don't expect you to copy the same code. Just for you to understand the logic.

Random rand = new Random(); 
int index;

/ We'll iterate through each button.
for(int i = 0; i < buttons.length; i++) {

        // Pick up a random image.
        do {

            index = rand.nextInt(images.length); // Generate a random number from 0 to images.length -1
            // We will set this index position from the image array to null after setting the icon to a button, so that same picture is not selected for some other button.
        } while(images[index] != null);


        button[i].setIcon(new javax.swing.ImageIcon(images[index])); // Set the image.
        images[index] = null; // coz you don't want the same image to be set to other buttons again.
}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;

public class JEightPuzzleFrame extends JFrame implements ActionListener{

    private int width;
    private int height;     
    private int position[][];
    private int count[] = {1,2,3,4,5,6,7,8,9};  // keep track of where the pieces are 
    private Image image1;
    private JPanel centerPanel;
    private JButton[][] listOfBtn = new JButton[3][3];
    private String Source;
    private String Title;
    private int ShuffleCount;

    public JEightPuzzleFrame(String Title, String Source){
        this.Source = Source;
        this.Title = Title;

        ShuffleCount = 0;
        if (ShuffleCount == 0){
            ShuffleCount++;
            set();

        }else{
            shuffle();
        }
    }
    private Image getIcon(int i, int j){
         // Read the image from folder
        BufferedImage image=null;
        try{
            image = ImageIO.read(new File(Source));
        }catch(IOException e){
            System.err.println("Image not found");
            System.exit(1);
        }       
        // get the height and width of the image for the window size
         width = image.getWidth();
         height = image.getHeight(); 
         Image source = (Image) image;
         image1 = createImage(new FilteredImageSource(source.getSource(),
                 new CropImageFilter(j*width/3, i*height/3, 
                     (width/3)+1, height/3)));
         return image1;
    }
    private void set(){
        position = new int[][] {
                {0, 1, 2}, 
                {3, 4, 5}, 
                {6, 7, 8}};

         centerPanel = new JPanel();
         centerPanel.setLayout(new GridLayout(3, 3, 0, 0)); // 3x3 grid
         add(centerPanel, BorderLayout.CENTER);

         // Read the image from folder
        BufferedImage image=null;
        try{
            image = ImageIO.read(new File(Source));
        }catch(IOException e){
            System.err.println("Image not found");
            System.exit(1);
        }       
        // get the height and width of the image for the window size
         width = image.getWidth();
         height = image.getHeight(); 
    /*  for ( int i = 0; i < 3; i++) {
            for ( int j = 0; j < 3; j++) {
                if ( i == 2 && j == 1) {
                    listOfBtn[2][1] = new JButton();
                    centerPanel.add(listOfBtn[2][1]);
                } else {
                 listOfBtn[i][j] = new JButton();
                 listOfBtn[i][j].addActionListener(this);
                 centerPanel.add(listOfBtn[i][j]);
                 Image source = (Image) image;
                  image1 = createImage(new FilteredImageSource(source.getSource(),
                            new CropImageFilter(j*width/3, i*height/3, 
                                (width/3)+1, height/3)));
                    listOfBtn[i][j].setIcon(new ImageIcon(image1));
                    listOfBtn[i][j].setVisible(true);
                }
            }
        } */
         // Set up for initial Game        
         //Button 1
         listOfBtn[0][0] = new JButton();
         centerPanel.add(listOfBtn[0][0]);
         count [0] = 9;
         // Button 2
         listOfBtn[0][1] = new JButton();
         listOfBtn[0][1].addActionListener(this);
         centerPanel.add(listOfBtn[0][1]);
         listOfBtn[0][1].setIcon(new ImageIcon(getIcon(0,0)));
         listOfBtn[0][1].setVisible(true);
         count[1] = 1;
         //Button 3
         listOfBtn[0][2] = new JButton();
         listOfBtn[0][2].addActionListener(this);
         centerPanel.add(listOfBtn[0][2]);
         listOfBtn[0][2].setIcon(new ImageIcon(getIcon(0,1)));
         listOfBtn[0][2].setVisible(true);
         count[2] = 2;
       //Button 4
         listOfBtn[1][0] = new JButton();
         listOfBtn[1][0].addActionListener(this);
         centerPanel.add(listOfBtn[1][0]);
         listOfBtn[1][0].setIcon(new ImageIcon(getIcon(1,1)));
         listOfBtn[1][0].setVisible(true);
         count[3] = 5;
       //Button 5
         listOfBtn[1][1] = new JButton();
         listOfBtn[1][1].addActionListener(this);
         centerPanel.add(listOfBtn[1][1]);
         listOfBtn[1][1].setIcon(new ImageIcon(getIcon(1,2)));
         listOfBtn[1][1].setVisible(true);
         count[4] = 6;
       //Button 6
         listOfBtn[1][2] = new JButton();
         listOfBtn[1][2].addActionListener(this);
         centerPanel.add(listOfBtn[1][2]);
         listOfBtn[1][2].setIcon(new ImageIcon(getIcon(0,2)));
         listOfBtn[1][2].setVisible(true);
         count[5] = 3;
       //Button 7
         listOfBtn[2][0] = new JButton();
         listOfBtn[2][0].addActionListener(this);
         centerPanel.add(listOfBtn[2][0]);
         listOfBtn[2][0].setIcon(new ImageIcon(getIcon(1,0)));
         listOfBtn[2][0].setVisible(true);
         count[6] = 4;
       //Button 8
         listOfBtn[2][1] = new JButton();
         listOfBtn[2][1].addActionListener(this);
         centerPanel.add(listOfBtn[2][1]);
         listOfBtn[2][1].setIcon(new ImageIcon(getIcon(2,0)));
         listOfBtn[2][1].setVisible(true);
         count[7] = 7;
       //Button 9
         listOfBtn[2][2] = new JButton();
         listOfBtn[2][2].addActionListener(this);
         centerPanel.add(listOfBtn[2][2]);
         listOfBtn[2][2].setIcon(new ImageIcon(getIcon(2,1)));
         listOfBtn[2][2].setVisible(true);
         count[8] = 8;

        validate();
        setSize(width, height);
       setTitle(Title);
       setResizable(false);
       setLocationRelativeTo(null); // center the image
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setVisible(true);
    }
    public void shuffle(){
        set();

    }

    public static void main(String[] args) {
            new JEightPuzzleFrame("Puzzle", "image.png");   
            System.out.println();
    }
    @Override
    public void actionPerformed(ActionEvent e){

     JButton button = (JButton) e.getSource();
        Dimension size = button.getSize();

        int emptyX = listOfBtn[0][0].getX();
        int emptyY = listOfBtn[0][0].getY();

        int buttonX = button.getX();
        int buttonY = button.getY();
        int buttonPosX = buttonX / size.width;
        int buttonPosY = buttonY / size.height;
        int buttonIndex = position[buttonPosY][buttonPosX];

        if (emptyX == buttonX && (emptyY - buttonY) == size.height ) {          

             int labelIndex = buttonIndex + 3;

             centerPanel.remove(buttonIndex);
             centerPanel.add(listOfBtn[0][0], buttonIndex);
             centerPanel.add(button,labelIndex);
             centerPanel.validate();

             int a = count[buttonIndex];
             count[buttonIndex] = count[labelIndex];
             count[labelIndex] = a;              
        }

        if (emptyX == buttonX && (emptyY - buttonY) == -size.height ) {

             int labelIndex = buttonIndex - 3;
             centerPanel.remove(labelIndex);
             centerPanel.add(button,labelIndex);
             centerPanel.add(listOfBtn[0][0], buttonIndex);

             centerPanel.validate();
             int a = count[buttonIndex];
             count[buttonIndex] = count[labelIndex];
             count[labelIndex] = a; 
        }

        if (emptyY == buttonY && (emptyX - buttonX) == size.width ) {

             int labelIndex = buttonIndex + 1;        
             centerPanel.remove(buttonIndex);
             centerPanel.add(listOfBtn[0][0], buttonIndex);
             centerPanel.add(button,labelIndex);                                 
             centerPanel.validate(); 
             int a = count[buttonIndex];
             count[buttonIndex] = count[labelIndex];
             count[labelIndex] = a; 
        }

        if (emptyY == buttonY && (emptyX - buttonX) == -size.width ) {

             int labelIndex = buttonIndex - 1;            
             centerPanel.remove(buttonIndex);
             centerPanel.add(listOfBtn[0][0], labelIndex);
             centerPanel.add(button,labelIndex);
             centerPanel.validate();

             int a = count[buttonIndex];
             count[buttonIndex] = count[labelIndex];
             count[labelIndex] = a; 
        } 
        if(count[0] == 1 &&
                count[1] == 2 &&
                count[2] == 3 &&
                count[3] == 4 &&
                count[4] == 5 &&
                count[5] == 6 &&
                count[6] == 7 &&
                count[7] == 8 &&
                count[8] == 9){

            JOptionPane.showMessageDialog(centerPanel,"Good job! Hit ok to scramble");
            shuffle();
         }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM