生存无尽视频

生存无尽模式开局教程, 新手阵型示范和单次选卡键控表演视频.


视频地址

《植物大战僵尸》生存无尽开局教程

《植物大战僵尸》生存无尽新手阵型

【TAS】《植物大战僵尸》生存无尽表演视频

新手阵型 (手动)

PE经典八炮

PE经典八炮

FE经典八炮

FE经典八炮

RE天台十炮

RE天台十炮

ME月夜十炮

ME月夜十炮

DE双冰六炮

DE双冰六炮

NE快六炮

NE快六炮

PE机械钟无炮

PE机械钟无炮

NE减速无炮

NE减速无炮

FE智能无炮

FE智能无炮

键控示范 (脚本)

PE经典十二炮

PE经典十二炮
# coding=utf-8
"""
阵名: PE经典十二炮
出处: https://tieba.baidu.com/f?kz=675626485
节奏: P6: PP|PP|PP|PP|PP|PP
"""

from pvz import *

WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制

SelectCards(["樱桃", "小喷"])

AutoCollect()  # 自动收集资源

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))
    Prejudge(-199, wave)

    # 关底炮炸珊瑚
    if wave in (20, ):
        Until(-150)
        Pao((4, 7))

    # 每波预判炸
    Until(-95)
    if wave in (10, 20):
        Until(-30)
    Pao((2, 9), (5, 9))

    # 旗帜波加樱桃消延迟
    if wave in (10, ):
        Until(-30 + 373 - 100)
        Card("樱桃", (2, 9))

    # 收尾额外多炸两轮
    if wave in (9, 19, 20):
        for _ in range(2):
            Delay(601)
            Pao((2, 9), (5, 9))

PE二十四炮

PE二十四炮
# coding=utf-8
"""
阵名: PE二十四炮
出处: https://tieba.baidu.com/p/991306518
节奏: P6: PPDD|PPI|PPSSDD|PPDD|PPI|PPSSDD
"""

from pvz import *

WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制

SetZombies(["普僵", "撑杆", "舞王", "冰车", "海豚", "矿工", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["复制冰", "寒冰菇", "咖啡豆", "南瓜", "坚果", "窝瓜", "花盆", "胆小", "阳光", "小喷"])

# UpdatePaoList(
#     [
#         (1, 1), (1, 3), (1, 5), (1, 7),
#         (2, 1), (2, 3), (2, 5), (2, 7),
#         (3, 1), (3, 3), (3, 5), (3, 7),
#         (4, 1), (4, 3), (4, 5), (4, 7),
#         (5, 1), (5, 3), (5, 5), (5, 7),
#         (6, 1), (6, 3), (6, 5), (6, 7),
#     ]
# )
# UpdatePaoList([(r, c) for r in range(1, 7) for c in range(1, 8, 2)])

AutoCollect()  # 自动收集资源
IceSpots([(4, 9)], 6)

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))

    # 精准之舞 PPDD
    if wave in (1, 4, 7, 11, 14, 17):
        Prejudge(-14, wave)
        Pao((2, 9), (5, 9))
        Delay(107)
        Pao((1, 7.7), (5, 7.7))

    # 冰之旋舞 PPI
    elif wave in (2, 5, 8, 12, 15, 18):
        Prejudge(-95, wave)
        Pao((2, 9), (5, 9))
        Delay(373 - 100 - 198)  # 冰同步于炮生效
        Coffee()

    # 六神乱舞 PPSSDD
    elif wave in (3, 6, 9, 13, 16, 19):
        Prejudge(-95, wave)
        Pao((2, 9), (5, 9), (2, 9), (5, 9))
        Delay(108)
        Pao((1, 8.8), (5, 8.8))
        if wave in (9, 19):  # 收尾
            Until(601 - 15)
            Pao((2, 9), (5, 9))

    # 大波推迟 PPSSDD
    elif wave == 10:
        Prejudge(-56, wave)
        Pao((2, 9), (5, 9), (2, 9), (5, 9))
        Delay(108)
        Pao((1, 8.8), (5, 8.8))

    elif wave == 20:
        Prejudge(-150, wave)
        Pao((4, 6), (4, 8))  # 炮炸珊瑚
        Delay(90)  # Until(-60)
        Pao((1, 9), (2, 9), (5, 9), (6, 9))
        Delay(108)
        Pao((1, 9), (2, 9), (5, 9), (6, 9))
        print("第 %s 波手动收尾." % wave)

PE裸奔十六炮

PE裸奔十六炮
# coding=utf-8
"""
阵名: PE裸奔十六炮
出处: https://tieba.baidu.com/p/1289540813
节奏: ch6: PPDC|IPd-PPD|PPDC|IPd-PPD, (6|12|6|12)
"""

from pvz import *

WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制


# 种垫铲垫
@RunningInThread
def DianCai():
    Card("小喷菇", (5, 9))
    Card("阳光菇", (6, 9))
    Delay(100)
    Shovel((5, 9))
    Shovel((6, 9))


# 偷菜
@RunningInThread
def Sunflower():
    sunflower_spots = [(1, 2), (1, 5), (1, 6), (2, 2), (2, 5), (2, 6)]
    # 开局种
    for spot in sunflower_spots:
        Card("向日葵", spot)
        Delay(751 + 1)
    # 等第 20 波刷新
    while ReadMemory("int", 0x6A9EC0, 0x768, 0x557C) < 20:
        Sleep(100)
    # 等白字出现
    while ReadMemory("int", 0x6A9EC0, 0x768, 0x140, 0x8C) != 12:
        Sleep(100)
    # 结尾铲
    for spot in sunflower_spots:
        Shovel(spot)


###

SetZombies(["普僵", "撑杆", "舞王", "冰车", "海豚", "矿工", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["咖啡豆", "寒冰菇", "复制冰", "樱桃", "窝瓜", "南瓜头", "向日葵", "胆小菇", "阳光菇", "小喷菇"])

# UpdatePaoList([
#     (3, 1), (3, 3), (3, 5), (3, 7),
#     (4, 1), (4, 3), (4, 5), (4, 7),
#     (5, 1), (5, 3), (5, 5), (5, 7),
#     (6, 1), (6, 3), (6, 5), (6, 7),
# ])

AutoCollect()  # 自动收集资源
IceSpots([(3, 9), (4, 9), (1, 4), (2, 4)], 10)
Sunflower()  # 偷菜线程

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))

    Prejudge(-198, wave)  # 每波均用 198 预判

    # PPD|I-
    if wave in (1, 3, 5, 7, 9, 10, 12, 14, 16, 18):
        if wave == 10:
            Until(-56)
            Pao((2, 9), (5, 9))
            Until(-56 + 110)
            Pao((5, 8))
            Until(601 - 200 - 100)  # 301
            Card("樱桃", (2, 9))  # 消延迟 炸小偷
        else:
            Until(-133)
            Pao((2, 9), (5, 9))
            Until(-133 + 110)
            Pao((5, 8))
        Until(601 + 50 - 298)  # 353
        Coffee()  # 50cs 预判冰

        if wave == 9:  # 第 9 波收尾
            Until(601 - 135)
            DianCai()
            Until(601 - 100)
            Pao((1, 2.4))
            Until(601 + 444 - 373)
            Pao((5, 7.4))
            Until(601 + 1200 - 200 - 373)
            Pao((2, 9), (5, 9))
            Delay(220)
            Pao((5, 8.5))
            Until(601 + 1200 - 133)
            Pao((1, 2.4), (5, 9))
            Until(601 + 1200 - 133 + 110)
            Pao((2, 9))
            Until(601 + 1200 + 601 - 100)
            Delay(600)
            Pao((2, 8), (5, 9))
            Card("小喷菇", (1, 7))
            Card("阳光菇", (2, 7))
            Delay(400)
            Shovel((1, 7), (2, 7))

    # C|Pd-PPD
    elif wave in (2, 4, 6, 8, 11, 13, 15, 17, 19):
        Until(-135)
        DianCai()  # -135 放垫, 撑杆跳跃用时 180, 落地后 5 冰生效
        Until(-100)
        if wave == 11:
            Pao((1, 4))  # 炸小鬼和小偷
        else:
            Pao((1, 2.4))
        Until(444 - 373)
        Pao((5, 7.4))
        Until(1200 - 200 - 373)
        Pao((2, 9), (5, 9))
        Delay(220)
        Pao((5, 8.5))

        if wave == 19:  # 第 19 波收尾
            Until(1200 - 133)
            Pao((2, 9), (5, 9))
            Delay(350)
            Pao((1, 2.4))
            Delay(300)
            Pao((5, 9))
            Delay(400)
            Pao((2, 9))
            Delay(500)
            Pao((5, 9))
            Delay(400)
            Pao((2, 8))
            Card("小喷菇", (1, 7))
            Card("阳光菇", (2, 7))
            Delay(400)
            Shovel((1, 7), (2, 7))

    elif wave == 20:
        Until(-150)
        Pao((4, 7))
        Until(-60)  # 等到刷新前 60cs
        Pao((1, 9), (2, 9), (5, 9), (6, 9))
        Delay(108)
        Pao((1, 9), (2, 9), (5, 9), (6, 9))
        Delay(180)
        Pao((1, 4))  # 尾炸小偷
        print("第 %s 波手动收尾." % wave)

