sairate 2cd753d3d9 feat(第7讲 字母卡牌): 实现记忆游戏并添加开始界面
- 新增 jiyi.py 文件,实现字母翻牌记忆游戏功能
- 添加 youxijiemian.py 文件,创建游戏开始界面
- 使用 turtle 和 tkinter 模块分别实现游戏和界面
- 支持选择不同难度的游戏模式
2025-06-29 09:06:19 +08:00

167 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import turtle
import random
import time
import string
def start_game(rows=8, cols=8):
SIZE = 80
COUNT = rows * cols
WIDTH, HEIGHT = cols * SIZE, rows * SIZE
# 初始化画布和窗口(上方留出按钮空间)
screen = turtle.Screen()
screen.setup(WIDTH + 40, HEIGHT + 80) # 上方多出40像素放按钮
screen.bgcolor('white')
screen.title("字母翻牌游戏")
# 注册字母图片(这里默认没有图片)
for ch in string.ascii_uppercase:
try:
turtle.addshape(f"{ch}.gif")
except:
pass
# 生成牌面内容
tiles = random.sample(string.ascii_uppercase * 2, COUNT // 2) * 2
random.shuffle(tiles)
# 卡片是否隐藏
hide = [True] * COUNT
# 游戏状态
state = {
'mark': None,
'matched_pair': None,
'reveal': None
}
# 卡片乌龟
turtles = [turtle.Turtle() for _ in range(COUNT)]
for t in turtles:
t.hideturtle()
t.penup()
# 公共画笔
pen = turtle.Turtle()
pen.hideturtle()
pen.penup()
# 返回按钮乌龟
back_btn = turtle.Turtle()
back_btn.hideturtle()
back_btn.penup()
def draw_back_button():
back_btn.goto(-WIDTH // 2, HEIGHT // 2 + 10)
back_btn.color("black", "lightgray")
back_btn.begin_fill()
for _ in range(2):
back_btn.forward(100)
back_btn.left(90)
back_btn.forward(40)
back_btn.left(90)
back_btn.end_fill()
back_btn.goto(-WIDTH // 2 + 20, HEIGHT // 2 + 15)
back_btn.write("返回", font=("Arial", 16, "bold"))
def check_back_button(x, y):
bx1, by1 = -WIDTH // 2, HEIGHT // 2 + 10
bx2, by2 = bx1 + 100, by1 + 40
return bx1 <= x <= bx2 and by1 <= y <= by2
def go_back_to_menu():
screen.bye()
import youxijiemian
youxijiemian.show_start_window()
# 你可以在这里调用 Tkinter 菜单例如show_start_window()
def xy(i):
x = -WIDTH // 2 + (i % cols) * SIZE
y = -HEIGHT // 2 + (i // cols) * SIZE
return x, y
def index(x, y):
col = int((x + WIDTH // 2) // SIZE)
row = int((y + HEIGHT // 2) // SIZE)
i = row * cols + col
if 0 <= i < COUNT:
return i
return None
def draw():
pen.clear()
for i in range(COUNT):
x, y = xy(i)
t = turtles[i]
t.goto(x + SIZE // 2, y + SIZE // 2)
if not hide[i]:
t.hideturtle()
elif i == state.get("mark") or i == state.get("reveal") or (state.get("matched_pair") and i in state["matched_pair"]):
t.shape("square")
t.shapesize(stretch_wid=3, stretch_len=3)
t.color("black")
t.showturtle()
pen.goto(x + SIZE // 2 - 15, y + SIZE // 2 - 20)
pen.write(tiles[i], font=('Arial', 24, 'bold'))
else:
pen.goto(x, y)
pen.color('black', 'skyblue')
pen.begin_fill()
for _ in range(4):
pen.forward(SIZE - 10)
pen.left(90)
pen.end_fill()
t.hideturtle()
draw_back_button()
turtle.update()
def hide_matched():
i1, i2 = state["matched_pair"]
hide[i1] = False
hide[i2] = False
state["matched_pair"] = None
draw()
def tap(x, y):
if check_back_button(x, y):
go_back_to_menu()
return
i = index(x, y)
if i is None or not hide[i] or state.get("matched_pair"):
return
m = state.get("mark")
if m is None:
state["mark"] = i
elif m == i:
return
elif tiles[m] != tiles[i]:
state["reveal"] = i
draw()
time.sleep(0.5)
state["mark"] = None
state["reveal"] = None
else:
state["matched_pair"] = (m, i)
state["mark"] = None
state["reveal"] = None
draw()
screen.ontimer(hide_matched, 2000)
draw()
if all(not h for h in hide):
pen.goto(0, 0)
pen.color("green")
pen.write("🎉 全部配对成功!", font=('Arial', 24, 'bold'))
turtle.tracer(False)
draw()
turtle.onscreenclick(tap)
turtle.done()
# 测试入口
if __name__ == "__main__":
start_game(8, 8)