8 puzzle game 

3 * 3 퍼즐에서 1~8 까지 숫자퍼즐이 위치하고 공백을 한칸 둔 상태에서 랜덤으로 섞습니다.

1 2 3
4 5 6
7 8 0(공백)

섞기 전

 

3 2 6
5 7 4
0(공백) 8 1

섞은 후

 

그 다음, 공백칸을 이용해 각 칸의 위치들을 바꿔가면서 섞기 전 모습으로 되돌리는 것입니다.

보통 이 문제에서 A* Search를 많이 사용하는데, 저는 알고리즘을 사용하지 않고 구현해 보았습니다.

 

import random
import time

current_state = [[1,2,3],[4,5,6],[7,8,0]]

direclist = [] # 방향값 저장하는 리스트

zero_row = 2
zero_col = 2

def RandomShuffle(arr,shakenum,zero_row,zero_col): #섞어주는 함수
    for i in range(shakenum):
        direction = random.randrange(1, 5)  # 위 1, 아래 2, 왼쪽 3, 오른쪽 4
        if(direction == 1):
            if(zero_row != 0):
                tmp = arr[zero_row-1][zero_col]
                arr[zero_row - 1][zero_col] = 0
                arr[zero_row][zero_col] = tmp
                zero_row -= 1
                direclist.append(1)
        elif (direction == 2):
            if (zero_row != 2):
                tmp = arr[zero_row+1][zero_col]
                arr[zero_row+1][zero_col] = 0
                arr[zero_row][zero_col] = tmp
                zero_row += 1
                direclist.append(2)
        elif (direction == 3):
            if(zero_col != 0):
                tmp = arr[zero_row][zero_col-1]
                arr[zero_row][zero_col-1] = 0
                arr[zero_row][zero_col] = tmp
                zero_col -= 1
                direclist.append(3)
        elif (direction == 4) :
            if(zero_col != 2):
                tmp = arr[zero_row][zero_col + 1]
                arr[zero_row][zero_col + 1] = 0
                arr[zero_row][zero_col] = tmp
                zero_col += 1
                direclist.append(4)
    return zero_row,zero_col


def onerevers(rearr,zero_row, zero_col): # 거꾸로 1칸 이동
    move = direclist.pop()
    if (move == 1):  # 아래
        if(zero_row != 2):
            tmp = rearr[zero_row + 1][zero_col]
            rearr[zero_row + 1][zero_col] = 0
            rearr[zero_row][zero_col] = tmp
            zero_row += 1
    elif (move == 2):  # 위
        if(zero_row != 0):
            tmp = rearr[zero_row - 1][zero_col]
            rearr[zero_row - 1][zero_col] = 0
            rearr[zero_row][zero_col] = tmp
            zero_row -= 1
    elif (move == 3):  # 오른쪽
        if(zero_col != 2):
            tmp = rearr[zero_row][zero_col + 1]
            rearr[zero_row][zero_col + 1] = 0
            rearr[zero_row][zero_col] = tmp
            zero_col += 1
    elif (move == 4):  # 왼쪽
        if(zero_col != 0):
            tmp = rearr[zero_row][zero_col - 1]
            rearr[zero_row][zero_col - 1] = 0
            rearr[zero_row][zero_col] = tmp
            zero_col -= 1
    return zero_row, zero_col


zero_row, zero_col = RandomShuffle(current_state,200,zero_row, zero_col) # 초기출력


print(current_state)# 초기출력


while True:
    stop = 1
    control = input("재시작(1), 1 스텝 이동(2), 끝까지 이동(3), 종료(0) : ")
    if(control == '1'):
        zero_row, zero_col = RandomShuffle(current_state, 200,zero_row,zero_col)
        print(current_state)
    elif(control == '2'):
        zero_row, zero_col = onerevers(current_state,zero_row, zero_col)
        print(current_state)
    elif(control == '3'):
        while(stop != 0):
            if not direclist:
                stop = 0
                print("성공\n")
                exit()
            zero_row, zero_col = onerevers(current_state,zero_row, zero_col)
            print(current_state)
            time.sleep(0.1)
    elif(control == '0'):
        exit()

 

쉽게 말해 섞은 방향을 기록해두었다가 반대로 움직이는 방식의 알고리즘입니다.

 

실행 화면

 

이동하는 중간 과정 출력 생략 후