PE经典四炮

PE经典四炮
# coding=utf-8
"""
阵名: PE经典四炮
出处: https://tieba.baidu.com/p/664115150
节奏: C7i: PP|I-PP|I-PP|I-N, (6|18|18|11.5)
"""

from pvz import *

SetZombies(["普僵", "撑杆", "舞王", "冰车", "海豚", "矿工", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["寒冰菇", "复制冰", "核蘑菇", "睡莲", "咖啡豆", "南瓜", "樱桃", "窝瓜", "阳光菇", "小喷"])

UpdatePaoList([(3, 1), (4, 1), (3, 3), (4, 3)])

AutoCollect()  # 自动收集资源
IceSpots([(3, 5), (1, 4), (6, 4), (1, 5), (6, 5)], 15)

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))

    Prejudge(-199, wave)

    # PP
    if wave in (1, 5, 9, 10, 14, 18):
        Until(601 - 200 - 373)
        Pao((2, 9), (5, 9))
        if wave == 10:
            Until(601 - 200 - 100)
            Card("樱桃", (2, 9))
        Until(601 + 20 - 298)  # 20cs 预判冰
        Coffee()
        if wave == 9:  # 第 9 波收尾
            Until(601 + 1800 - 200 - 373)
            Pao((2, 8.3), (5, 8.3))
            print("第 %s 波手动收尾." % wave)  # 倭瓜/垫材

    # I-PP
    elif wave in (2, 6, 11, 15, 19):
        Until(1800 - 200 - 373)
        Pao((2, 8.3), (5, 8.3))
        if wave != 19:
            Until(1800 + 20 - 298)  # 20cs 预判冰
            Coffee()
        if wave == 19:  # 第 19 波收尾
            Until(1800 + 1800 - 200 - 373)
            Pao((2, 8.3), (5, 8.3))
            print("第 %s 波手动收尾." % wave)  # 倭瓜/垫材/樱桃

    # I-PP
    elif wave in (3, 7, 12, 16):
        Until(1800 - 200 - 373)
        Pao((2, 8.3), (5, 8.3))
        Until(1800 + 50 - 298)  # 50cs 预判冰
        Coffee()

    # I-N
    elif wave in (4, 8, 13, 17):
        if wave == 4:
            row, col = (3, 8)
        elif wave == 8:
            row, col = (3, 9)
        elif wave == 13:
            row, col = (4, 8)
        elif wave == 17:
            row, col = (4, 9)
        Until(1150 - 200 - 298)
        Card("睡莲", (row, col))
        Card("核蘑菇", (row, col))
        Card("咖啡豆", (row, col))

    elif wave in (20, ):
        # 不管珊瑚
        Until(-60)
        Pao((2, 9), (5, 9))
        Until(300)
        Coffee()
        print("第 %s 波手动收尾." % wave)  # 樱桃/窝瓜/垫材/炮

DE前置八炮

DE前置八炮
# coding=utf-8
"""
阵名: DE前置八炮
出处: https://tieba.baidu.com/p/3943536673
节奏: ch5: PP|I-PP|IPP-PP, (601|1437|1437)
"""

from pvz import *

SetZombies(["普僵", "撑杆", "舞王", "冰车", "气球", "矿工", "小丑", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["咖啡豆", "寒冰菇", "复制冰", "樱桃", "窝瓜", "坚果", "花盆", "胆小菇", "阳光菇", "小喷菇"])

UpdatePaoList([(1, 1), (1, 5), (3, 1), (3, 5), (2, 5), (4, 5), (5, 1), (5, 5)])

AutoCollect()  # 自动收集资源
IceSpots([(2, 1), (4, 1), (3, 7)], 14 - 1)

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))
    Prejudge(-195, wave)

    # PP
    if wave in (1, 4, 7, 10, 13, 16, 19):
        Until(-40)
        Pao((2, 9), (4, 9))
        Until(601 + 10 - 298)
        Coffee()
        if wave in (19, ):
            Until(601 + 1437 - 200 - 373)
            Pao((2, 8.7), (4, 8.7))
            # Until(601 + 1437 - 150)
            Until(4500 - 200 - 373)
            Pao((2, 8.4), (4, 8.4))

    # I-PP
    elif wave in (2, 5, 8, 11, 14, 17):
        if wave == 2:
            Until(10 + 400)
            Card("倭瓜", (3, 9))  # 压冰车护存冰
        if wave == 11:
            Until(10 + 400 - 100)
            Card("樱桃", (3, 8))  # 炸冰车小偷护存冰
        if wave == 2:
            Until(750)
            Card("小喷菇", (3, 8))  # 垫撑杆
            Delay(100)
            Shovel((3, 8))
        Until(1437 - 200 - 373)
        Pao((2, 8.7), (4, 8.7))
        Until(1437 + 20 - 298)
        Coffee()

    # IPP-PP
    elif wave in (3, 6, 9, 12, 15, 18):
        Until(-150)
        Pao((2, 8.5), (4, 8.5))
        Until(1437 - 200 - 373)
        Pao((2, 8.7), (4, 8.7))
        if wave in (9, ):
            Until(1437 - 40)
            Pao((2, 8.7), (4, 8.7))
            # Until(1437 + 601 + 1437 - 200 - 373)
            Until(4500 - 200 - 373)
            Pao((2, 8.4), (4, 8.4))

    elif wave == 20:
        Until(-60)
        Pao((1, 9), (2, 9), (4, 9), (5, 9))
        Delay(108)
        Pao((1, 8.8), (4, 8.8))
        Until(300)
        Coffee()  # 冰杀小偷
        Until(999)
        Card("复制冰", (4, 1))  # 最后一个存冰
        print("第 %s 波手动收尾." % wave)

RE十六炮

RE十六炮
# coding=utf-8
"""
阵名: RE十六炮
出处: https://tieba.baidu.com/p/1410367512
节奏: ch6: PSD/P|IP-PPD|PSD/P|IP-PPD, (6|12|6|12)
"""

from pvz import *

WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制

SetZombies(["普僵", "撑杆", "橄榄", "冰车", "小丑", "气球", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["玉米", "玉米炮", "樱桃", "倭瓜", "坚果", "核蘑菇", "冰蘑菇", "模仿者寒冰菇", "咖啡豆", "花盆"])

UpdatePaoList([
    (1, 3),  # P
    (1, 5),  # S
    (1, 7),  #    P
    (1, 1),  # D
    (2, 3),  # P
    (2, 5),  # P
    (2, 7),  #    P
    (2, 1),  # D
    (3, 3),  # P
    (3, 5),  # S
    (3, 7),  #    P
    (3, 1),  # D
    (4, 6),  # P
    (4, 1),  # P
    (5, 6),  #    P
    (5, 1),  # D
])

AutoCollect()  # 自动收集资源
IceSpots([(5, 3), (4, 3)], 11)

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))

    # PPSD
    if wave in (1, 3, 5, 7, 9, 10, 12, 14, 16, 18):
        Prejudge(-10, wave)  # -10+373 < 377
        RoofPao((2, 9), (2, 9), (4, 9))
        Delay(110)  # 110 拦截
        RoofPao((2, 8.8))
        Until(601 + 50 - 298)  # 50cs 预判冰
        Coffee()
        if wave == 9:
            Until(601 - 150)
            RoofPao((2, 9))
            Until(601 + 1200 - 200 - 373)
            RoofPao((5, 9), (5, 9))
            Delay(1100)  # 等会儿
            RoofPao((5, 9))

    # IP-PPD
    elif wave in (2, 4, 6, 8, 11, 13, 15, 17, 19):
        Prejudge(-150, wave)
        RoofPao((2, 9))
        Until(1200 - 200 - 373)  # 1200cs 波长
        RoofPao((2, 9), (4, 9))  # 激活炸
        Delay(220)  # 220 拦截
        RoofPao((2, 7.8))
        if wave == 19:
            Until(1200 - 10)
            RoofPao((2, 9), (2, 9), (4, 9))
            Delay(110)  # 110 拦截
            RoofPao((2, 8.8))
            Until(1200 + 601 - 150)
            RoofPao((5, 9))
            Until(1200 + 601 + 1200 - 200 - 373)
            Delay(50)  # 等会儿
            RoofPao((5, 9))

    elif wave == 20:
        Prejudge(-200, wave)
        Coffee()  # 冰消空降
        Until(-100)
        RoofPao((2, 8.5), (5, 8.5))  # 炸冰车
        Until(50)
        RoofPao((4, 2.5), (4, 6.7))  # 炸小偷
        Until(800)
        RoofPao((2, 9), (2, 9), (2, 9), (2, 9))
        Until(1000)
        RoofPao((4, 9), (4, 9), (4, 9), (4, 9))
        print("第 %s 波手动收尾." % wave)

