# GESP等级：一级 | GESP Python 一级考点
"""
第5课：抬笔落笔——乌龟会轻功
GESP考点：#6 画笔控制(penup/pendown)
------------------------------------------------------------
知识点：
  1. t.penup()  —— 抬笔（不画线）
  2. t.forward() —— 移动（抬笔时就是"跳"）
  3. t.pendown() —— 落笔（继续画线）
  4. t.pensize() —— 加粗画笔
  5. t.color()   —— 换颜色

口诀：
  抬脚 = penup，不画线
  落脚 = pendown，画线
  忘了落笔 = 后面全白画
"""

import turtle

t = turtle.Turtle()
t.speed(3)
t.pensize(3)

# ============================================================
# 【演示1】抬笔与落笔的基本效果 —— 画两个分离的圆
# ============================================================
def demo_separated_circles():
    """展示 penup → forward → pendown → circle 的完整流程"""

    t.color("blue")

    # 1. 落笔画第一个圆（默认就是落笔状态）
    t.pendown()
    t.circle(30)          # 画一个半径为30的圆
    t.write("第1个圆", font=("SimHei", 12))

    # 2. 抬笔 → 跳到右边
    t.penup()             # ✨ 抬笔：移动时不留痕迹
    t.forward(100)        # "跳"到新位置
    t.pendown()           # ✨ 落笔：恢复画线

    # 3. 落笔画第二个圆
    t.color("red")
    t.circle(30)
    t.write("第2个圆（跳过来的）", font=("SimHei", 12))

    t.penup()
    t.goto(-50, -100)
    t.pendown()


# ============================================================
# 【演示2】故意犯错 —— 忘了 pendown 会怎样？
# ============================================================
def demo_forgot_pendown():
    """展示忘记落笔的后果：画了但啥也看不见"""

    t.color("green")

    t.penup()             # 抬笔
    t.forward(60)         # 跳
    # !!! 忘了写 t.pendown() !!!
    t.circle(25)          # 想画圆，但因为笔还抬着，什么也没有

    t.write("咦？圆呢？", font=("SimHei", 14, "normal"))

    # 正确的做法
    t.pendown()
    t.circle(25)
    t.write("这里才是对的！", font=("SimHei", 12))

    t.penup()
    t.goto(-50, -200)
    t.pendown()


# ============================================================
# 【演示3】组合拳：画三个分离的正方形
# ============================================================
def demo_three_squares():
    """三个正方形，用 penup/forward/pendown 分隔"""

    colors = ["purple", "orange", "cyan"]

    for i in range(3):
        t.color(colors[i])

        # 落笔 → 画正方形
        t.pendown()
        for _ in range(4):
            t.forward(40)
            t.left(90)

        # 抬笔 → 跳到下一个位置
        t.penup()
        t.forward(80)
        # 注意：没有 pendown() —— 留着给练习填空用

    # 最后补上落笔，避免影响后续代码
    t.pendown()


# ============================================================
# 【练习1】填空补全 —— 抬笔 → 跳跃 → 落笔
# ============================================================
def practice_fill_blank():
    """
    下面这段代码不完整，请补上缺少的语句：
    - 在画每个图形之前，确保笔落下
    - 在移动之前，记得抬笔
    """
    t.color("darkgreen")
    t.pensize(4)

    # ---- 图形 A：小三角形 ----
    # 填空1：___________   # 提示：先落笔
    for _ in range(3):
        t.forward(50)
        t.left(120)

    # 填空2：___________   # 提示：抬笔，准备跳到下一个位置
    t.forward(100)

    # ---- 图形 B：小正方形 ----
    # 填空3：___________   # 提示：落笔
    for _ in range(4):
        t.forward(50)
        t.right(90)

    t.penup()
    t.goto(50, -350)
    t.pendown()

    # 参考答案写在底部注释中，做完再查看


# ============================================================
# 【练习2】画三个分离的圆（不同颜色、不同半径）
# ============================================================
def practice_three_circles():
    """
    用 penup/forward/pendown 画出三个彼此分离的圆。
    要求：
      - 圆1：红色，半径 20
      - 圆2：蓝色，半径 35
      - 圆3：绿色，半径 50
      - 每个圆之间用抬笔移动 80 像素
    """
    circles = [("red", 20), ("blue", 35), ("green", 50)]

    # 请补全以下循环体
    for color_name, radius in circles:
        pass  # 在这里补 your code！
        # 提示步骤：
        #   1. t.color(color_name)
        #   2. t.pendown()
        #   3. t.circle(radius)
        #   4. t.penup()
        #   5. t.forward(80)
        # （最后一个圆后面可以不 forward）


# ============================================================
# 【练习3】跳格子 —— 用 penup 跳过"障碍"
# ============================================================
def practice_jump_grid():
    """
    场景：地面上有一些障碍格子。
    规则：
      - 遇到障碍（灰色方块）时要用 penup 跳过
      - 在空地上要落笔画线
    难度：★☆☆☆☆
    """

    # 画一个 5×1 的路线，第2格和第4格是障碍
    obstacles = [False, True, False, True, False]  # True = 障碍

    t.pensize(6)
    t.color("black")

    for i, is_obstacle in enumerate(obstacles):
        cell_x = i * 60  # 每格 60 像素

        if is_obstacle:
            # ---- 障碍格：不画线，跳过去 ----
            # 填空：使用 penup 抬笔
            t.forward(60)
            # 填空：这里应该写什么？想清楚再填！
        else:
            # ---- 空地格：画线走过去 ----
            # 填空：使用 pendown 落笔
            t.forward(60)

        # 在格子中间标记编号
        t.penup()
        t.backward(30)
        t.write(f"格{i+1}", font=("SimHei", 10))
        t.forward(30)

    t.penup()
    t.goto(-100, -420)
    t.pendown()


# ============================================================
# ★ 挑战题（学有余力者）：画虚线
# ============================================================
def challenge_dashed_line():
    """
    用 penup/pendown 交替画出虚线。
    规律：落笔画一段 → 抬笔跳一段 → 落笔画一段 → 抬笔跳一段…
    """
    t.color("gray")
    t.pensize(4)

    for i in range(10):
        t.pendown()
        t.forward(15)    # 画线段
        t.penup()
        t.forward(10)    # 跳过间隙

    t.write("虚线 = penup / pendown 交替", font=("SimHei", 14))

    t.hideturtle()


# ============================================================
# 主程序入口 —— 按顺序执行各个演示和练习
# ============================================================
if __name__ == "__main__":
    demo_separated_circles()
    demo_forgot_pendown()
    demo_three_squares()

    # 练习部分需要学生手动补全后取消注释运行
    # practice_fill_blank()
    # practice_three_circles()
    # practice_jump_grid()
    # challenge_dashed_line()

    turtle.done()


"""
参考答案（做完前不要偷看哦！）
-------------------------------
【练习1 填空1】t.pendown()
【练习1 填空2】t.penup()
【练习1 填空3】t.pendown()

【练习2 循环体】
    t.color(color_name)
    t.pendown()
    t.circle(radius)
    t.penup()
    t.forward(80)

【练习3 障碍格】
    t.penup()          # 抬笔跳过障碍
    t.forward(60)
    t.pendown()        # 别忘了落笔！不然空地也画不了

【练习3 空地格】
    t.pendown()        # 默认已落笔，但写上更安全
    t.forward(60)
"""
