使用mu编辑器 + pgzero编写拼图小游戏
python
import random
SIZE = 96 # 设置每张图块的大小
WIDTH = SIZE * 3 # 根据土块大小设置窗口
HEIGHT = SIZE * 3
pics = [] # 存放图块
finished = False # 游戏结束标识
# 将前八张图块存放在pics列表中
for i in range(8):
# 使用Actor()方法创建图块
pic = Actor("puzzle_pic" + str(i))
# 给每张图块设置索引值
pic.index = i
pics.append(pic)
# 将图块列表pics的顺序打乱
random.shuffle(pics)
# 设立每块图块的初始位置
for i in range(8):
# 使用余数确认x坐标,如0、3、6余数为0,所以都在第一列
pics[i].left = i % 3 * SIZE
# 使用除数确认y坐标,如0、1、2除以3整数部分都为0,所以在第一行
pics[i].top = i // 3 * SIZE
# 创建最后一张图块,固定放置在最后一个位置
lastpic = Actor("puzzle_pic8")
lastpic.left = 2 * SIZE
lastpic.top = 2 * SIZE
def draw():
# 设置游戏背景色
screen.fill((255,255,255))
# 绘制图块
for pic in pics:
pic.draw()
# 如果游戏结束,则将最后一张图块绘制进游戏中
if finished:
lastpic.draw()
# 显示结束语
screen.draw.text("victory!",center = (WIDTH // 2, HEIGHT // 2),
fontsize = 50, color = "red")
# 鼠标点击处理
def on_mouse_down(pos):
if finished:
return
# 获取被点击位置的坐标
grid_x = pos[0] // SIZE
grid_y = pos[1] // SIZE
# 检测是否存在图块
thispic = get_pic(grid_x,grid_y)
# 不存在,则return,不执行任何存在
if thispic == None:
return
# 存在,则判断其相邻位置是否为空,如为空,则移动图块至空位
if grid_y> 0 and get_pic(grid_x,grid_y - 1) == None:
thispic.y -= SIZE
return
if grid_y< 2 and get_pic(grid_x,grid_y + 1 ) == None:
thispic.y += SIZE
return
if grid_x> 0 and get_pic(grid_x - 1,grid_y) == None:
thispic.x -= SIZE
return
if grid_x< 2 and get_pic(grid_x + 1,grid_y) == None:
thispic.x += SIZE
return
# 通过坐标获取图块信息
def get_pic(grid_x,grid_y):
# 循环遍历图块判断是否有图块在对应坐标中
for pic in pics:
if pic.x // SIZE == grid_x and pic.y // SIZE == grid_y:
return pic
return None
def update():
global finished
if finished:
return
# 遍历前八个坐标位置,判断位置上的图块是否符合需求
for i in range(8):
# 获取坐标位置上的图块信息
pic = get_pic(i % 3 ,i// 3)
# 如果不存在图块或者图块索引值不对,则return
if (pic == None or pic.index != i):
return
# 游戏结束
finished = True
# 设置胜利
sounds.win.play()
代码执行,便会生成3x3拼图小游戏
完成拼图后
但是,因为是使用随机数Random无规则的打乱顺序,所以会导致游戏存在无解的情况
所以放弃采用random.shuffle(pics)
打乱图块的方法,改为程序多次自动随机点击空图块相邻的图块,实现打乱图块效果
python
# 将图块列表pics的顺序打乱
# random.shuffle(pics)
blank_pic = [2,2] # 初始空白图块的坐标
# 逆向打乱拼图顺序
def init_pics():
global blank_pic
move_list = []
# 将空白图块相邻的图块位置插入列表中
if blank_pic[0] > 0:
move_list.append([blank_pic[0] - 1,blank_pic[1]])
if blank_pic[0] < 2:
move_list.append([blank_pic[0] + 1,blank_pic[1]])
if blank_pic[1] > 0:
move_list.append([blank_pic[0],blank_pic[1] - 1])
if blank_pic[1] < 2:
move_list.append([blank_pic[0],blank_pic[1] + 1])
# 从列表中随机一个图块进行点击
blank_pic = random.choice(move_list)
on_mouse_down([blank_pic[0] * SIZE,blank_pic[1] * SIZE])
最后,根据自己的设定,循环调用init_pics
方法,实现打乱效果
python
for i in range(50):
init_pics()
运行结果如图,也是实现了随机打乱图块的效果,且不会出现无解的情况
调整优化:
SUM_X
,SUM_Y
:可设置拼图难度,生成m*n拼图random_num
:设置系统打乱方块的步数
python
# 在这里写上你的代码
import random
SUM_X = 4 # 设置每行存放图块的数量
SUM_Y = 3 # 设置每列存放图块的数量
random_num = 100 # 打乱方块次数
SIZE = 96 # 设置每张图块的大小
SUM_I = SUM_X * SUM_Y # 图块总数
WIDTH = SIZE * SUM_X # 根据土块大小设置窗口
HEIGHT = SIZE * SUM_Y
pics = [] # 存放图块
finished = False # 游戏结束标识
blank_pic = [SUM_X - 1,SUM_Y - 1] # 空白图块坐标
# 将显示图块存放在pics列表中
for i in range(SUM_I - 1):
# 使用Actor()方法创建图块
pic = Actor("puzzle_pic" + str(i))
# 给每张图块设置索引值
pic.index = i
pics.append(pic)
# 设立每块图块的初始位置
for i in range(SUM_I - 1):
# 使用余数确认x坐标
pics[i].left = i % SUM_Y * SIZE
# 使用除数确认y坐标
pics[i].top = i // SUM_X * SIZE
# 创建最后一张图块,固定放置在最后一个位置
lastpic = Actor("puzzle_pic8")
lastpic.left = SUM_X * SIZE
lastpic.top = SUM_Y * SIZE
def draw():
# 设置游戏背景色
screen.fill((255,255,255))
# 绘制图块
for pic in pics:
pic.draw()
# 如果游戏结束,则将最后一张图块绘制进游戏中
if finished:
lastpic.draw()
# 显示结束语
screen.draw.text("victory!",center = (WIDTH // 2, HEIGHT // 2),
fontsize = 50, color = "red")
# 鼠标点击处理
def on_mouse_down(pos):
if finished:
return
# 获取被点击位置的坐标
grid_x = pos[0] // SIZE
grid_y = pos[1] // SIZE
# 检测是否存在图块
thispic = get_pic(grid_x,grid_y)
# 不存在,则return,不执行任何存在
if thispic == None:
return
# 存在,则判断其相邻位置是否为空,如为空,则移动图块至空位
if grid_y> 0 and get_pic(grid_x,grid_y - 1) == None:
thispic.y -= SIZE
return
if grid_y< (SUM_Y - 1) and get_pic(grid_x,grid_y + 1 ) == None:
thispic.y += SIZE
return
if grid_x> 0 and get_pic(grid_x - 1,grid_y) == None:
thispic.x -= SIZE
return
if grid_x< (SUM_X - 1) and get_pic(grid_x + 1,grid_y) == None:
thispic.x += SIZE
return
# 通过坐标获取图块信息
def get_pic(grid_x,grid_y):
# 循环遍历图块判断是否有图块在对应坐标中
for pic in pics:
if pic.x // SIZE == grid_x and pic.y // SIZE == grid_y:
return pic
return None
def update():
global finished
if finished:
return
# 遍历前八个坐标位置,判断位置上的图块是否符合需求
for i in range(SUM_I - 1):
# 获取坐标位置上的图块信息
pic = get_pic(i % SUM_X ,i// SUM_Y)
# 如果不存在图块或者图块索引值不对,则return
if (pic == None or pic.index != i):
return
# 游戏结束
finished = True
# 设置胜利
sounds.win.play()
# 逆向打乱拼图顺序
def init_pics():
global blank_pic
move_list = []
if blank_pic[0] > 0:
move_list.append([blank_pic[0] - 1,blank_pic[1]])
if blank_pic[0] < SUM_X - 1:
move_list.append([blank_pic[0] + 1,blank_pic[1]])
if blank_pic[1] > 0:
move_list.append([blank_pic[0],blank_pic[1] - 1])
if blank_pic[1] < SUM_Y - 1:
move_list.append([blank_pic[0],blank_pic[1] + 1])
# 从列表中随机一个移动方法
blank_pic = random.choice(move_list)
on_mouse_down([blank_pic[0] * SIZE,blank_pic[1] * SIZE])
for i in range(random_num):
init_pics()
因为图块是随机打乱的,我们无法确认随机出来的图块会不会跟没打乱的图块一致,出现一进游戏就获胜的情况,但这我们可以加代码去判定,比较简单,所以就不阐述了