ME十三炮

ME十三炮
# coding=utf-8
"""
阵名: ME十三炮
出处: https://tieba.baidu.com/p/5288033944
节奏: C5u-35s: PPD|PPD|PPD|IP-PPD, (6|6|6|17)
"""

from pvz import *


@RunningInThread
def I():
    Card("花盆", (3, 7))
    Card("寒冰菇", (3, 7))
    Delay(100 + 1)
    Shovel((3, 7))


@RunningInThread
def II():
    Card("花盆", (3, 7))
    Card("复制冰", (3, 7))
    Delay(320 + 100 + 1)
    Shovel((3, 7))


SetZombies(["普僵", "撑杆", "橄榄", "冰车", "小丑", "气球", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["玉米", "玉米炮", "三叶草", "保护伞", "樱桃", "倭瓜", "坚果", "花盆", "寒冰菇", "复制冰"])

UpdatePaoList([
    (1, 3), (1, 5), (1, 1), \
    (2, 3), (2, 5), (2, 1), \
    (3, 3), (3, 5), (3, 1), \
    (4, 6), \
    (4, 1), (5, 6), (5, 1) \
    ])

AutoCollect()  # 自动收集资源

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))

    if wave in (20, ):
        Prejudge(10 - 320, wave)
        II()  # 冰消空降
        Until(100)
        RoofPao((5, 8))
        Until(800)
        RoofPao((2, 9), (2, 9), (2, 9), (2, 9))
        Until(1000)
        RoofPao((4, 9), (4, 9), (4, 9), (4, 9))
        print("第 %s 波手动收尾." % wave)

    # IP-PPD
    elif wave in (4, 8, 10, 14, 18):
        Prejudge(-150, wave)
        if wave in (4, 10, 18):  # 本波原版冰
            Until(5 - 100)
            I()
        Until(100)
        RoofPao((5, 8))
        Until(1700 - 200 - 373)
        RoofPao((2, 8.5), (4, 8.5))
        Delay(230)  # Until(1700 - 200 - 373 + 230)  # 减速延迟 230 炸小鬼
        RoofPao((2, 7))

    # PPD
    else:  # elif wave in (1, 2, 3, 5, 6, 7, 9, 11, 12, 13, 15, 16, 17, 19):
        Prejudge(10, wave)  # 刷新后
        RoofPao((2, 8.5), (4, 8.5))
        Delay(130)  # Until(10 + 130)  # 原速延迟 130 炸小鬼
        RoofPao((2, 7.7))
        if wave in (7, 13):  # 下一波的复制冰
            Until(601 + 5 - 100 - 320)
            II()
        if wave in (9, 19):  # 收尾
            Until(601)
            RoofPao((2, 8.5), (4, 8.5))
            Delay(130)
            RoofPao((2, 7.5))
            # 自动操作收尾
            Until(601 + 601)
            RoofPao((2, 8.5))
            Delay(300)
            RoofPao((5, 8))
            Delay(500)
            RoofPao((5, 8))

NE十五炮

NE十五炮
# coding=utf-8
"""
阵名: NE十五炮
出处: https://tieba.baidu.com/p/1067040250
节奏: C8u: IPP-PP|PADC|PPDD|IPP-PP|NDC|PPDD, (13|6|6|13|6|6)
"""

from pvz import *


@RunningInThread
def DianCai():
    Card("小喷", (4, 9))
    Card("阳光", (5, 9))
    Delay(120)
    Shovel((4, 9))
    Shovel((5, 9))


SetZombies(["普僵", "撑杆", "舞王", "小丑", "气球", "矿工", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["复制冰", "原版冰", "核蘑菇", "樱桃", "倭瓜", "墓碑", "南瓜", "三叶草", "阳光菇", "小喷菇"])

# UpdatePaoList([
#     (1, 1), (2, 1), (3, 1), (4, 1), (5, 1),
#     (1, 5), (2, 5), (3, 5), (4, 5), (5, 5),
#     (1, 7), (2, 7), (3, 7), (4, 7), (5, 7),
#     ])

AutoCollect()  # 自动收集资源

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))
    Prejudge(-195, wave)

    # PPD
    if wave in (10, ):
        Until(-56)
        Pao((2, 9), (4, 9))
        Until(0)
        Pao((2, 9))

    # IPP-PP
    elif wave in (1, 7, 11, 17):
        Until(-150)
        Pao((2, 8.5), (4, 8.5))
        Until(5 - 100)
        Card("寒冰菇", (1, 9))
        if wave == 11:
            Until(-150 + 83)
            DianCai()
        Until(1300 - 200 - 373)
        Pao((2, 9), (4, 9))

    # PADC
    elif wave in (2, 8, 12, 18):
        Until(-95)
        Pao((2, 9))
        Until(-12)
        Pao((2, 9))
        Until(-95 + 373 - 100)
        Card("樱桃", (5, 9))

    # PPDD
    elif wave in (3, 9, 13, 19):
        Until(-95)
        Pao((2, 9), (5, 9))
        Until(-15)
        Pao((1, 9), (4, 9))
        Until(0)
        DianCai()
        Until(601 + 44 - 100 - 320)  # 44cs 预判冰
        Card("模仿者寒冰菇", (1, 9))

        if wave in (9, 19):
            Until(601 - 150)
            Pao((4, 9))
            Delay(450)
            Pao((1, 9))
            Until(601 + 1300 - 200 - 373)
            Delay(300)
            Pao((2, 9), (5, 9))

    # IPP-PP
    elif wave in (4, 14):
        Until(-150)
        Pao((2, 8.5), (4, 8.5))
        Until(1300 - 200 - 373)
        Pao((2, 9), (4, 9))

    # NDC
    elif wave in (5, 15):
        Until(-12)
        Pao((2, 9))
        Until(-95 + 373 - 100)
        Card("核蘑菇", (3, 9) if wave == 5 else (2, 9))

    # PPDD
    elif wave in (6, 16):
        Until(-95)
        Pao((2, 9), (5, 9))
        Until(-12)
        Pao((1, 9), (4, 9))
        Until(0)
        DianCai()

    elif wave == 20:
        Until(-56)
        Pao((1, 9), (4, 9))
        Until(-35)
        Pao((2, 9), (5, 9))  # 炸墓碑冒出的僵尸
        Until(601 - 100 - 83)
        Pao((1, 8.3), (4, 8.3))
        Until(601 - 100)
        # 冰杀小偷
        with MouseLock():
            SafeClick()
            ClickSeed("寒冰菇")
            ClickGrid((1, 9))
            ClickGrid((2, 9))
            ClickGrid((3, 9))
            ClickGrid((4, 9))
            ClickGrid((5, 9))
            SafeClick()
        Delay(100)
        Pao((2, 8.2), (5, 8.2))
        print("第 %s 波手动收尾." % wave)

FE二十二炮

FE二十二炮
# coding=utf-8
"""
阵名: FE二十二炮
出处: None
节奏: ch9-57s: IPP-PPDD|PSD/PDC|IPP-PPDD|PSD/PDC|N+AD/DC|PD/PDC|PSD/PDC, (13.5|6|13.5|6|6|6|6)
"""

from pvz import *

WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制
WriteMemory("unsigned short", 0xd231, 0x0041a68d)  # 浓雾透视


# Cannon Fodder
# 下标 6/7 8/9
# 垫材 花盆/胆小菇 阳光菇/小喷菇
# 根据小喷是否可用来决定用哪一组垫材
@RunningInThread
def DianCai():
    if ReadMemory("bool", 0x6A9EC0, 0x768, 0x144, 0x70 + 9 * 0x50):
        Card("阳光菇", (5, 9))
        Card("小喷菇", (6, 9))
    else:
        Card("花盆", (5, 9))
        Card("胆小菇", (6, 9))
    Delay(30)
    Shovel((5, 9), (6, 9))


