본문 바로가기

Programming/Algorithm

[Python3] 푸쉬푸쉬

한 때 애니콜시절 필자가 즐겨했던 피쳐폰게임 푸쉬푸쉬이다. 당시 한 스테이지를 클리어하기 위해 밤을 세워 했던 기억이 있는데, 지금 머리가 조금 커졌는지 경험이 있는지 쉽게 풀린다. 암튼 이것을 코딩으로 구현하고자 하는데 GUI가 이해하기 어려울까봐(필자가 못해서) 그냥 텍스트 형식으로 제작하였다. 

규칙은 다음과 같다.

P를 움직여 공을 밀어서 .에다가 둬서 모든 .이 있는 자리에 공을 두면 된다.

공은 한번에 하나씩만 움직일 수 있다.

간단해 보이지만 공 상하좌우 공이나 벽인경우나 .에 공이 들어갈 경우 모양이 바뀌면서 그 모양도 밀어서 다시 .으로 바뀌는 것까지 여러개를 생각해야했다. 각설하고 코드로 뛰어들어가 설명하겠다.

 

import os   #움직이고 그전 화면을 지우기위해 필요하다.


def left_dot():    """함수명은 left_dot으로 원래 남아있는 .의 갯수를 세기위해 만들었는데 맵에 모든 곳을 검사하는 부분이 있어서 재활용하고자 .과 O가 합쳐진곳을 @로 바꾸거나 .과 P가 합쳐진곳을 R로 바꾸는 것을 여기다가 넣었다.""" 

    left_dot = 0

    for j in range(len(mapp)):

        for k in range(len(mapp[j])):

            if(mapp[j][k] in ['O','@'] and tempmapp[j][k]=='.'):

                mapp[j][k]='@'

            elif( tempmapp[j][k]=='.'):

                left_dot+=1

            if(mapp[j][k]=='P' and tempmapp[j][k]=='.'):

                mapp[j][k]='R'

    return left_dot


def prt_map():   

    for I in mapp:

        print(' '.join(I))    #공백 없이 출력해봤는데 너무 밋밋해서 공백과함께 출력하도록 했다.

    print("")


def wherep():    #P나 R이 어딨는지 (x,y)형태로 반환한다.

    p_x=0

    p_y=0

    for I in range(len(mapp)):

        if ('P' in mapp[I]):

            p_y = I

            p_x = mapp[I].index('P')

            break

        if ('R' in mapp[I]):

            p_y = I

            p_x = mapp[I].index('R')

            break

    return p_x, p_y

#원래 공백과 마침표가 모두 같은크기라 보기 편했는데 블로그에 올리니까 이상해졌다...

mapp = [

        list(" #### "),

        list("##  # "),

        list("#PO ##"),

        list("##O ##"),

        list("## O #"),

        list("#.O  #"),

        list("#..O.#"),

        list("######")        

        ]

#tempmapp은 O와 P가 없는 맵으로 O나 P가 움직였을 때 그 자리를 복원하기위해 쓰인다.

tempmapp = [

        list(" #### "),

        list("##  # "),

        list("#   ##"),

        list("##  ##"),

        list("##   #"),

        list("#.   #"),

        list("#....#"),

        list("######")        

        ]


n = 0    #움직인 칸 수 벽에 부딪히거나 움직이지 못할때는 안올라간다.

x, y = wherep()

temp = [tempmapp[y][x]]


while (1):

    os.system('cls')    #화면지우기다. 모바일에선 cls대신 clear을 쓴다.

    print("move count:", n)

    print("Dot Left:",left_dot())

    if(left_dot()==0):

        print("Clear! You did it",n,"moves!")

        prt_map()

        break

    prt_map()

    usr_in = input("type w,a,s,d to move: ").lower()


    if (usr_in not in ['w', 'a', 's', 'd']):

        print("\nw,a,s,d!!!\n")

        continue    #w,a,s,d가 아닌걸 걸러서 다시 입력하게 돌아간다.


    x, y = wherep()    #움직여야하니 일단 어딨는지부터 받아온다.


    if (usr_in == 'w'):

        if (mapp[y - 1][x] == '#' or (mapp[y - 1][x] in ['@','O'] and mapp[y - 2][x] in ['O', '#','@'])):

            print("can't move!")

            continue    #벽이나 공뒤에 공, 벽으로 막힐경우 다시 입력하게한다.

        else:

            if (mapp[y - 1][x] in ['@','O']):

                mapp[y - 2][x] = 'O'

            mapp[y - 1][x] = 'P'

            mapp[y][x] = tempmapp[y][x]    #O위에 O를 O자리에 P를 P자리에 원래 맵을 넣는다. 


    if (usr_in == 'a'):

        if (mapp[y][x - 1] == '#' or (mapp[y][x - 1] in ['@','O'] and mapp[y][x - 2] in ['O','@', '#'])):

            print("can't move!")

            continue


        else:

            if (mapp[y][x-1] in ['@', 'O']):

                mapp[y][x-2] = 'O'

            mapp[y][x-1] = 'P'

            mapp[y][x] = tempmapp[y][x]


    if (usr_in == 's'):

        if (mapp[y + 1][x] == '#' or (mapp[y + 1][x] in ['@','O'] and mapp[y + 2][x] in ['O','@', '#'])):

            print("can't move!")

            continue


        else:

            if (mapp[y+1][x] in ['@','O']) :

                mapp[y+2][x] = 'O'

            mapp[y+1][x] = 'P'

            mapp[y][x] = tempmapp[y][x]


    if (usr_in == 'd'):

        if (mapp[y][x + 1] == '#' or (mapp[y][x + 1] in ['@','O'] and mapp[y][x + 2] in ['O','@', '#'])):

            print("can't move!")

            continue


        else:

            if (mapp[y][x+1] in ['@','O'] ):

                mapp[y][x+2] = 'O'

            mapp[y][x+1] = 'P'

            mapp[y][x] = tempmapp[y][x]

            

    n += 1    #움직인다음 드디어 칸수가증가한다.

참고로 파이썬IDLE에서 실행시키지말고 cmd를 열어 이 프로그램이 저장된곳으로 가서

python 이름.py로 열어야 화면이 지워진다.


'Programming > Algorithm' 카테고리의 다른 글

[Python3] BruteList  (0) 2017.01.04
[Python3] 대칭수찾기  (0) 2016.12.28
[Python3] 변수 스왑  (0) 2016.12.11
[Python3] 올바른 괄호 판단하기1  (0) 2016.12.06
[Python3] 디지털 숫자 찍기  (0) 2016.12.04