ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1. 그리디하게 사과를 지워보자
    Project/Fruit Box 2022. 12. 6. 23:28

    코드를 이쁘게 정리하느라 시간이 좀 걸렸다

    라이브러리는 pyautogui 하나만 사용하였다

    import pyautogui as pg

    이전 글에서 자바 스크립트 분석을 시도했으나 쉽지 않았다

    아니 가능한지는 지금도 모르겠다

    그렇기에 이미지 인식으로 방향을 돌렸다

     

    이미지 인식에는 openCV를 사용해야 하나 고민하였지만

    문제의 크기를 축소시켜 문제 해결을 하려 했다

    바로 게임 창의 크기를 고정시킨다

    그러면 단순이 이미지의 위치를 찾는 것으로 창을 읽을 수 있다

    해당 코드는 아래와 같다

    def init_board():
        location_dict = {}
        im = pg.screenshot()
    
        for i in range(1, 10):
            locations = pg.locateAll(f"{i}.png", im)
            for item in locations:
                location_dict[item] = i
    
        #17*10개의 사과를 찾아야 함
        assert len(location_dict) == 170, "Plz Check Game Screen"
    
        #높이 정렬
        locations = sorted(location_dict.items(), key=lambda x: x[0].top)
        board = [] # [position, number]
        for i in range(10):
            #한 줄 추가, x 좌표로 정렬
            board.append(locations[i*17:i*17+17])
            board[-1] = sorted(board[-1])
    
        for (x, i) in enumerate(board):
            for (y, j) in enumerate(i):
                board[x][y] = [j[0], j[1]]
    
        return board

    폴더에 1.png ~ 9.png로 사과 이미지가 저장되어있다

    스크린샷을 찍어 im에 저장하고 pg.locateAll로 모든 사과의 위치를 저장한다

    만약 문제가 있어 사과를 찾지 못하면 오류를 assert 하도록 구현하였다

     

    그리고 위치를 높이로 정렬하고, x로 정렬하여 board에 저장하였다

    결과적으로 board에 [box_data, number] 형태로 저장이 되도록 구현하였다

     

    자 다른 함수들은 깃허브에서 찾아보도록하고 바로 탐색법으로 넘어가자

    우선 모델을 적용시키기 전, 드래그를 구현 할 수 있는지 알아야 했다

     

    그렇기에 먼저 무지성 그리디 삭제를 구현하였다

    간단하게 왼쪽 위부터 탐색하며, 삭제가 가능한 행동들을 저장한다

    그리고 그냥 단순히 가장 먼저 찾은 행동을 시행한다

    #play game board with greedy method
    def greedy_search(board):
        score = 0
        while(1):
            actions = find_action(board)
            if len(actions) == 0:
                break
            action = actions[0]
            st, ed = action[0], action[1]
            box_s, box_e = board[st[0]][st[1]], board[ed[0]][ed[1]]
            score += action[2]
    
            drag_apple(box_s, box_e)
            remove_apple(board, st, ed)
            print(f"\rSolved: {score}/170", end="              ")

    함수 이름보면 대충 역할을 알 수 있을 것이니 설명은 패스~

     

    아마도 잘 작동한다

    당연히 그냥 바로 처음 나온 걸 지우는 게 최적의 점수를 보장하지는 않을 것이다

    그래도 낮아도 70점에서 종종 120 점을 넘는 퍼포먼스도 나온다

    최고 점수 캡쳐를 까먹었다


    이걸 좀 더 개선하기 위해 게임 AI를 학습시키는 방법과

    트리를 pruning 하는 휴리스틱 서치 등이 떠올랐다

    아직 뭘 할지는 모르겠지만, 천천히 고민해보자

     

    https://github.com/P-Jun/apple_game

     

    GitHub - P-Jun/apple_game: https://www.pjun.io/category/Project/Fruit%20Box

    https://www.pjun.io/category/Project/Fruit%20Box. Contribute to P-Jun/apple_game development by creating an account on GitHub.

    github.com

    해당 코드는 위 깃헙에 업로드해두었다

    'Project > Fruit Box' 카테고리의 다른 글

    3. 강화 학습으로 사과를 지워보자  (2) 2023.03.27
    2. 전략적으로 사과를 지워보자  (0) 2023.03.27
    0. 재밌는 사과 게임  (0) 2022.11.30

    댓글

Designed by Tistory.