package tt;
/* 퍼즐게임 소스 설명 우선 버튼을 3X3으로 세팅....버튼을 9개와 랜던 버튼과 순서가 맞는지 확인하는 버튼을 만든다...
* 또 Rectangle 클래스를 생성하여 좌표위치를 입력한다..버튼을 생성한 다음 Rectangle을 버튼에 넣어 버튼의 위치를 잡아준다.]
* 그리고 나서 클릭한 버튼 주위에 빈칸이 있는지 확인하고 빈칸이 있을 경우 그곳으로 버튼을 옮긴다...이때 사용하는 메소드가 checkIsEmpty()이다
* 버튼을 옮기다가 순서에 맞으면 check버튼을 눌러 성공여부를 확인한다...그리고 랜덤함수를 구현하여 게임을 다시 시작할 수 있게하였다 자세한 설명은 메소드별로 할 것이다..
*/
//소스를 돌리기 위해서 옆에 있는 절대위치에 a0와 그외 이미지가 필요하다. 이미지는 파일을 첨부하겠다.그리고 절대위치 수정과 JDK18버전에서 실행했기에 각기 맞는 버전에서 정렬하기 위해서는 subString()메소드와 charAt()메소드의 수정도 필요하다.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class MyButton3 extends JFrame implements ActionListener{
JButton btn[][] = new JButton[3][3];
JButton rand = new JButton("섞기");
JButton check = new JButton("체크");
JButton arr = new JButton("정렬");
Rectangle r_before,temp,r_after;
Rectangle[][] rect = new Rectangle[3][3];
JPanel panel = new JPanel();
ImageIcon[][] img = new ImageIcon[3][3];
JLabel label = new JLabel();
ArrayList<JButton> btn_values;
int x=0;
int y=0;
public MyButton3(){
//배치관리자는 절대위치를 사용...panel.setLayout(null);
setSize(350,450);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("JAVA_PUZZLE");
panel.setLayout(null);
//버튼 생성
img[0][0] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a0.png");
img[0][1] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a1.png");
img[0][2] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a2.png");
img[1][0] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a3.png");
img[1][1] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a4.png");
img[1][2] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a5.png");
img[2][0] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a6.png");
img[2][1] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a7.png");
img[2][2] = new ImageIcon("C:\\javapr\\test\\src\\tt\\a8.png");
btn[0][0] = new JButton(img[0][0]);
btn[0][1] = new JButton(img[0][1]);
btn[0][2] = new JButton(img[0][2]);
btn[1][0] = new JButton(img[1][0]);
btn[1][1] = new JButton(img[1][1]);
btn[1][2] = new JButton(img[1][2]);
btn[2][0]= new JButton(img[2][0]);
btn[2][1] =new JButton(img[2][1]);
btn[2][2] = new JButton(img[2][2]);
//좌표값 대입
rect[0][0] =new Rectangle(10,10,100,100);
rect[0][1] =new Rectangle(110,10,100,100);
rect[0][2] =new Rectangle(210,10,100,100);
rect[1][0] =new Rectangle(10,110,100,100);
rect[1][1] =new Rectangle(110,110,100,100);
rect[1][2] =new Rectangle(210,110,100,100);
rect[2][0] =new Rectangle(10,210,100,100);
rect[2][1] =new Rectangle(110,210,100,100);
rect[2][2] =new Rectangle(210,210,100,100);
//버튼에 리스너 등록
btn[0][0].addActionListener(this);
btn[0][1].addActionListener(this);
btn[0][2].addActionListener(this);
btn[1][0].addActionListener(this);
btn[1][1].addActionListener(this);
btn[1][2].addActionListener(this);
btn[2][0].addActionListener(this);
btn[2][1].addActionListener(this);
btn[2][2].addActionListener(this);
rand.addActionListener(this);
check.addActionListener(this);
arr.addActionListener(this);
//패널에 버튼 붙임
panel.add(btn[0][0]);
panel.add(btn[0][1]);
panel.add(btn[0][2]);
panel.add(btn[1][0]);
panel.add(btn[1][1]);
panel.add(btn[1][2]);
panel.add(btn[2][0]);
panel.add(btn[2][1]);
panel.add(btn[2][2]);
panel.add(rand);
panel.add(check);
panel.add(label);
panel.add(arr);
//버튼 위치 설정
btn[0][0].setBounds(rect[0][0]);
btn[0][1].setBounds(rect[0][1]);
btn[0][2].setBounds(rect[0][2]);
btn[1][0].setBounds(rect[1][0]);
btn[1][1].setBounds(rect[1][1]);
btn[1][2].setBounds(rect[1][2]);
btn[2][0].setBounds(rect[2][0]);
btn[2][1].setBounds(rect[2][1]);
btn[2][2].setBounds(rect[2][2]);
rand.setBounds(10, 350, 60, 40);
check.setBounds(80, 350, 80,40);
arr.setBounds(190, 350, 80,40);
//프레임에 패널을 붙이고 setVisible을 사용하여 보이게함
add(panel);
this.setVisible(true);
}
public static void main(String[] args)
{
new MyButton3();
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btn[0][0])
checkIsEmpty(btn[0][0]);
else if(e.getSource() == btn[0][1])
checkIsEmpty(btn[0][1]);
else if(e.getSource() == btn[0][2])
checkIsEmpty(btn[0][2]);
else if(e.getSource() == btn[1][0])
checkIsEmpty(btn[1][0]);
else if(e.getSource() == btn[1][1])
checkIsEmpty(btn[1][1]);
else if(e.getSource() == btn[1][2])
checkIsEmpty(btn[1][2]);
else if(e.getSource() == btn[2][0])
checkIsEmpty(btn[2][0]);
else if(e.getSource() == btn[2][1])
checkIsEmpty(btn[2][1]);
else if(e.getSource() == btn[2][2])
checkIsEmpty(btn[2][2]);
else if(e.getSource()==rand)
randMethod();
else if(e.getSource()==check)
check_success();
else if(e.getSource()==arr)
arr();
}
//checkIsEmpty메소드는 상하좌우를 검사한다...빈칸이 있을시 빈칸과 클릭한 버튼을 바꾸어 준다...
/* checkIsEmpty는 버튼이 클릭 되었을때 위,오른쪽,아래쪽 왼쪽에 빈칸이 있는지 검사하고 빈칸이 있다면 클릭된 버튼과 빈칸을 위치와 버튼 객체를 교한해 준다.
* if문의 뒷부분에서 객체를 교환한 이유는 객체를 먼저 교환하면 위치가 바꾸지 않기 때문이다..예를 들어 X, Y를 교환할때
* rect를 이용하여 위치를 변경시킨다...그러면 X,Y의 좌표가 바뀌어진다...그런데 객체를 먼저 바꾸면 객체가 교환되면서 좌표의 값이 바뀌지가 않는다.
*/
public void checkIsEmpty(JButton btnl)
{
JButton tmp;
/*된 버튼을 찾는다..랜덤으로 버튼을 섞어 놓으면 찾을 수 없는 것 같지만 e.getSource에서
*클릭된 좌표를 값을 가진 인스턴스를 매개변수로 넘겨주어 어느 위치에서 버튼이 클릭되었는지 for문을 통해서 알수 있다.
*/
for(int i = 0; i < 3;i++)
for(int j = 0; j < 3; j++)
if(btn[i][j].equals(btnl))
{x = i;y = j;}
if((x-1)>=0 && (((btn[x-1][y].toString().split(",")[11])).substring(12,40)).contains("C:\\javapr\\test\\src\\tt\\a8.png"))
{
System.out.println("1:"+" "+x+" "+y);
r_before = btn[x-1][y].getBounds();
r_after = btn[x][y].getBounds();
temp = r_before;
r_before = r_after;
r_after = temp;
btn[x-1][y].setBounds(r_before.x,r_before.y,r_before.width,r_before.height);
btn[x][y].setBounds(r_after.x,r_after.y,r_after.width,r_after.height);
tmp = btn[x-1][y];
btn[x-1][y] = btn[x][y];
btn[x][y] = tmp;
}
//배열의 오른쪽에 빈칸이 있는지 검사한다...
if((y+1) < 3 && (((btn[x][y+1].toString().split(",")[11])).substring(12,40)).contains("C:\\javapr\\test\\src\\tt\\a8.png"))
{
System.out.println("2:"+" "+x+" "+y);
r_before = btn[x][y+1].getBounds();
r_after = btn[x][y].getBounds();
temp = r_before;
r_before = r_after;
r_after = temp;
btn[x][y+1].setBounds(r_before.x,r_before.y,r_before.width,r_before.height);
btn[x][y].setBounds(r_after.x,r_after.y,r_after.width,r_after.height);
tmp = btn[x][y+1];
btn[x][y+1] = btn[x][y];
btn[x][y] = tmp;
}
//눌러진 버튼의 배열아래쪽을 검사한다....
if((x+1) < 3 && (((btn[x+1][y].toString().split(",")[11])).substring(12,40)).contains("C:\\javapr\\test\\src\\tt\\a8.png"))
{
System.out.println("3:"+" "+x+" "+y);
r_before = btn[x+1][y].getBounds();
r_after = btn[x][y].getBounds();
temp = r_before;
r_before = r_after;
r_after = temp;
btn[x+1][y].setBounds(r_before.x,r_before.y,r_before.width,r_before.height);
btn[x][y].setBounds(r_after.x,r_after.y,r_after.width,r_after.height);
tmp = btn[x+1][y];
btn[x+1][y] = btn[x][y];
btn[x][y] = tmp;
}
//클릭된 버튼의 왼쪽에 버튼이 있는지 검사한다...
if((y-1) >= 0 &&(((btn[x][y-1].toString().split(",")[11])).substring(12,40)).contains("C:\\javapr\\test\\src\\tt\\a8.png"))
{
System.out.println("4:"+" "+x+" "+y);
r_before = btn[x][y-1].getBounds();
r_after = btn[x][y].getBounds();
temp = r_before;
r_before = r_after;
r_after = temp;
btn[x][y-1].setBounds(r_before.x,r_before.y,r_before.width,r_before.height);
btn[x][y].setBounds(r_after.x,r_after.y,r_after.width,r_after.height);
tmp = btn[x][y-1];
btn[x][y-1] = btn[x][y];
btn[x][y] = tmp;
}
}
/*randMethod는 JButton을 섞는 역활을 한다...우선 ArrayList에 JButton을 넣는다 그 다음 Random을 이용히여
*ArrayList에서 JButton을 빼내준 다음 버튼 새로운 배열에 넣고 그 버튼을 Array에서 지운다..그렇게 해서 9가지를 섞는다
*/
private void randMethod() {
label.setText("");
// 배열의 값을 저장할 리스트
btn_values = new ArrayList<JButton>();
for(int i=0;i<3;i++) {
for(int j=0;j<3;j++) {
btn_values.add(btn[i][j]);
// 배열의 값들을 리스트에 저장
}
}
Random ra = new Random();
for(int i=0;i<3;i++) {
for(int j=0;j<3;j++) {
// 리스트에서 몇번째 값을 가져올지 랜덤하게 선택
int rv = ra.nextInt( btn_values.size() );
// 리스트에서 선택된 값을 배열에 저장
btn[i][j]= btn_values.get(rv);
// 리스트에서 방금 가져온 값을 삭제
btn_values.remove( rv );
}
}
//새로 섞인 버튼을 출력한다...
for(int i = 0; i < 3;i++)
for(int j = 0; j < 3;j++)
btn[i][j].setBounds(rect[i][j]);
}
/*버튼들이 순서대로 정렬되어 있는지 검사한다...우선 배열을 9까지 돌리고 btn[i][j].getActionCommand().equals(""+k)
* k가 0부터 증가하면서 버튼의 순서와 맞는지 검사한다...버튼이 배열순서와 맞는다면 아무일을 하지 않고 틀릴 경우 isTrue에 false를 넣어준다
* 한번이라도 false가 들어가면 버튼의 순서와 맞지 않으므로 label.setText("success")를 해주지 않는다..만약
* 한번도 false라고 isTrue에 들어가지 않으면 label.setText("success")를 해준다..
* 또 메소드 앞에 label.setText("")를 해주어 전에 setText()한 것을 지워준다..
*/
public void check_success()
{
label.setText("");
int k =0;
boolean isTrue= true;
for(int i = 0; i < 3;i++)
for(int j = 0; j < 3;j++)
{
if(k < 9 ){
if(btn[i][j].toString().contains("C:\\javapr\\test\\src\\tt\\a"+k+".png"))
{}
else
{isTrue=false;}
k++;
}
}
if(isTrue == true)
{
label.setText("SUCESS");
label.setBounds(20,280,100,100);
}else{
label.setText("FAILED");
label.setBounds(20,280,100,100);
}
}
/*arr은 button을 선택정렬을 한다.정렬하는 방법은 button객체의 이미지 위치에서 이미지 숫자를 뽑아 정렬하면서 버튼 객체를 선택정렬을 한다.
*/
public void arr()
{
JButton btn_tmp[]=new JButton[20];
JButton btn_tmp2=new JButton();
int m=0,n=0;
int p=0;
//버튼을 btn_tmp1차원 배열에 옮긴다.
for(int i = 0; i < 3;i++)
for(int j = 0; j < 3;j++)
btn_tmp[p++]=btn[i][j];
/*임시로 만든 1차원 배열에서 객체를 정보를 toString()메소드로 출력한다음 ImegeIcon객체에서 그림을 절대위치를 뽑아내고 그림마다 붙어있는 숫자를 가지고
*선택정렬을 한다.
*/
for( m = 0; m < 9;m++)
for( n =m+1; n < 9;n++)
{
if((((btn_tmp[m].toString().split(",")[11])).substring(12,40)).charAt(23)>(((btn_tmp[n].toString().split(",")[11])).substring(12,40)).charAt(23))
{
btn_tmp2=btn_tmp[m];
btn_tmp[m]=btn_tmp[n];
btn_tmp[n]=btn_tmp2;
}
}
//선택정렬이 끝난 1차원 배열을 2차둰 배열에 순서대로 넣는다.
p=0;
for(int i = 0; i < 3;i++)
for(int j = 0; j < 3;j++)
btn[i][j]=btn_tmp[p++];
for(int i = 0; i < 3;i++)
for(int j = 0; j < 3;j++)
btn[i][j].setBounds(rect[i][j]);
}
}