SetZombies(["普僵", "撑杆", "舞王", "冰车", "海豚", "矿工", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["寒冰菇", "模仿冰", "毁灭菇", "睡莲", "樱桃", "坚果", "花盆", "胆小", "阳光", "小喷"])

UpdatePaoList([
    (1, 1),
    (2, 1),
    (3, 1),
    (4, 1),
    (5, 1),
    (6, 1),
    (1, 3),
    (2, 3),
    (3, 3),
    (4, 3),
    (5, 3),
    (6, 3),
    (1, 5),
    (2, 5),
    (3, 5),
    (4, 5),
    (5, 5),
    (6, 5),
    (1, 7),
    (2, 7),
    # (3, 7),
    # (4, 7),
    (5, 7),
    (6, 7),
])

AutoCollect()  # 自动收集资源

# IPP-PPDD
Prejudge(5 - 100, 1)  # 本波 5cs 预判冰
Card("寒冰菇", (2, 9))
Until(-15)
Pao((1, 8.8))  # 上半场热过渡, 炸 1 路收跳跳
Until(444 - 373)
Pao((5, 7.4))  # 下半场热过渡, 右极限大概 7.43
Until(1350 - 200 - 373)
Pao((2, 9), (5, 8.7))  # 激活炮, 下半场落点左移收跳跳
Delay(220)
Pao((1, 8.6), (5, 8.6))  # 连续拦截之一, 落点左移

# PSD/PDC
Prejudge(-133, 2)  # 133 预判对应上波过 220 继续拦截
Pao((1, 9), (5, 9))  # 连续拦截之二
Until(-95)
Pao((2, 9))  # 上半场 S
Until(-133 + 110)
Pao((5, 7.8))  # 下半场 D
Until(-95 + 110)
Pao((1, 8.8))  # 上半场 D
Until(601 + 5 - 100 - 320)  # 下一波 5cs 预判冰
Card("模仿者寒冰菇", (2, 9))

# IPP-PPDD
# 相比 wave1 多了垫材操作
Prejudge(-180, 3)
DianCai()  # 垫上一波撑杆
Until(-15)
Pao((1, 8.8))
Until(444 - 373)
Pao((5, 7.4))
Until(5 + 600)  # 全部解冻
DianCai()  # 垫红眼
Until(1350 - 200 - 373)
Pao((2, 9), (5, 8.7))
Delay(220)
Pao((1, 8.6), (5, 8.6))

# PSD/PDC
# 炸法同 wave2
Prejudge(-133, 4)
Pao((1, 9), (5, 9))
Until(-95)
Pao((2, 9))
Until(-133 + 110)
Pao((5, 7.8))
Until(-95 + 110)
Pao((1, 8.8))

# N+AD/DC
# 连续加速波下半场对应垫材 24 炮打法, 因此激活炮要尽早生效
# 最早为 226 可全炸巨人, 相当于 147 预判炮
# 这里 N 相当于激活炮, 上半场 A 相当于 S
Prejudge(-145 + 83, 5)  # 下半场使撑杆不啃炮的最早放垫材时间
DianCai()  # 垫上一波撑杆
Until(-145 + 110)
Pao((5, 7.8))  # 下半场 D
Until(-95 + 110)
Pao((1, 8.8))  # 上半场 D
Until(-145 + 373 - 100)  # 等效 145 预判炮
Card("睡莲", (3, 9))
Card("毁灭菇", (3, 9))
Until(-95 + 373 - 100)  # 等效 95 预判炮
Card("樱桃炸弹", (2, 9))

# PD/PDC
# 下半场对应垫材 24 炮打法, 上半场精准之舞
Prejudge(-145, 6)
Pao((5, 9))  # 下半场 P
Delay(83)
DianCai()  # 垫上一波撑杆
Until(-145 + 110)
Pao((5, 7.8))  # 下半场 D
Until(-14)
Pao((2, 9))  # 上半场 P
Delay(107)
Pao((1, 7.8))  # 上半场 D

# PSD/PDC
Prejudge(-145, 7)
Pao((5, 9))  # 下半场 P
Until(-95)
Pao((2, 9), (2, 9))  # 上半场 PS
Until(-145 + 83)
DianCai()  # 垫上一波撑杆
Until(-145 + 110)
Pao((5, 7.8))  # 下半场 D
Until(-95 + 110)
Pao((1, 8.8))  # 上半场 D

# IPP-PPDD
Prejudge(-180, 8)
DianCai()
Until(5 - 100)
Card("寒冰菇", (2, 9))
Until(-15)
Pao((1, 8.8))
Until(444 - 373)
Pao((5, 7.4))
Until(1350 + 15 - 100 - 320 - 373 - 1)  # 571
Pao((2, 8.2))
Until(5 + 600)  # 全部解冻
DianCai()
Until(1350 - 200 - 373)  # 777
Pao((2, 9), (5, 8.7))
Until(1350 + 15 - 100 - 320)  # 945
Card("模仿者寒冰菇", (2, 9))
Until(1350 - 200 - 373 + 220)  # 997
Pao((1, 8.8), (5, 8.6))  # 上半场炸撑杆

# 收尾波
Prejudge(-133, 9)
Pao((1, 9), (5, 9))
Until(-15)
Pao((1, 9), (5, 9))
Until(1300 - 200 - 373)  # 1350->1300
Pao((2, 9), (5, 9))
Delay(220)
Pao((1, 9), (5, 9))
Delay(220)
Pao((1, 9), (5, 9))
Delay(600)  # 等冰菇 CD
Pao((2, 9), (5, 9))
Delay(700)  # 清伴舞
Pao((2, 9), (5, 9))

# PSD/PDC
# 上半场 PSD, 下半场收撑杆省垫材
Prejudge(-83, 10)  # -83
Pao((1, 9))
Until(-14)  # -14
Pao((5, 9))
Until(-83 + 104)  # 394-373=21
Pao((2, 9))
Until(-14 + 110)  # 96
Pao((5, 7.8))
Until(-83 + 104 + 110)  # 131
Pao((1, 8.8))

# IPP-PPDD
Prejudge(5 - 100, 11)
# 相比 wave1 多了垫红眼操作
Card("寒冰菇", (2, 9))
Until(-15)
Pao((1, 8.8))
Until(444 - 373)
Pao((5, 7.4))
Until(5 + 600)  # 全部解冻
DianCai()
Until(1350 - 200 - 373)
Pao((2, 9), (5, 8.7))
Delay(220)
Pao((1, 8.6), (5, 8.6))

# PSD/PDC
Prejudge(-133, 12)  # 133 预判对应上波过 220 继续拦截
Pao((1, 9), (5, 9))  # 连续拦截之二
Until(-95)
Pao((2, 9))  # 上半场 S
Until(-133 + 110)
Pao((5, 7.8))  # 下半场 D
Until(-95 + 110)
Pao((1, 8.8))  # 上半场 D
Until(601 + 5 - 100 - 320)  # 下一波 5cs 预判冰
Card("模仿者寒冰菇", (2, 9))

# IPP-PPDD
# 相比 wave11 多了垫材操作
Prejudge(-180, 13)
DianCai()  # 垫上一波撑杆
Until(-15)
Pao((1, 8.8))
Until(444 - 373)
Pao((5, 7.4))
Until(5 + 600)  # 全部解冻
DianCai()  # 垫红眼
Until(1350 - 200 - 373)
Pao((2, 9), (5, 8.7))
Delay(220)
Pao((1, 8.6), (5, 8.6))

# PSD/PDC
# 炸法同 wave12
Prejudge(-133, 14)
Pao((1, 9), (5, 9))
Until(-95)
Pao((2, 9))
Until(-133 + 110)
Pao((5, 7.8))
Until(-95 + 110)
Pao((1, 8.8))

# N+AD/DC
# 操作同 wave5,  弹坑改为 4-9
Prejudge(-145 + 83, 15)
DianCai()
Until(-145 + 110)
Pao((5, 7.8))
Until(-95 + 110)
Pao((1, 8.8))
Until(-145 + 373 - 100)
Card("睡莲", (4, 9))
Card("毁灭菇", (4, 9))
Until(-95 + 373 - 100)
Card("樱桃炸弹", (2, 9))

# PD/PDC
# 下半场对应垫材 24 炮打法, 上半场精准之舞
Prejudge(-145, 16)
Pao((5, 9))  # 下半场 P
Delay(83)
DianCai()  # 垫上一波撑杆
Until(-145 + 110)
Pao((5, 7.8))  # 下半场 D
Until(-14)
Pao((2, 9))  # 上半场 P
Delay(107)
Pao((1, 7.8))  # 上半场 D

# PSD/PDC
Prejudge(-145, 17)
Pao((5, 9))  # 下半场 P
Until(-95)
Pao((2, 9), (2, 9))  # 上半场 PS
Until(-145 + 83)
DianCai()  # 垫上一波撑杆
Until(-145 + 110)
Pao((5, 7.8))  # 下半场 D
Until(-95 + 110)
Pao((1, 8.8))  # 上半场 D

# IPP-PPDD
Prejudge(-180, 18)
DianCai()
Until(5 - 100)
Card("寒冰菇", (2, 9))
Until(-15)
Pao((1, 8.8))
Until(444 - 373)
Pao((5, 7.4))
Until(1350 + 15 - 100 - 320 - 373 - 1)  # 571
Pao((2, 8.2))
Until(5 + 600)  # 全部解冻
DianCai()
Until(1350 - 200 - 373)  # 777
Pao((2, 9), (5, 8.7))
Until(1350 + 15 - 100 - 320)  # 945
Card("模仿者寒冰菇", (2, 9))
Until(1350 - 200 - 373 + 220)  # 997
Pao((1, 8.8), (5, 8.6))  # 上半场炸撑杆

# 收尾波
Prejudge(-133, 19)
Pao((1, 9), (5, 9))
Until(-15)
Pao((1, 9), (5, 9))
Until(1300 - 200 - 373)  # 1350->1300
Pao((2, 9), (5, 9))
Delay(220)
Pao((1, 9), (5, 9))
Delay(220)
Pao((1, 9), (5, 9))
Delay(600)  # 等冰菇 CD
Pao((2, 9), (5, 9))
Delay(700)  # 清伴舞
Pao((2, 9), (5, 9))

# PP-PPPPPPPP
Prejudge(-150, 20)
Pao((4, 7))  # 炮炸珊瑚
Until(-60)  # 等到刷新前 60cs
Pao((2, 9), (5, 9))
Delay(108)
Pao((1, 8.8), (5, 8.8))
Delay(108)
Pao((1, 8.6), (5, 8.6))
Delay(108)
Pao((2, 8.4), (5, 8.4))  # 炸小偷
print("最后一大波手动收尾.")

RE椭盘十四炮

RE椭盘十四炮

由于某些游戏机制的问题, 咖啡豆和模仿者的生效时机是不确定的. 这个示例为了提高 ICE3 的成功率编写了一个寒冰菇生效时间修正函数, 修改内存统一时间后能减少录视频 S/L 所花费的时间.

# coding=utf-8
"""
阵名: RE椭盘十四炮
出处: https://tieba.baidu.com/p/5029428684
节奏: ch4: ICE3+PPDD+B-PP|ICE3+PPDD+B-PP, (1780|1780)
"""

from pvz import *


# 冰三修正函数
@RunningInThread
def ICE3(t):
    clock = ReadMemory("int", 0x6A9EC0, 0x768, 0x5568)  # 基准时间
    while (ReadMemory("int", 0x6A9EC0, 0x768, 0x5568) - clock) < (t - 50):
        Sleep(0.1)
    ice_index = 0
    plants_count_max = ReadMemory("unsigned int", 0x6A9EC0, 0x768, 0xB0)
    plants_offset = ReadMemory("unsigned int", 0x6A9EC0, 0x768, 0xAC)
    for i in range(plants_count_max):
        plant_dead = ReadMemory("bool", plants_offset + 0x141 + 0x14C * i)
        plant_crushed = ReadMemory("bool", plants_offset + 0x142 + 0x14C * i)
        plant_type = ReadMemory("int", plants_offset + 0x24 + 0x14C * i)
        plant_countdown = ReadMemory("int", plants_offset + 0x50 + 0x14C * i)
        if not plant_dead and not plant_crushed and plant_type == 14 and 45 < plant_countdown < 55:
            ice_index = i
            break
    while (ReadMemory("int", 0x6A9EC0, 0x768, 0x5568) - clock) < (t - 10):
        Sleep(0.1)
    WriteMemory("int", 11, plants_offset + 0x50 + 0x14C * ice_index)


WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制

SetZombies(["普僵", "撑杆", "橄榄", "冰车", "小丑", "气球", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["花盆", "寒冰菇", "模仿者寒冰菇", "毁灭菇", "咖啡豆", "樱桃炸弹", "火爆辣椒", "倭瓜", "寒冰射手", "坚果墙"])

UpdatePaoList([
    (4, 2),  # P
    (4, 4),  # P
    (1, 4),  # D
    (5, 4),  # D
    (5, 6),  # B
    (3, 1),  # P
    (4, 7),  # P
    ###
    (1, 2),  # P
    (2, 4),  # P
    (3, 3),  # D
    (3, 5),  # D
    (2, 6),  # B
    (2, 1),  # P
    (3, 7),  # P
])
# IPPDDP-PP IPPDDP-PP  14
# PPDDDD    IP-PP      9
# PPSSDD    IAA'aP-PP  9
Skip(5)  # 调整炮序
# while ReadMemory("int", 0x6A9EC0, 0x7FC) != 3:
#     Sleep(1)
# while ReadMemory("bool", 0x6A9EC0, 0x768, 0x164):
#     Sleep(1)
Card("花盆", (1, 7))
Card("寒冰菇", (1, 7))

AutoCollect([1, 2, 3, 4, 5, 6, 17], 15)
IceSpots([(4, 6), (2, 3), (1, 1), (1, 6)], 18 - 1)

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))

    if wave in (1, ):
        Prejudge(-190, wave)
        Until(377 - 373)
        RoofPao((2, 8.8), (4, 8.8))
        Until(506 - 373)
        RoofPao((2, 8.8), (4, 8.8))
        Until(601 + 34 - 373)
        RoofPao((2, 8.8), (4, 8.8))
        Until(601 + 34 - 298)
        Card("咖啡豆", (1, 7))  # Coffee()
        ICE3(298)

    elif wave in (2, ):
        Prejudge(-190, wave)
        Until(50)
        Shovel((1, 7))  # 铲
        Until(1300 - 200 - 373)  # 727
        RoofPao((4, 8.2))
        Until(1780 - 200 - 373)  # 1207
        RoofPao((2, 9), (4, 9))
        Until(1780 + 10 - 298)  # 1492
        Coffee()
        ICE3(298)

    elif wave in (10, ):
        Prejudge(-15, wave)
        RoofPao((2, 9), (4, 9), (2, 9), (4, 9))
        Until(-15 + 110)  # 95
        RoofPao((4, 7.7))  # 空炸小鬼兼小偷
        Until(-15 + 190)  # 175
        RoofPao((1, 5))  # 2-5? 尾炸小鬼兼小偷
        Until(601 + 10 - 298)  # 313
        Coffee()
        ICE3(298)

    elif wave in (11, ):
        Prejudge(-190, wave)
        Until(10 + 400 - 100)
        Card("辣椒", (1, 7))
        Card("花盆", (4, 9))
        Card("樱桃", (4, 9))
        Until(10 + 400 + 10)
        Shovel((1, 7))  # 铲
        Shovel((4, 9))  # 铲
        Until(1250 - 200 - 373)  # 1300->1250
        RoofPao((3, 8.21))  # 落点改为 3 路炸掉 2 路冰车
        Until(1780 - 200 - 373)
        RoofPao((2, 9), (4, 9))
        Until(1780 + 10 - 298)
        Coffee()
        ICE3(298)

    elif wave in (3, 12):
        Prejudge(-190, wave)
        Until(10 + 400 - 373)
        RoofPao((2, 9), (4, 9))
        Until(10 + 400 - 373 + 220)
        RoofPao((4, 8.5))  # 空炸
        Until(10 + 400 - 373 + 300)
        RoofPao((2, 4.7))  # 尾炸小鬼跳跳
        Until(1300 - 200 - 373)
        RoofPao((4, 8.2))
        Until(1780 - 200 - 373)
        RoofPao((2, 9), (4, 9))
        Until(1780 + 10 - 298)
        Coffee()
        ICE3(298)

    elif wave in (9, 19):
        Prejudge(-190, wave)
        Until(10 + 400 - 373)
        RoofPao((2, 9), (4, 9))
        Until(10 + 400 - 373 + 220)
        RoofPao((2, 8.5), (4, 8.5))
        Until(1300 - 200 - 373)
        RoofPao((3, 8.22))  # 落点改为 3 路减少小丑炸核机率
        # 收尾
        Until(1705 - 200 - 298)
        Card("花盆", (3, 9))
        Card("核蘑菇", (3, 9))
        Card("咖啡豆", (3, 9))
        Until(1705 - 200 + 230 - 373)
        RoofPao((2, 8.5), (4, 8.5))  # 拦截
        Until(1705 - 200 + 230 + 230 - 373)
        RoofPao((2, 8.5), (4, 8.5))  # 拦截
        Until(1705 - 200 + 230 + 230 + 230 - 373)
        RoofPao((3, 9), (5, 9))  # 留下 1 路
        Delay(50)
        Card("寒冰射手", (1, 6))
        # 清场
        if wave == 9:
            Skip(7 - 4 - 1 + 5)  # 调整炮序
            Until(2700)
            Card("花盆", (1, 8))  # 垫一下
            Until(4500 - 200 - 373)  # Until(4500 - 5)  # 出红字时
            Delay(400)  # 等那一门炮
            RoofPao((1, 8))  # 清场
            Until(4500 - 200 + 100)
            Shovel((1, 6))  # 铲掉冰豆
            Until(4500 - 5 + 750 - 599)  # 第 10 波刷新前 599
            Card("花盆", (1, 7))
        else:  # 19
            Until(4500 - 200 - 373)
            RoofPao((1, 8))  # 清场
            Delay(200)
            Shovel((1, 6))  # 铲掉冰豆

    elif wave in (20, ):
        Prejudge(50 - 298, wave)
        Coffee()  # 冰消空降
        Until(75)
        RoofPao((2, 3), (4, 8), (2, 8))  # 炸冰车小偷
        Until(1250 - 200 - 373)
        RoofPao((1, 9), (2, 9), (4, 9), (5, 9))
        Until(1250 - 200 - 373 + 220)
        RoofPao((1, 9), (2, 9), (4, 9), (5, 9))
        # 收尾
        print("第 %d 波手动收尾." % wave)
        # Delay(1000)
        # Pao((3, 9), (4, 9))
        # Card("花盆", (1, 7))
        # Card("坚果", (1, 7))
        # Until(5500 - 182)
        # Card("倭瓜", (1, 6))
        # Until(5500 + 100)
        # Shovel((1, 7))
        # Shovel((1, 7))

    else:  # wave in (4, 5, 6, 7, 8, 13, 14, 15, 16, 17, 18):
        # 收尾波前一波延长波长
        WL = 1925 if wave in (8, 18) else 1780
        Prejudge(-190, wave)
        Until(10 + 400 - 373)
        RoofPao((2, 9), (4, 9))
        Until(10 + 400 - 373 + 220)
        RoofPao((2, 8.5), (4, 8.5))
        Until(1300 - 200 - 373)
        RoofPao((4, 8.2))
        Until(WL - 200 - 373)  # WL-573
        RoofPao((2, 9), (4, 9))
        if wave in (8, 18):
            Until(WL - 200 - 373 + 83)  # WL-490
            Card("花盆", (2, 8))  # 垫 2 路梯子
        Until(WL + 10 - 298)  # WL-288
        Coffee()
        ICE3(298)
        if wave in (8, 18):
            Until(WL - 200)  # WL-200
            Shovel((2, 8))  # 炮落地铲

