사과게임(레몬게임) 파이썬으로 고득점 받기

https://wwme.kr/lemon/play?mode=normal

 

레몬 게임 | 덥덥미

레몬 게임을 플레이 해보세요. 게임 기록이 덥덥미에 저장되고 리더보드에 표시됩니다.

wwme.kr

 

 

레몬게임은 10*17 행렬에 숫자가 1~9중 하나가 쓰여있는데 사각형으로 드래그할 수 있다

 

이 사각형 안의 숫자 합이 10이 되면 해당 영역의 숫자들이 지워진다

 

지워진 숫자 수만큼 점수를 얻는다.

 

더이상 드래그할 수 없으면 배열이 교체된다.

 

---------------------------------------------------------------------------------------------------------------------------------------------------

 

막상 직접 해보니까 30점도 안나오더라고

 

그래도 웹으로 만들어져서 그런지 selenium을 이용하면 자동으로 할 수 있을 것 같다는 느낌을 받았다

 

selenium 4.0.0 이상 버전부터는 크롬 웹 드라이버를 다운받지 않아도 자동으로 크롬 웹을 실행시킬 수 있다고 한다

 

웹 드라이버 있긴 해야하는듯? 버전을 신경쓰지는 않아도 되는것 같고

 

그래서 selenium 버전을 pip show selenium으로 확인하고 4.0.0이 아니라면

 

pip install selenium==4.0.0으로 다운부터 받고 시작

 

from selenium import webdriver

import time

# 웹 드라이버 실행 (Chrome 기준)
driver = webdriver.Chrome()
driver.get("https://wwme.kr/lemon/play?mode=normal")

 

 

etc-image-0

 

 

웹을 실행한 다음 배열의 모든 수를 찾아 채워넣는다

 

from selenium.webdriver.common.by import By

def detect():

    elements = driver.find_elements(By.CLASS_NAME, "cell")

    maps = [[0]*17 for _ in range(10)]

    i = 0
    j = 0

    for elem in elements:

        x = elem.text

        if x.isdigit():

            maps[i][j] = int(x)
        
        j += 1

        if j == 17:

            i += 1
            j = 0
    
    return maps

 

 

etc-image-1

 

 

 

 

각 영역의 xpath를 보면

 

/html/body/div/div[1]/main/div/main/div[2]/div[2]/div/div[1]/div[1]

 

이런식으로 되어있는데 더 자세히 보면 y행 x열의 xpath가

 

/html/body/div/div[1]/main/div/main/div[2]/div[2]/div/div[y]/div[x] 형태로 되어있음을 알 수 있다

 

이때 좌상단 (x,y) 우하단 (z,w)라고 하면 (x,y)부터 (z,w)까지 드래그하는 코드는

 

from selenium.webdriver.common.action_chains import ActionChains

xpath1 = f'/html/body/div[1]/div[1]/main/div/main/div[2]/div[2]/div/div[{y+1}]/div[{x+1}]'

start_element = driver.find_element(By.XPATH, xpath1)

xpath2 = f'/html/body/div[1]/div[1]/main/div/main/div[2]/div[2]/div/div[{w+1}]/div[{z+1}]'
end_element = driver.find_element(By.XPATH, xpath2)

action = ActionChains(driver)
action.click_and_hold(start_element).move_to_element(end_element).release().perform()

 

 

그러면 (0,0)에서 (16,9)까지 모든 시작점 (x,y)에 대하여, 왼쪽 상단, 오른쪽 상단, 왼쪽 하단, 오른쪽 하단으로 드래그해본다

 

이때 영역 내 원소 합이 10이 되기만 하면 그 영역을 지우는걸로 한다.

 

etc-image-2

 

 

 

어떻게 지우느냐에 따라 득점이 달라질 수 있는데 그냥 (0,0)부터 (16,9)까지 차례대로 탐색해서 가능한 영역 찾기만 하면 지우기로 하자

 

def cal(x,y,z,w):

    a,b = min(x,z),max(x,z)
    c,d = min(y,w),max(y,w)

    v = 0

    for i in range(a,b+1):

        for j in range(c,d+1):

            if i >= 0 and i <= 16 and j >= 0 and j <= 9:

                v += maps[j][i]
            
            else:

                return -1
    
    return v

def find():

    for y in range(10):

        for x in range(17):
            
            #시작좌표 (x,y)

            for j in range(10):

                for i in range(17):

                    dx = x + i
                    dy = y + j

                    v = cal(x,y,dx,dy)

                    if v > 10:

                        break

                    elif v == 10:

                        return x,y,dx,dy
                    
                    elif v == -1:
                        
                        break

            
            for j in range(10):

                for i in range(17):

                    dx = x - i
                    dy = y + j

                    v = cal(x,y,dx,dy)

                    if v > 10:

                        break

                    elif v == 10:

                        return x,y,dx,dy
                    
                    elif v == -1:
                        
                        break
            
            
            
            for j in range(10):

                for i in range(17):

                    dx = x + i
                    dy = y - j

                    v = cal(x,y,dx,dy)

                    if v > 10:

                        break

                    elif v == 10:

                        return x,y,dx,dy
                    
                    elif v == -1:
                        
                        break
            
            
            for j in range(10):

                for i in range(17):

                    dx = x - i
                    dy = y - j

                    v = cal(x,y,dx,dy)

                    if v > 10:

                        break

                    elif v == 10:

                        return x,y,dx,dy
                    
                    elif v == -1:
                        
                        break
    
    return -1,-1,-1,-1

 

 

못찾으면 -1,-1,-1,-1을 return한다

 

못찾는 경우는 인게임에서 알아서 배열이 리필될것이다

 

그러면 다시 배열의 수를 추적해서 채워넣은다음 다시 위 과정을 반복하면 된다

 

maps = detect()

for _ in range(10000):

    x,y,z,w = find()

    if x == -1 and y == -1 and z == -1 and w == -1:

        maps = detect()
        continue

    xpath1 = f'/html/body/div[1]/div[1]/main/div/main/div[2]/div[2]/div/div[{y+1}]/div[{x+1}]'

    start_element = driver.find_element(By.XPATH, xpath1)

    xpath2 = f'/html/body/div[1]/div[1]/main/div/main/div[2]/div[2]/div/div[{w+1}]/div[{z+1}]'
    end_element = driver.find_element(By.XPATH, xpath2)

    action = ActionChains(driver)
    action.click_and_hold(start_element).move_to_element(end_element).release().perform()

    for i in range(x,z+1):

        for j in range(y,w+1):

            maps[j][i] = 0

 

 

524점 나왔는데 아무튼 잘 되긴 하는듯

 

etc-image-3

728x90