【Python】《浅塘》自动求解与过关

环境:PC端,在蓝叠模拟器上运行

import keyboard, pyautogui, sys, time
from PIL import ImageDraw
X, Y, gridSize, puzzle = 78, 307, 84, ''  #(x,Y)为左上格中心坐标,gridsize为格子大小
answer, checkers, states, test = "", "", set(), True
def dragTo(s, goal):
    global X, Y
    pyautogui.mouseDown()
    pyautogui.moveTo(X+(s%6+goal)*gridSize, Y+(s//6)*gridSize, duration=0.2)
    pyautogui.moveTo(X+(s%6+goal)*gridSize, Y+(s//6)*gridSize, duration=0.2)
    pyautogui.mouseUp()
def move(s):
    global puzzle
    p = puzzle
    for i in range (0, len(s), 2):
        checker, d = s[i: i + 2]
        first, last = p. find(checker), p.rfind(checker)
        if d == '↑': p = p[:first-6] + checker + p[first-5:last] + "_" + p[last+1:]
        if d == '↓': p = p[:first] + "_" + p[first+1:last+6] + checker + p[last+7:]
        if d == '←': p = p[:first-1] + checker + p[first:last] + "_" + p[last + 1:]
        if d == '→': p = p[:first] + "_" + p[first+1:last+1] + checker + p[last+2:]
    return p
def moves(s):
    n = 0
    for i in range(0, len(s), 2):
        n += (i == 0 or s[i-2:i] != s[i:i+2])
    return n
while True:
    keyboard.on_press_key("alt", lambda x: sys.exit())
    screen = pyautogui.screenshot()
    if test:
        screenTest = pyautogui.screenshot()
        draw = ImageDraw.Draw(screenTest)
    pic, row, col, puzzle = '', ord('a'), ord('A'), ''
    for i in range(121):
        xx, yy = X + (i%11) * gridSize / 2, Y + (i // 11) * gridSize / 2
        kx = gridSize/2-2 if (i % 11) % 2 == 0 else 2
        ky = gridSize/2-2 if (i //11) % 2 == 0 else 2
        rect_area = screen.crop((xx-kx, yy-ky, xx+kx, yy+ky)).resize((1, 1))
        draw.rectangle([(xx-kx, yy-ky), (xx+kx, yy+ky)], fill=None, outline="red")
        color = rect_area.getpixel((0, 0))
        if color[0] < 150: pic += "蓝" if color[1] < 160 else "口"
        else: pic += "红" if color[1] < 150 else "黄"
    if test:
        screenTest.save(r"D:/浅塘.png")
        test = False
    for i in range(11): print(pic[i*11:(i+1)*11])
    for i in range(36):
        x, y = i//6, i%6  # x是行数,y是列数
        xy = x*2*11 + y*2
        color = pic[xy]
        if color == "红": puzzle += 'x'
        elif color == "口": puzzle += '_'
        elif (x==0 or pic[xy - 11]=="口") and (x == 5 or pic[xy +11] =="口"):  # 行块
            puzzle += chr(row)
            row += (y==5 or pic[xy + 1]=="口")
        else:  # 列块
            if x > 0 and pic[xy - 11] != "口": puzzle += puzzle[(x-1)*6+y]
            else:
                puzzle += chr(col)
                col += 1
    checkers = set(''.join(i for i in puzzle.split()))
    answer, states, steps = '', set(), ['']
    while not answer:
        steps0 = []
        for step in steps:
            p = move(step)
            if p not in states: states.add(p)
            else: continue
            if p.rfind('x') % 6 == 5: answer = step; break
            for checker in checkers:
                first, last = p.find(checker), p.rfind(checker)
                if checker < 'a':
                    i = 1
                    while first - i*6 >= 0 and p[first-i*6] == '_':
                        steps0 += [step + (checker+'↑')*i]
                        i+=1
                    i = 1
                    while last + i * 6 < 36 and p[last+i*6] == '_':
                        steps0 += [step + (checker + '↓') * i]
                        i += 1
                else:  # 横子
                    i = 1
                    while first//6 == (first-i)//6 and p[first-i] == '_':
                        steps0 += [step + (checker+'←')*i]
                        i += 1
                    i = 1
                    while last//6 == (last+i)// 6 and p[last+i] == '_':
                        steps0 += [step + (checker+'→')*i]
                        i += 1
        if not answer: steps = [i for i in steps0]
    print("步骤", answer)
    print("步数", moves(answer))
    i = 0
    while i < len(answer):
        p = move(answer[:i])
        checker, d = answer[i: i+2]
        n, first, last = 1, p.find(checker), p.rfind(checker)
        while i+2 < len(answer) and answer[i] == answer[i+2]: i, n = i+2, n+1
        else: i+=2
        if d in ['↑', '←']:
            pyautogui.moveTo(X + (first%6)*gridSize, Y + (first//6)*gridSize)
            dragTo(first - n*(6 if d=='↑' else 1), i==len(answer))
        else:
            pyautogui.moveTo(X + (last%6)*gridSize, Y + (last//6)*gridSize)
            dragTo(last + n*(6 if d=='↓' else 1), i==len(answer))
    time.sleep(0.8)
    for i in range(2): pyautogui.click(450, 400)
    for i in range(2): pyautogui.click(300, 666)
    time.sleep(2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值