PE半场十二炮

PE半场十二炮

这个示例为了实现自动补植物 (其实辅助操作完全可以手动完成) 编写了一个较为复杂的函数, 作者水平有限不保证函数实现足够完善和智能, 代码仅供参考. 另外这个函数使用了部分框架内部私有变量和方法, 这些内容可能会在后续版本中被改名或者移除, 需要谨慎使用. 如果你看不懂自定义函数的内容也没有关系, 不需要去弄懂, 也不推荐这么照做 (指使用非公开接口).

# coding=utf-8
"""
阵名: PE半场十二炮
出处: https://tieba.baidu.com/p/1801759994
节奏: ch4: I+BC/d-PDD/P|I+BC/d-PDD/P, (18|18)
"""

from pvz import *

WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制


# 种垫铲垫
@RunningInThread
def DianCai():
    Card("小喷", (1, 9))
    Card("阳光", (2, 9))
    Delay(100)
    Shovel((1, 9))
    Shovel((2, 9))


# 烧小偷
@RunningInThread
def 口吐金蛇():
    # 等第 10 波刷新
    while ReadMemory("int", 0x6A9EC0, 0x768, 0x557C) < 10:
        Sleep(1)
    Delay(400)
    Card("睡莲", (4, 9))
    Card("辣椒", (4, 9))
    Delay(100 + 1)
    Shovel((4, 9))
    # 等第 20 波刷新
    while ReadMemory("int", 0x6A9EC0, 0x768, 0x557C) < 20:
        Sleep(1)
    Delay(400)
    Card("睡莲", (4, 9))
    Card("辣椒", (4, 9))
    Delay(100 + 1)
    Shovel((4, 9))



