Part 1. 로그인에서 로그인 부분을 설명하였고, Part 2. 슬라이딩 퍼즐에 관련하여 설명하겠습니다.

Swing을 이용하여 슬라이딩 퍼즐 GUI를 만들었습니다.


Puzzle DTO

package Puzzle_pkg;


public class PuzzleData {
	private String ID,Time,Rank;
	public PuzzleData() {}
	public PuzzleData(String ID, String Time){
		this.ID = ID;
		this.Time = Time;
	}
	
	public PuzzleData(String ID, String Time, String Rank){
		this.ID = ID;
		this.Time = Time;
		this.Rank = Rank;
	}
	
	public PuzzleData(String ID){
		this.ID = ID;
	}
	
	
	public String GetID(){
		return ID;
	}
	public void SetID(String ID){
		this.ID = ID;
	}
	public String GetTime(){
		return Time;
	}
	public void SetTime(String Rank){
		this.Time = Rank;
	}
	public String GetRank(){
		return Rank;
	}
	public void SetRank(String Rank){
		this.Rank = Rank;
	}
	
}

 


Puzzle DAO

package Puzzle_pkg;

import java.util.*;
import java.sql.*;

public class PuzzleDB{
	Connection conn = null;
	ResultSet rs = null;
	Statement st = null;
	PreparedStatement ps = null;
	
	public PuzzleDB() { // 생성자로 데이터베이스 연결
		try {
			final String url = "jdbc:mariadb://localhost:3306/puzzledb";
			final String id = "root";
			final String pw = "1234";
			
			Class.forName("org.mariadb.jdbc.Driver");
			conn = DriverManager.getConnection(url, id, pw);
			
		}catch(ClassNotFoundException cnfe) {
			System.out.println("DB 드라이버 로딩 실패:"+ cnfe.toString());
		}catch(SQLException sqle){
			System.out.println("DB 접속실패"+ sqle.toString());
		}catch(Exception e){
			System.out.println("Unkown error");
			e.printStackTrace();
		}
	}
	
	public void DBClose() { // 커넥션 연결 종료
		try {
			if(rs != null) rs.close();
			if(st != null) st.close();
			if(ps != null) ps.close();
		} catch (Exception e) {
			System.out.println(e + " => DBClose fail");
		}
	}
//퍼즐 정보 저장
	public void InsertPuzzleDB(PuzzleData puzzledata) { // puzzle table -> puzzle data insert
		try {
			String sql = "insert into puzzle values(?, ?, ?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, puzzledata.GetID());
			ps.setString(2, puzzledata.GetTime());
			ps.setString(3, null);
			ps.executeUpdate();
		} catch(SQLException e) {
			e.printStackTrace();
		} finally {
			DBClose();
		}
	}
// 퍼즐 정보 목록	
	public Vector<PuzzleData> PuzzleDBlist()  // puzzle table -> puzzle data list
	{
		Vector<PuzzleData> Ar = new Vector<PuzzleData>();
		 
		 try{
			 st = conn.createStatement();
			 
			 String sql = "Select DENSE_RANK() OVER (ORDER BY Time ASC ) as RANK, ID, Time from puzzle";
			 rs = st.executeQuery(sql);
			 while (rs.next()) {
				 Ar.add(new PuzzleData(rs.getString(1), rs.getString(2), rs.getString(3)));
			 }
		 }catch (SQLException e) {
				e.printStackTrace();
			} finally {
				DBClose();
			}
		 return Ar;
		 
	}

Vector 사용하여 데이터형을 PuzzleData(DTO)로 정하였고, DB에 있는 퍼즐 정보를 불러와 저장하는 메소드입니다.

// 퍼즐 정보 업데이트
	public void UpdatePuzzleDB(PuzzleData puzzledata)  // puzzle table -> puzzle data update
	{
		try {
			String Updata = "update puzzle set Rank = ?, where Time = ?;";
			ps = conn.prepareStatement(Updata);
			ps.setString(1, puzzledata.GetRank());
			ps.setString(2, puzzledata.GetTime());
			ps.executeUpdate();
			}catch(SQLException e){	
				e.printStackTrace();
			} finally {
				DBClose();
			}
	}

퍼즐 정보를 수정하는 메소드입니다.

	
	// 퍼즐 정보 삭제
	public void Delete(String ID)  // puzzle table -> puzzle data delete
	{
		String Delete = "delete from puzzle where ID = ?;";
		try {
			ps = conn.prepareStatement(Delete);
			ps.setString(1, ID);
			ps.executeUpdate();
		}catch (SQLException e) {
			e.printStackTrace();
		} finally {
				DBClose();
		}	
	}
}

