Python/Python Challenge

[Python Challenge 22] 조이콘은 비쌉니다.

Python Challenge 22의 Url은 다음과 같다

Python challenge 22 : http://www.pythonchallenge.com/pc/hex/copper.html


구성

화면에는 조이스틱 하나밖에 안 보인다. 특별한 점은 안보이니, 주석을 보자

주석의 힌트를 따라 white.gif로 이동해 보자

이게 필자가 화면을 낮춘게 아니라 진짜 저 검은색 화면이 다다 ㅋㅋㅋㅋ 이상한데.. 조이스틱과 연관이 있을지도?

 


해결 아이디어

일단 저 그림이 수상해 보여서 forensically에 돌려보았다.

https://29a.ch/photo-forensics/#forensic-magnifier

 

Forensically, free online photo forensics tools

Forensically is a set of free tools for digital image forensics. It includes clone detection, error level analysis, meta data extraction and more.

29a.ch

* steghide와 같은 역할을 해주는 인터넷 사이트이다. 직관적이라 자주 이용하고 있다.

사진을 보면 정가운데에 빨간 점이 있다... 응?

gif의 특징상 frame의 조합으로 이루어 지는 경우가 많은데, 이 빨간 박스들의 위치가 문제를 푸는데 도움이 많이 될 것 같은 기분이 들었다.

### 22_1.py

from PIL import Image

if __name__=="__main__" :
    cnt = 1
    with Image.open("white.gif") as img :
        for f in range(img.n_frames) :
            img.seek(f)
            print(img.getbbox())

처음에는 프레임별로 저장해 봤는데 한 120장정도가 나오더라, 저장해본 결과는 끔찍했다. 따라서 코드를 바꾸어 출력으로 한 게 22_1.py이고, 결과는 다음과 같다.

...

(102, 100, 103, 101)
(102, 100, 103, 101)
(102, 100, 103, 101)
(102, 100, 103, 101)
(102, 102, 103, 103)
(100, 102, 101, 103)
(100, 102, 101, 103)
(98, 102, 99, 103)
(98, 100, 99, 101)
(98, 100, 99, 101)
(98, 100, 99, 101)
(98, 100, 99, 101)
(98, 100, 99, 101)
(98, 100, 99, 101)
(98, 100, 99, 101)
(98, 98, 99, 99)
>>> 

* PIL의 getbbox()는 사진에서 빈공간을 제외하고 나오는 왼쪽 / 위 / 오른쪽 / 아래 끝 점을 픽셀로 표현해준다. 

 

위의 결과를 보고 유추해볼 수 있는내용은 다음과 같았다.

 

"100,100,100,100을 가운데로 움직이는 조이스틱인가?"

 

코드를 다음과 같이 짜보았고 예상은 정확하게 들어맞았다.

### 22_2.py

from PIL import Image, ImageDraw

if __name__=="__main__" :
    cnt = 1

    ans = Image.new("RGB",(300,200))
    draw = ImageDraw.Draw(ans)
    l,u,r,d = (0,0,0,0)
    x,y = (100,100)
    
    with Image.open("white.gif") as img :
        for f in range(img.n_frames) :
            img.seek(f)
            l,u,r,d = (x-100 for x in img.getbbox())
            x += l
            y += u
    
            draw.point([x,y])

    ans.save("ans.png")

결과는 다음과 같다.

어... 뭔가 의미가 있는데, 글자가 겹쳤다. 22_1.py 출력을 자세하게 보면, 결과가 l==0과 u==0으로 멈추는 구간이 있다. 그걸 이용해서 조이스틱이 멈추면 옆으로 이동하는 코드를 짜 보자

### 22_3.py

from PIL import Image, ImageDraw

if __name__=="__main__" :
    cnt = 1

    ans = Image.new("RGB",(300,200))
    draw = ImageDraw.Draw(ans)
    l,u,r,d = (0,0,0,0)
    x,y = (0,100)
    
    with Image.open("white.gif") as img :
        for f in range(img.n_frames) :
            img.seek(f)
            l,u,r,d = (x-100 for x in img.getbbox())

            if(u==0 and l==0) :
                x += 50
            x += l
            y += u
    
            draw.point([x,y])

    ans.save("ans.png")

결과는 다음과 같다.

찾았다. bonus

Answer url : http://www.pythonchallenge.com/pc/hex/bonus.html