@RunningInThread
def NutsFixer(spots, seed):
    """
    坚果类植物修复. 在单独的子线程运行.
    @参数 spots(list): 位置, 包括若干个 (行, 列) 元组.
    @参数 seed(str): 卡片名称, 可选值 ["坚果", "高坚果", "南瓜头"].
    @示例:
    >>> NutsFixer([(3, 8), (4, 8)], "高坚果")
    >>> NutsFixer([(4, 5),(4, 6),(4, 7),(4, 8)], "南瓜头")
    """

    # 1.草地 2.裸地 3.泳池
    # 16.睡莲 33.花盆
    # 3.坚果 23.高坚果 30.南瓜头

    from pvz.core import debug
    from pvz.core import info
    from pvz.core import warning
    from pvz.core import error
    from pvz.core import read_memory
    from pvz.core import thread_sleep_for
    from pvz.extra import get_seed_by_name
    from pvz.extra import get_index_by_name
    from pvz.extra import get_block_type
    from pvz.extra import get_plants_croods
    from pvz.extra import use_seed
    from pvz.extra import game_scene
    from pvz.extra import game_delay_for

    while read_memory("int", 0x6A9EC0, 0x7FC) != 3:
        thread_sleep_for(1)

    info("启动坚果类植物修复线程.")

    seed_type = get_seed_by_name(seed)  # 根据名称得到卡片代号
    if seed_type not in (3, 23, 30, 3 + 48, 23 + 48, 30 + 48):
        error("自动修复只支持 坚果/高坚果/南瓜头.")
    seed_index = get_index_by_name(seed)  # 获取卡片的位置, 数组下标需要 -1
    if seed_index is None:
        error("卡槽没有 %s 卡片, 退出坚果类植物修复线程." % seed)

    seed_cost = read_memory("int", 0x69F2C0 + seed_type * 0x24)  # 卡片价格
    seed_recharge = read_memory("int", 0x69F2C4 + seed_type * 0x24)  # 卡片冷却
    # HP_MAX = 4000 if seed_type in (3, 30) else 8000
    if seed_type == 3:  # Wall-nut
        HP_MAX = read_memory("int", 0x45E1A7)
    elif seed_type == 23:  # Tall-nut
        HP_MAX = read_memory("int", 0x45E215)
    else:  # 30 Pumpkin
        HP_MAX = read_memory("int", 0x45E445)
    LINIT = int(HP_MAX * 0.1) if len(spots) < 2 else int(HP_MAX * 0.3)  # TODO

    # 补种函数
    def fix(spot):
        slots_offset = read_memory("unsigned int", 0x6A9EC0, 0x768, 0x144)
        seed_usable = read_memory("bool", slots_offset + 0x70 + (seed_index - 1) * 0x50)  # 该卡片是否可用
        sun = read_memory("int", 0x6A9EC0, 0x768, 0x5560)  # 当前阳光
        if seed_usable and sun >= seed_cost:
            while read_memory("bool", 0x6A9EC0, 0x768, 0x164):  # 处于暂停
                thread_sleep_for(1)
        else:
            return False
        success = False
        if get_block_type(spot) == 3 and (16, spot[0], spot[1]) not in get_plants_croods():
            seed_lilypad_index = get_index_by_name("睡莲")
            if seed_lilypad_index is None:
                warning("卡片 睡莲 不在卡槽中.")
            else:
                seed_lilypad_usable = read_memory("bool", slots_offset + 0x70 + (seed_lilypad_index - 1) * 0x50)
                if seed_lilypad_usable:
                    use_seed("睡莲", spot)
                    use_seed(seed, spot)
                    success = True
        elif game_scene in (4, 5) and (33, spot[0], spot[1]) not in get_plants_croods():
            seed_flowerpot_index = get_index_by_name("花盆")
            if seed_flowerpot_index is None:
                warning("卡片 花盆 不在卡槽中.")
            else:
                seed_flowerpot_usable = read_memory("bool", slots_offset + 0x70 + (seed_flowerpot_index - 1) * 0x50)
                if seed_flowerpot_usable:
                    use_seed("花盆", spot)
                    use_seed(seed, spot)
                    success = True
        else:
            use_seed(seed, spot)
            success = True
        thread_sleep_for(1)
        return success

    while read_memory("int", 0x6A9EC0, 0x7FC) == 3 and read_memory("int", 0x6A9EC0, 0x768, 0x557C) < 20:
    # while read_memory("int", 0x6A9EC0, 0x7FC) == 3:

        croods_which_has_plant = []
        plants = get_plants_croods()
        for plant_type, plant_row, plant_col in plants:
            # 需要修复的植物是 南瓜 时, 只有南瓜才算占位
            # 需要修复的植物是 坚果/高坚果 时, 不是 睡莲/花盆/南瓜 就算占位
            if (seed_type in (30, 30 + 48) and plant_type in (30, 30 + 48)) or (seed_type not in (30, 30 + 48)
                                                                                and plant_type not in (16, 30, 33)):
                croods_which_has_plant.append((plant_row, plant_col))
                if plant_type == 47:  # 玉米炮占两格
                    croods_which_has_plant.append((plant_row, plant_col + 1))
        spot_which_has_plant = [i for i in spots if i in croods_which_has_plant]

        for spot in spots:
            # 位置有植物但不是坚果/高坚果/南瓜
            if spot in spot_which_has_plant and (seed_type, spot[0], spot[1]) not in plants:
                thread_sleep_for(1)
                continue
            # 位置有植物而且是坚果/高坚果/南瓜
            elif spot in spot_which_has_plant and (seed_type, spot[0], spot[1]) in plants:
                plants_count_max = read_memory("unsigned int", 0x6A9EC0, 0x768, 0xB0)
                plants_offset = read_memory("unsigned int", 0x6A9EC0, 0x768, 0xAC)
                plants_index = None
                for i in range(plants_count_max):
                    plants_disappeared = read_memory("bool", plants_offset + 0x141 + 0x14C * i)
                    plants_crushed = read_memory("bool", plants_offset + 0x142 + 0x14C * i)
                    plants_type = read_memory("int", plants_offset + 0x24 + 0x14C * i)
                    plants_row = read_memory("int", plants_offset + 0x1C + 0x14C * i)
                    plants_col = read_memory("int", plants_offset + 0x28 + 0x14C * i)
                    if (not plants_disappeared and not plants_crushed and plants_type == seed_type and plants_row == spot[0] - 1
                            and plants_col == spot[1] - 1):  # 特定位置
                        plants_index = i
                debug("位置 %s 的植物 %s 下标为 %d." % (str(spot), seed, plants_index))
                plant_hp = read_memory("int", plants_offset + 0x40 + 0x14C * plants_index)
                debug("位置 %s 的植物 %s 血量为 %d." % (str(spot), seed, plant_hp))
                if plant_hp < LINIT:
                    if fix(spot):  # 种植
                        game_delay_for(seed_recharge + 1)
                    break
            # 位置没有植物
            elif spot not in spot_which_has_plant:
                if fix(spot):  # 种植
                    game_delay_for(seed_recharge + 1)
                break

        game_delay_for(10)

    info("停止坚果类植物修复线程.")