퍼즐 정보를 삭제하는 메소드입니다.


Puzzle Swing

package Puzzle_pkg;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import Login_pkg.LoginData;
import Login_pkg.LoginDB;


public class Puzzle_Swing extends JFrame {
	PuzzleDB Pdb = new PuzzleDB();
	LoginData Ldata = new LoginData();
	LoginDB Ldb = new LoginDB();
	private JButton changebtn; // 빈칸과 바꿀 칸 변경
	private JButton[][] numbtn = new JButton[4][4]; // 15 까지의 버튼
	private int[][] numcount = new int[4][4]; // 15까지의 숫자
	private int row = 0, col = 0;
	private static String timerBuffer;  //경과 시간 문자열이 저장될 버퍼 정의
	private static int oldTime;  //타이머 시작 시각을 기억하고 있는 변수

	public Puzzle_Swing() {
		stopwatch(1); // 시간 측정 시작
		// 배치
		setTitle("슬라이딩 퍼즐");
		setSize(350, 350);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Container c = getContentPane();
		c.setLayout(new GridLayout(4, 4));

		int k = 1;
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				numbtn[i][j] = new JButton(String.valueOf(k));
				numbtn[i][j].setFont(new Font("굴림체", Font.BOLD, 30));
				c.add(numbtn[i][j]);
				numbtn[i][j].addKeyListener(new MyKeyListener());
				k++;
			}
		}		
		

		getNum();
		display();
		
		setVisible(true);
	}

	// 0~16 난수발생
	public void getNum() {
		int[] num = new int[16];
		int n = 0;
		boolean Check = false;
		for (int i = 0; i < 16; i++) {
			Check = true;
			while (Check) {
				n = (int) (Math.random() * 16);
				Check = false;
				for (int j = 0; j < i; j++) {
					if (n == num[j]) // 같은 수 저장 방지
					{
						Check = true;
						break;
					}
				}
			}
			num[i] = n;
			numcount[i / 4][i % 4] = n;
			if (n == 15) { // 랜덤 칸 생성
				row = i / 4;
				col = i % 4;
			}

		}
	}

	// 디스플레이
	public void display() {

		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (i == row && j == col) {
					numbtn[i][j].setText(String.valueOf(""));

					numbtn[i][j].setEnabled(false);
				} else {
					System.out.println("numcount["+i+"]"+"["+j+"] "+numcount[i][j]+" ");
					numbtn[i][j].setText(String.valueOf(numcount[i][j] + 1));
					numbtn[i][j].setEnabled(true);
				}
			}
		}
	}

	// 종료 여부 확인 numbtn 과 k 가 같으면 종료
	public boolean isEnd() {
		
		int k = 1;
		try {
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				if (Integer.parseInt(numbtn[i][j].getText()) != k)
					return false;
				System.out.println("k :"+k);
				k++;
			}
		}
		}catch(NumberFormatException e) { 
			
		}
		
		return true;

	}
	
	private class MyKeyListener extends KeyAdapter {
		
		public void keyPressed(KeyEvent e) {
			
			boolean isEnd = false;
			int keyCode = e.getKeyCode();
			
			switch (keyCode) {
			case KeyEvent.VK_UP: // 방향키 ↑ 클릭 시 동작
				if (row == 0) { // 바깥 나감 방지
					break;
				} else {
					changebtn = numbtn[row - 1][col]; // 변경할 위 버튼
					numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 숫자 변경
					numbtn[row][col].setEnabled(true);

					row = row - 1; // 위에를 다시 가리킴

					changebtn = numbtn[row][col]; // 빈칸 버튼 지정
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);
					
					isEnd(); // 게임 종료 확인
					if (isEnd) { // isEnd를 true로 변경하면 키보드 입력 시 테스트가 바로 가능 함.
						
						String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
						int s = Ldb.LoginOX(new LoginData(getID));
						if(s== -1) {
							JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							while(true) {
								getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
								s = Ldb.LoginOX(new LoginData(getID));
								if(s == 1) {
									break;
								}
								else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							}
							JOptionPane.showMessageDialog(null, "등록 완료		ID: "+getID+", 걸린 시간: "+timerBuffer);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}
						else {
							JOptionPane.showMessageDialog(null, "등록 완료		ID: "+getID+", 걸린 시간: "+timerBuffer);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}

					}
					break;
				}

			case KeyEvent.VK_DOWN:  // 방향키 ↓ 클릭 시 동작
				if (row == 3) {  // 바깥 나감 방지
					break;
				} else {
					changebtn = numbtn[row + 1][col];  // 변경할 아래 버튼
					numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 숫자 변경
					System.out.println("row : " + row + " col : " + col);
					numbtn[row][col].setEnabled(true);

					row = row + 1; // 아래를 다시 가리킴

					changebtn = numbtn[row][col]; // 빈칸 버튼 지정
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);

					isEnd(); // 게임 종료 확인
					if (isEnd) {
						
						String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
						int s = Ldb.LoginOX(new LoginData(getID));
						if(s== -1) {
							JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							while(true) {
								getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
								s = Ldb.LoginOX(new LoginData(getID));
								if(s == 1) {
									break;
								}
								else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							}
							JOptionPane.showMessageDialog(null, "등록 완료		ID: "+getID+", 걸린 시간: "+timerBuffer);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}
						else {
							JOptionPane.showMessageDialog(null, "Your message: "+getID);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}

					}

					break;
				}
				
			case KeyEvent.VK_RIGHT:  // 방향키 → 클릭 시 동작
				if (col == 3) {  // 바깥 나감 방지
					break;
				} else {
					changebtn = numbtn[row][col + 1]; // 변경할 오른쪽 버튼
					numbtn[row][col].setText(String.valueOf(changebtn.getText()));  // 변경할 버튼 숫자 변경
					System.out.println("row : " + row + " col : " + col);
					numbtn[row][col].setEnabled(true);

					col = col + 1; // 오른쪽을 다시 가리킴

					changebtn = numbtn[row][col]; // 빈칸 버튼 지정
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);

					isEnd(); // 게임 종료 확인
					if (isEnd) {
						
						String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
						int s = Ldb.LoginOX(new LoginData(getID));
						if(s== -1) {
							JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							while(true) {
								getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
								s = Ldb.LoginOX(new LoginData(getID));
								if(s == 1) {
									break;
								}
								else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							}
							JOptionPane.showMessageDialog(null, "등록 완료		ID: "+getID+", 걸린 시간: "+timerBuffer);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}
						else {
							JOptionPane.showMessageDialog(null, "Your message: "+getID);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}

					}
				}
				break;
				
			case KeyEvent.VK_LEFT:  // 방향키 ← 클릭 시 동작
				if (col == 0) {  // 바깥 나감 방지
					break;
				} else {
					changebtn = numbtn[row][col - 1]; // 변경할 왼쪽 버튼
					numbtn[row][col].setText(String.valueOf(changebtn.getText())); // 변경할 버튼 숫자 변경
					System.out.println("row : " + row + " col : " + col);
					numbtn[row][col].setEnabled(true);

					col = col - 1; // 왼쪽을 다시 가리킴

					changebtn = numbtn[row][col]; // 빈칸 버튼 지정
					numbtn[row][col].setText("");
					numbtn[row][col].setEnabled(false);

					isEnd(); // 게임 종료 확인
					if (isEnd) {
						
						String getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
						int s = Ldb.LoginOX(new LoginData(getID));
						if(s== -1) {
							JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							while(true) {
								getID = JOptionPane.showInputDialog("아이디를 입력 해주세요.");
								s = Ldb.LoginOX(new LoginData(getID));
								if(s == 1) {
									break;
								}
								else JOptionPane.showMessageDialog(null, "아이디가 동일하지 않습니다.");
							}
							JOptionPane.showMessageDialog(null, "등록 완료		ID: "+getID+", 걸린 시간: "+timerBuffer);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}
						else {
							JOptionPane.showMessageDialog(null, "Your message: "+getID);
							Pdb.InsertPuzzleDB(new PuzzleData(getID, timerBuffer));
							System.exit(0);	
						}

					}
					
					break;
				}
			}
			stopwatch(0); // 시간 측정 종료
		}
		
	}
	
	 public static void stopwatch(int onOff) {
		    if (onOff == 1)  //타이머 on
		      oldTime = (int) System.currentTimeMillis() / 1000;

		    if (onOff == 0) // 타이머 off, 시분초 timerBuffer 에 저장
		      secToHHMMSS(  ((int) System.currentTimeMillis() / 1000) - oldTime  );
		  }

		  // 정수로 된 시간을 초단위(sec)로 입력 받고, 문자열로 시분초를 저장
		  public static void secToHHMMSS(int secs) {
		    int hour, min, sec;

		    sec  = secs % 60;
		    min  = secs / 60 % 60;
		    hour = secs / 3600;

		    timerBuffer = String.format("%02d%02d%02d", hour, min, sec);
		  }
		  	  
}

실행화면

슬라이딩 퍼즐 화면

 

다음으로 랭킹에 대한 설명은 Part 3. 랭킹에서 하도록 하겠습니다.


Part 1. 로그인 바로가기

Part 3. 랭킹 바로가기

 

전체소스코드 바로가기

+ Recent posts