用Python海龟库实现记忆配对游戏:从基础到进阶
记忆配对游戏(Memory Puzzle)是一款经典的训练记忆力的小游戏。玩家需要通过翻牌找出所有匹配的图案对。本文将详细解析如何使用Python的 turtle 库实现这个游戏,并探讨几种有趣的改进方案。
游戏基本原理
游戏的核心逻辑很简单:
- 游戏板由隐藏的卡片组成,每张卡片背后是一个数字(或图案)
- 玩家每次翻开两张卡片
- 如果两张卡片匹配,则保持翻开状态
- 如果不匹配,卡片会再次隐藏
- 目标是用最少的点击次数找出所有匹配对
小贴士: 记忆配对游戏不仅能锻炼记忆力,还能提高观察力和策略思维能力,适合各个年龄段的玩家。
代码实现解析
下面是基于 turtle 库实现的记忆配对游戏代码:
"""Memory, puzzle game of number pairs.
Exercises:
1. Count and print how many taps occur.
2. Decrease the number of tiles to a 4x4 grid.
3. Detect when all tiles are revealed.
4. Center single-digit tile.
5. Use letters instead of tiles.
"""
from random import *
from turtle import *
from freegames import path
car = path('car.gif')
tiles = list(range(32)) * 2
state = {'mark': None}
hide = [True] * 64
def square(x, y):
"""Draw white square with black outline at (x, y)."""
up()
goto(x, y)
down()
color('black', 'white')
begin_fill()
for count in range(4):
forward(50)
left(90)
end_fill()
def index(x, y):
"""Convert (x, y) coordinates to tiles index."""
return int((x + 200) // 50 + ((y + 200) // 50) * 8)
def xy(count):
"""Convert tiles count to (x, y) coordinates."""
return (count % 8) * 50 - 200, (count // 8) * 50 - 200
def tap(x, y):
"""Update mark and hidden tiles based on tap."""
spot = index(x, y)
mark = state['mark']
if mark is None or mark == spot or tiles[mark] != tiles[spot]:
state['mark'] = spot
else:
hide[spot] = False
hide[mark] = False
state['mark'] = None
def draw():
"""Draw image and tiles."""
clear()
goto(0, 0)
shape(car)
stamp()
for count in range(64):
if hide[count]:
x, y = xy(count)
square(x, y)
mark = state['mark']
if mark is not None and hide[mark]:
x, y = xy(mark)
up()
goto(x + 2, y)
color('black')
write(tiles[mark], font=('Arial', 30, 'normal'))
update()
ontimer(draw, 100)
shuffle(tiles)
setup(420, 420, 370, 0)
addshape(car)
hideturtle()
tracer(False)
onscreenclick(tap)
draw()
done()
代码核心组件分析
1. 初始化与数据结构
- 游戏素材:使用
freegames库中的汽车图片作为背景 - 游戏数据:
tiles:存储64个数字(0 - 31各两个)state:记录当前选中的卡片hide:布尔数组,记录每张卡片是否隐藏
2. 图形绘制函数
square(x, y):绘制单个白色方块(卡片背面)index(x, y):将屏幕坐标转换为卡片索引xy(count):将卡片索引转换为屏幕坐标
3. 游戏逻辑函数
tap(x, y):处理鼠标点击事件- 计算点击位置对应的卡片索引
- 判断是否形成匹配对
- 更新卡片隐藏状态
draw():绘制游戏界面- 清除当前画面
- 绘制背景图片
- 绘制所有未匹配的卡片
- 显示当前选中的卡片内容
- 设置定时器,实现动画效果
4. 游戏控制流程
- 随机打乱卡片顺序
- 设置游戏窗口和画布
- 注册鼠标点击事件处理函数
- 启动游戏主循环
进阶改进方案
原代码中列出了5个练习,这些改进可以提升游戏体验:
1. 统计点击次数
# 添加点击计数器
tap_count = 0
def tap(x, y):
global tap_count
tap_count += 1 # 每次点击增加计数
# 原有的点击处理逻辑...
# 在draw()函数中添加显示计数
up()
goto(-190, 190) # 左上角位置
color('red')
write(f'Taps: {tap_count}', font=('Arial', 16, 'normal'))
2. 缩小游戏板为4x4
# 修改初始化部分
tiles = list(range(8)) * 2 # 4x4需要8对数字
hide = [True] * 16 # 16张卡片
# 修改坐标转换函数
def index(x, y):
return int((x + 100) // 50 + ((y + 100) // 50) * 4)
def xy(count):
return (count % 4) * 50 - 75, (count // 4) * 50 - 75
# 修改窗口大小
setup(350, 350, 370, 0)
3. 检测游戏胜利条件
def is_game_over():
return all(not h for h in hide)
def draw():
# 原有绘制逻辑...
# 检查游戏是否结束
if is_game_over():
up()
goto(0, 0)
color('blue')
write('You Win!', align='center', font=('Arial', 36, 'bold'))
return # 停止绘制循环
update()
ontimer(draw, 100)
4. 居中显示数字
def draw():
# 原有逻辑...
if mark is not None and hide[mark]:
x, y = xy(mark)
up()
# 根据数字位数调整位置
num = tiles[mark]
x_offset = 2 if num >= 10 else 15 # 两位数偏移2,一位数偏移15
goto(x + x_offset, y + 10) # 垂直方向也微调
color('black')
write(num, font=('Arial', 30, 'normal'))
5. 使用字母代替数字
# 修改tiles初始化
import string
tiles = list(string.ascii_uppercase[:8]) * 2 # 使用A - H的字母
注意: 在实现这些改进时,请确保理解每处修改的原理,避免引入新的错误。建议一次只实现一个改进,并充分测试后再进行下一个。
总结
这个记忆配对游戏展示了如何利用Python的 turtle 库创建简单而有趣的交互式应用。通过分析代码结构,我们可以看到游戏开发的基本模式:
- 数据结构设计(存储游戏状态)
- 图形绘制(界面渲染)
- 用户交互处理(鼠标/键盘事件)
- 游戏逻辑控制(状态更新与判断)
通过实现进阶改进,我们不仅提升了游戏体验,还学习了如何扩展现有代码。这种逐步迭代的开发方式是游戏编程中的常见模式。
你可以进一步发挥创意,添加更多功能,如计时系统、难度级别、音效反馈等,让游戏更加丰富多彩!
扩展思考: 尝试将游戏打包为可执行文件,或者移植到网页上使用JavaScript实现,这些都是很好的学习项目!