###

SetZombies(["普僵", "撑杆", "舞王", "冰车", "海豚", "矿工", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["白冰", "冰菇", "咖啡", "荷叶", "南瓜", "樱桃", "辣椒", "倭瓜", "阳光", "小喷"])

UpdatePaoList([
    (1, 3), (2, 3), (3, 3), \
    (1, 5), (2, 5), (3, 5), \
    (1, 7), (2, 7), (3, 7), \
    (1, 1), (2, 1), (3, 1), \
    ])


while ReadMemory("int", 0x6A9EC0, 0x7FC) != 3:  # 还没进入战斗界面
    Sleep(1)
while ReadMemory("bool", 0x6A9EC0, 0x768, 0x164):  # 处于暂停状态
    Sleep(1)
Card("寒冰菇", (5, 5))  # 临时存冰
Card("睡莲", (3, 9))  # 临时存冰位
Card("南瓜头", (3, 9))  # 其实不需要


AutoCollect()  # 自动收集资源
IceSpots([(4, 5), (4, 6), (4, 7), (4, 8), (3, 9)], 17 - 1)
NutsFixer([(4, 5), (4, 6), (4, 7), (4, 8)], "南瓜头")
口吐金蛇()


for wave in range(1, 21):
    print("当前操作波次: " + str(wave))
    Prejudge(-190, wave)

    if wave in (1, 10):
        Until(-95)
        Pao((1, 9))
        Until(-15)
        Pao((2, 9), (5, 9))
        Until(-15 + 110)
        Pao((5, 7.7))
        Until(-15 + 110 + 373 - 100)  # 368
        Card("樱桃", (1, 9))

    elif wave == 20:
        Until(-150)
        Pao((4, 7))
        Until(-60)  # 等到刷新前 60cs
        Pao((2, 9), (5, 9), (2, 9), (5, 9))
        Until(-60 + 110)
        Pao((1, 8.8), (2, 8.8))  # 炮不够 ==
        Until(-60 + 110 + 373 - 100)
        Card("樱桃", (5, 9))
        print("第 %s 波手动收尾." % wave)
        # Pao((5, 8))
        Until(5500 + 100)
        Shovel((3, 9), (3, 9))  # 跳白字后铲掉

    else:
        Until(-133)
        Pao((1, 8.0))  # 拦截上波红眼, 分离部分快速僵尸
        Until(360 - 373)
        Pao((2, 8.15))  # 无冰分离
        Until(360 - 298)  # 360cs 反应冰
        Coffee() if wave not in (2,) else Card("咖啡豆", (5, 5))
        Until(360 + 500 - 373)
        # WZ_PNT = (5, 2.7) if wave in (3, 12) else (5, 3)  # 尾炸落点
        WZ_PNT = (5, 3)
        Pao(WZ_PNT) if wave not in (2, 11) else None  # 下半场尾炸
        Until(1800 - 200 - 373)
        Pao((2, 9), (5, 8.1))  # 激活炸
        Delay(10)
        DianCai()  # 垫撑杆
        Until(1800 - 200 - 373 + 220)
        Pao((1, 8.2))  # 秒白眼, 触发红眼投掷

        if wave in (9, 19):  # 收尾波次
            Until(1800 - 133)
            Pao((1, 8.0))
            Until(1800 + 360 - 373)
            Pao((2, 9))
            Until(1800 + 360 + 500 - 373)
            Pao((5, 2.5))
            Until(1800 + 1800 - 200 - 373)
            Pao((5, 6))
            Delay(110)
            Pao((5, 6))
            Delay(110)
            Pao((5, 3))
            Until(4500 - 200 - 373)
            Pao((5, 5))
            Skip(2) if wave == 9 else None  # 中场调整炮序

PE最后之作

PE最后之作

这个示例为了实现自动补植物 (其实辅助操作完全可以手动完成) 编写了一个较为复杂的函数, 作者水平有限不保证函数实现足够完善和智能, 代码仅供参考.

# coding=utf-8
"""
阵名: PE最后之作
出处: https://tieba.baidu.com/p/5102612180
节奏: ch5u-35.62s: PPDD|I-PPdd|IPP-PPDDCC, (6|13|16.62)
"""

from pvz import *

WriteMemory("int", 0x00679300, 0x0040FCED)  # 取消点炮限制

# @RunningInThread
# def DianCai():
#     diancai_list = ["保护伞", "胆小", "阳光", "小喷"]
#     diancai_spot = [(1, 8), (2, 8), (5, 8), (6, 8)]
#     import random
#     random.shuffle(diancai_list)
#     for i in range(4):
#         Card(diancai_list[i], diancai_spot[i])
#     Delay(10)
#     for i in range(4):
#         Shovel(diancai_spot[i])


@RunningInThread
def DianCai():
    Card("保护伞", (1, 8))
    Card("胆小", (2, 8))
    Card("阳光", (5, 8))
    Card("小喷", (6, 8))
    Delay(10)
    Shovel((1, 8))
    Shovel((2, 8))
    Shovel((5, 8))
    Shovel((6, 8))


@RunningInThread
def TallNutKeeper(spots):
    """
    泳池水路 7/8 列临时高坚果阻挡海豚.
    残血或被偷后自动补, 两行均有时中场种伞保护, 关底大波刷出后停止运行.
    @参数 spots(list[(int, int)]): 坐标.
    示例:
    >>> TallNutKeeper([(3, 7)])
    >>> TallNutKeeper([(3, 8), (4, 8)])
    """

    slots_offset = ReadMemory("unsigned int", 0x6A9EC0, 0x768, 0x144)
    slots_count = ReadMemory("unsigned int", 0x6A9EC0, 0x768, 0x144, 0x24)

    # 睡莲/高坚果/保护伞的卡槽数组下标
    lilypad_seed = None
    tallnut_seed = None
    umbrella_seed = None
    for i in range(slots_count):
        seed_type = ReadMemory("int", slots_offset + 0x5C + i * 0x50)
        if seed_type == 16:
            lilypad_seed = i
        elif seed_type == 23:
            tallnut_seed = i
        elif seed_type == 37:
            umbrella_seed = i

    # 返回值 (bool): 当前游戏是否暂停
    def GamePaused():
        return ReadMemory("bool", 0x6A9EC0, 0x768, 0x164)

    # 返回值 (int): 游戏界面
    def GameUI():
        return ReadMemory("int", 0x6A9EC0, 0x7FC)

    # 返回值 (int): 已刷新波数
    def CurrentWave():
        return ReadMemory("int", 0x6A9EC0, 0x768, 0x557C)

    # 返回值 (int): 下一波刷新倒计时
    def WaveCountdown():
        return ReadMemory("int", 0x6A9EC0, 0x768, 0x559C)

    # 获取指定位置的高坚果下标, 没有返回 None
    def GetTheTallnutIndex(r, c):
        plants_count_max = ReadMemory("int", 0x6A9EC0, 0x768, 0xB0)
        plants_offset = ReadMemory("unsigned int", 0x6A9EC0, 0x768, 0xAC)
        for i in range(plants_count_max):
            plant_disappeared = ReadMemory("bool", plants_offset + 0x141 + 0x14C * i)
            plant_crushed = ReadMemory("bool", plants_offset + 0x142 + 0x14C * i)
            plant_type = ReadMemory("int", plants_offset + 0x24 + 0x14C * i)
            plant_row = ReadMemory("int", plants_offset + 0x1C + 0x14C * i)
            plant_col = ReadMemory("int", plants_offset + 0x28 + 0x14C * i)
            if (not plant_disappeared and not plant_crushed \
            and plant_type == 23 and plant_row == (r - 1) and plant_col == (c - 1)):
                return i

    # 更新高坚果
    def UpdateTallnut(r, c):
        slots_offset = ReadMemory("unsigned int", 0x6A9EC0, 0x768, 0x144)
        seed_usable = ReadMemory("bool", slots_offset + 0x70 + tallnut_seed * 0x50)  # 该卡片是否可用
        seed_cost = ReadMemory("int", 0x69F2C0 + 23 * 0x24)  # 卡片价格
        sun = ReadMemory("int", 0x6A9EC0, 0x768, 0x5560)  # 当前阳光
        if seed_usable and sun >= seed_cost:
            while GamePaused():
                Delay(1)
            Card("高坚果", (r, c))

    # 开场种
    Delay(800)  # TODO 让给存冰位先
    for spot in spots:
        while GamePaused():
            Delay(1)
        Card("睡莲", spot)
        Card("高坚果", spot)
        if spot != spots[-1]:  # 不是最后一个
            Delay(3000 + 1)
    Delay(1)

    # 保护伞状态, 种植于第一个高坚果前一列
    umbrella_planted = False  # 已经种植
    umbrella_shoveled = False  # 已经铲除
    umbrella_row, umbrella_col = spots[0][0], spots[0][1] + 1

    # 主循环, 第 20 波刷新前持续运行
    while GameUI() == 3 and CurrentWave() < 20:

        # 两列均有高坚果时, 第 10 波刷新前种伞, 第 11 波铲掉
        if len(spots) == 2 and umbrella_seed is not None:
            if not umbrella_planted and 9 <= CurrentWave() <= 10 and WaveCountdown() <= 600:
                while GamePaused():
                    Delay(1)
                # print("Planting Umbrella Leaf to protect 2 Tall-nuts.")
                Card("睡莲", (umbrella_row, umbrella_col))
                Card("伞叶", (umbrella_row, umbrella_col))
                umbrella_planted = True
            elif not umbrella_shoveled and CurrentWave() >= 11:
                while GamePaused():
                    Delay(1)
                # print("Shovel Umbrella Leaf.")
                Shovel((umbrella_row, umbrella_col))
                Shovel((umbrella_row, umbrella_col))
                umbrella_shoveled = True

        # 遍历指定要种植高坚果的格点
        for spot in spots:
            row, col = spot
            index = GetTheTallnutIndex(row, col)  # 获取该格点的高坚果下标
            if index is None:
                # 没有则补种高坚果
                UpdateTallnut(row, col)
                Delay(3000 + 1)
            else:
                plants_offset = ReadMemory("unsigned int", 0x6A9EC0, 0x768, 0xAC)
                plant_hp = ReadMemory("int", plants_offset + 0x40 + 0x14C * index)
                if plant_hp < 2000:
                    # 血量低于一定值则修复高坚果
                    UpdateTallnut(row, col)
                    Delay(3000 + 1)

        Sleep(100)  # 每 1s 检测一次


###
###
###

SetZombies(["普僵", "撑杆", "舞王", "冰车", "海豚", "矿工", "跳跳", "蹦极", "扶梯", "篮球", "白眼", "红眼"])

SelectCards(["咖啡豆", "寒冰菇", "复制冰", "睡莲", "高坚果", "樱桃", "保护伞", "胆小", "阳光", "小喷"])

# UpdatePaoList([
#     (1, 1), (2, 1), (5, 1), (6, 1), \
#     (1, 3), (2, 3), (5, 3), (6, 3), \
#     (1, 6), (2, 6), (3, 6), (4, 6), (5, 6), (6, 6), \
#     ])

while ReadMemory("int", 0x6A9EC0, 0x7FC) != 3:  # 还没进入战斗界面
    Sleep(1)
while ReadMemory("bool", 0x6A9EC0, 0x768, 0x164):  # 处于暂停状态
    Sleep(1)
Card("睡莲", (3, 3))  # 临时存冰位

AutoCollect()  # 自动收集资源
IceSpots([(1, 5), (6, 5), (3, 3)], 13)
TallNutKeeper([(3, 8), (4, 8)])

for wave in range(1, 21):
    print("当前操作波次: " + str(wave))

    if wave in (1, ):
        Prejudge(-95, wave)
        Pao((2, 9), (5, 9))
        Delay(110)
        Pao((1, 7.7), (5, 7.7))

    elif wave in (2, 10):
        Prejudge(-15, wave)
        Pao((2, 9), (5, 9))
        Until(-15 + 107)
        Pao((1, 7.625), (5, 7.625))
        if wave == 10:
            Until(-15 + 373 - 100)
            Card("樱桃", (2, 9))  # A
        Until(601 + 20 - 298)  # 20cs 预判冰
        Coffee()

    elif wave in (3, 6, 9, 11, 14, 17):  # I-PPdd
        Prejudge(1300 - 200 - 373, wave)
        Pao((2, 8.8), (5, 8.8))
        Until(1300 + 20 - 298)  # 20cs 预判冰
        Coffee()
        Until(1300 - 200 - 373 + 350)  # 减速尾炸
        Pao((1, 2.4), (5, 2.4))
        if wave == 9:
            Until(1300 + 180)
            Pao((1, 7.2), (5, 7.2))  # 可省略
            Until(1300 + 1662 - 200 - 373)
            Pao((2, 8.8), (5, 8.8))
            Delay(81)
            DianCai()
            Delay(220 - 81)
            Pao((1, 7.8), (5, 7.8))
            Skip(4)

    elif wave in (4, 7, 12, 15, 18):  # IPP-PPDDC
        Prejudge(180, wave)
        Pao((1, 7.2), (5, 7.2))
        Until(1662 - 200 - 373)
        Pao((2, 8.8), (5, 8.8))
        Delay(81)
        DianCai()
        Delay(220 - 81)
        Pao((1, 7.4), (5, 7.4))  # 左移

    elif wave in (5, 8, 13, 16, 19):  # PPDD
        Prejudge(-15, wave)
        Pao((2, 9), (5, 9))
        Until(-15 + 107)
        Pao((1, 7.625), (5, 7.625))
        Until(601 + 20 - 298)  # 20cs 预判冰
        Coffee()
        if wave == 19:
            Until(601 + 1300 - 200 - 373)
            Delay(100)  # 尾炸炮时机微调
            Pao((2, 8.8), (5, 8.8))
            Delay(220)
            Pao((1, 7.8), (5, 7.8))
            Skip(3)

    elif wave in (20, ):
        Prejudge(-150, wave)
        Pao((4, 7))
        Until(-60)
        Pao((1, 9), (2, 9), (5, 9), (6, 9))
        Delay(108)
        Pao((1, 9), (2, 9), (5, 9), (6, 9))