게시판 즐겨찾기
편집
드래그 앤 드롭으로
즐겨찾기 아이콘 위치 수정이 가능합니다.
3*3 퍼즐 맞추기 알고리즘 질문이요 ..ㅜㅜ
게시물ID : programmer_1104짧은주소 복사하기
작성자 : BeOkay
추천 : 0
조회수 : 2349회
댓글수 : 7개
등록시간 : 2014/02/09 01:21:06
class PuzzleSolvingProject {  	private int[] moveX = {0,0,1,-1};  	private int[] moveY = {-1,1,0,0};  	private char[] moving = {'L','R','U','D','S'};  	                      // 왼쪽    오른쪽  아래  위     스탈트  	private final int WIDTH = 3;  	private final int HEIGHT = 3;  	int count=0;  	  	public void solvePuzzle(int[] arr){  		  		int[][] puzzleMap = new int[WIDTH][HEIGHT];  		int nowX=0,nowY=0;  		int idx=0;  		for(int j=0; j<3; j++){  			for(int y=0; y<3; y++){  				puzzleMap[j][y]=arr[idx++];  				  				if(puzzleMap[j][y]==0){  					nowX=j;  					nowY=y;  				}  			}  		}  		if(movePuzzle(puzzleMap,nowX,nowY,4)==false)  			System.out.println("Impossible");  		return;  	}  	//퍼즐이 다 맞춰졌는지 검사. 맞으면 true 틀리면 false  	private boolean isPerFect(int[][] map, int nowX, int nowY){  		int idx=0;  		for(int i=0; i<WIDTH; i++)  			for(int j=0; j<HEIGHT; j++){  				if(map[i][j] != idx)  					return false;  				idx++;  			}  		return true;  	}  	//다음 퍼즐을 움직일때 경계를 벗어나는지 검사. 벗어난다면 false, 벗어나지 않는다면 true  	private boolean isCanMove(int nextX,int nextY){  		if( nextX < 0 || nextY < 0)  			return false;  		if( nextY >= HEIGHT || nextX >= WIDTH )  			return false;  		return true;  	}  	//재귀호출 되는 함수. isPerFect가 true를 반환하면, 함수를 종료하며 true반환. 그리고 이전 움직임 출력.  	private boolean movePuzzle(int[][] puzzleMap,int nowX,int nowY,int priorMove){   		System.out.println("Now X"+nowX+"  "+"Now Y"+nowY+"  "+"priorMove"+"  "+moving[priorMove]);  		  		for(int i=0; i<3; i++){  			for(int j=0; j<3; j++){  				System.out.print(puzzleMap[i][j]);  			}  			System.out.println();  		}  		if(isPerFect(puzzleMap,nowX,nowY)==true){  			System.out.println(moving[priorMove]);  			return true;  		}  		int[][] newPuzzle = new int[WIDTH][HEIGHT];  		for(int i=0; i<WIDTH; i++)  			for(int j=0; j<HEIGHT; j++)  				newPuzzle[i][j]=puzzleMap[i][j];  		  		for(int i=0; i<moveX.length; i++){  			if(isCanMove(nowX+moveX[i],nowY+moveY[i])){  				changePuzzle(newPuzzle,nowX,nowY,nowX+moveX[i],nowY+moveY[i]);  				if(movePuzzle(newPuzzle,nowX+moveX[i],nowY+moveY[i],i)==true){  					System.out.println(moving[priorMove]);  					return true;  				}  			}  		}  		return false;  	}  	//실제 퍼즐을 바꾸는 역할. 리턴값 엄음.  	private void changePuzzle(int[][] puzzleMap,int nowX,int nowY,int nextX,int nextY){  		int temp=puzzleMap[nextX][nextY];  		puzzleMap[nextX][nextY]=puzzleMap[nowX][nowY];  		puzzleMap[nowX][nowY]=temp;  		return;  	}  }    public class PuzzleSolving {  	public static void main(String[] args){   		PuzzleSolvingProject ps = new PuzzleSolvingProject();  		int[] arr = {1,2,0,3,4,5,6,7,8,9};  		ps.solvePuzzle(arr);  	}  }

깊이 우선 탐색으로 코드가 진행되는데... 문제는 위의 코드는 컴파일 되지만, 어떤 경우는 탐색이 계속 중복되는 루프에 빠져서,
스택 오버플로우가 일어나네요... 어떻게 중복되는지 안되는지 확인해서 메모할 수 있을까요 ㅜㅜ? 
예를들면 왼쪽->오른쪽->왼쪽->오른쪽 대충 이런식으로 발생합니다. 여기서 계속 막히네요..
그리고 다른 문제점 있다면 지적해 주심 감사요..ㅋㅋ
전체 추천리스트 보기
새로운 댓글이 없습니다.
새로운 댓글 확인하기
글쓰기
◀뒤로가기
PC버전
맨위로▲
공지 운영 자료창고 청소년보호