本节教程通过 2048 的小游戏快速、完整地呈现了使用 Python 语言编程的过程,将之前介绍的内容有机地结合在了一起 。2048是一款流行于手机、平板等终端设备上的益智小游戏,最早于 2014 年 3 月发行,主界面如图 1 所示。

图 1:2048 小游戏的主界面

其游戏规则是:每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢,系统也会在空白的地方随机出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。系统给予的数字方块不是 2 就是 4,玩家要想办法在这小小的 16 格范围中凑出“2048”这个数字方块。

网友总结的游戏技巧有:

  • 最大数尽可能放在角落;
  • 数字按顺序紧邻排列;
  • 首先满足最大数和次大数在的那一列/行是满的;
  • 时刻注意活动较大数(32以上)旁边要有相近的数;
  • 以大数所在的一行为主要移动方向;
  • 不要急于“清理桌面”;
  • 根据游戏规则,可以整理出游戏的流程,如图 2 所示。

图 2:2048 小游戏的主要流程

根据流程图,可以将整个游戏程序大致分为三个部分:

  1. 程序初始化;
  2. 判断用户输入;
  3. 进入游戏主循环。

其中第三部分可以继续细分为以下三个部分:

  1. 等待操作;
  2. 判断操作并处理;
  3. 重新开始或退出。

为了游戏界面效果美观,这里使用了 pygame 库。安装 pygame 库的命令如下:


1.  pip install pygame

安装过程如图 3 所示。

图 3:pygame 库安装过程

下面我们继续关注 2048 小游戏。首先来看程序初始化,这里主要完成以下工作:导入所需模块,初始化棋盘和窗口界面,初始化各种组件和变量。根据游戏规则,棋盘大小为 4×4 共 16 格的正方形棋盘,简便起见我们使用二维列表存储每个格子里的数字。

定义棋盘并初始化每个格子存储的数字的语句如下:

board = [[0, 0, 0, 0]
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]

以下语句用于初始化窗口的相关属性:

#每个格子的边长,单位:像素(下同)
box_size = 50
#格子之间的间距
box_gap = 5
#中心棋盘区域上边缘离窗口顶部的距离
top_of_window = 100
#中心棋盘区域下边缘离窗口底部的距离
bottom_of_window = 30
#中心棋盘区域左边缘离窗口左边的距离
left_of_window = 2 0
#窗口宽度
window_width = box_size * 4 + box_gap * 5 + left_of_window * 2
#窗口高度
window_height = top_of_window + box_gap * 5 + box_size * 4 + left_of_window + bottom_of_window
#初始化窗口
window = pygame.display.set_mode((window_width, window_height), 0, 32)
#窗口标题
pygame.display.set_caption("2048")
#得分
score = 0
#使用 pygame 内置颜色值定义一些颜色常量
OLDLACE = pygame.color.THECOLORS["oldlacen"]
IVORY = pygame.color.THECOLORS["ivory3"]
BLACK = pygame.color.THECOLORS["black"]
RED = pygame.color.THECOLORS["red"]
RED2 = pygame.color.THECOLORS["red2"]
DARKGOLD = pygame.color.THECOLORS["darkgoldenrodl"]
GOLD = pygame.color.THECOLORS["gold"]
GRAY = pygame.color.THECOLORS["gray41"]
CHOCOLATE = pygame.color.THECOLORS["chocolate"]
CHOCOLATE1 = pygame.color.THECOLORS["chocolate1"]
CORAL = pygame.color.THECOLORS["coral"]
CORAL2 = pygame.color.THECOLORS["coral2"]
ORANGED = pygame.color.THECOLORS["orangered"]
ORANGED2 = pygame.color.THECOLORS["orangered2"]
DARKORANGE = pygame.color.THECOLORS["darkorange"]
DARKORANGE2 = pygame.color.THECOLORS["darkorange2"]
FORESTGREEN = pygame.color.THECOLORS["forestgreen"]
#界面字体
FONTNAME = "SimHei"

绘制棋盘格子主要由 Box 类和 draw_box( ) 函数完成:

class Box:def __init__(self, topleft, text, color):self.topleft = topleftself.text = textself.color = colordef render(self, surface):x, y = self.topleft#绘制棋盘格pygame.draw.rect(surface, self.color, (xz y, box_size, box_ size))#定义棋盘格中数字的高度text_height = int(box_size * 0.35)#设置棋盘格中数字使用的字体font_obj = pygame.font.SysFont(FONTNAME, text_height)text_surface = font_obj.render(self.text, True, BLACK)text_rect = text_surface.get_rect()text_rect.center = (x + box_size / 2, y + box_size / 2)surface.blit(text_surface, text_rect)
def draw_box():giobal board#定义棋盘上每个格子中不同数字的颜色colors = {0 : (192, 192, 192) , 2 : (176, 224, 230) , 4 : (127, 255, 212), 8 : (135, 206, 235) , 16 : (64, 224, 208),32 : (0, 255, 255), 64 : (0, 201, 87), 128: (50, 205, 50), 256 : (34, 139, 34),512 : (0, 255, 127) , 1024 : (61, 145, 64), 2048 : (48, 128, 20), 4096 : (65, 105, 255),8192 : (8, 46, 84) , 16384 : (11, 23, 70), 32 768: (25, 25, 112), 65536 : (0, 0, 255) }x, y = left_of_window, top_of_windowsize = box_size * 4 + box gap * 5pygame.draw.rect(window, BLACK, (x, y, size, size))x, y = x + box_gap, y + box_gap#使用嵌套循环绘制棋盘上所有格子for i in range(4):for j in range(4):idx = board. [ i ] [ j ]if idx == 0:text =""else :text = str(idx)if idx > 65536: idx = 65536color = colors[idx]box = Box((x, y), text, color) box.render(window)x += box_size + box_gapx = left_of_window + box_gapy += box_size + box_gap

接下来需要初始化棋盘上开局的数字,来看 set_random_number( ) 函数:

def set_random_number():pool =[]for i in range(4):for j in range (4):if board[i][j] == 0:pool. append. ( (if j ))m = random.choice(pool)pool.remove(m)value = random.uniform(0, 1)if value < 0.1:value = 4else :value = 2board[m[0]][m[1]] = value

其作用是在棋盘上随机选取两个格子,将其值设置为 2 或 4。

以下代码将绘制游戏窗口其余的界面内容:

#显示游戏名称
window.blit(write ("2048", height = 45, color = GOLD), (left_of_ window, left_of_window // 2))
#显示当前得分
window.blit(write("得分", height=14, color=FORESTGREEN), (left_of_window+105, left_of_window//2 + 5))
rect1 = pygame.draw.rect(window, FORESTGREEN, (left_of_window+100, left_of_window//2 + 30, 60, 20))
text1 = write(str(score), height=14, color=GOLD)
text1_rect = text1.get_rect()
text1_rect.center = (left_of_window+100+30, left_of_window//2 + 40)
window.blit(textlf textl_rect)
#显示历史最高分
window.blit(write("最高", height=14, color=FORESTGREEN), (left_of_window+175, left_of_window//2 + 5))
rect2 = pygame.draw.rect(window, FORESTGREEN, (left_of_window+165, left_of_window//2 + 30, 60, 20))
#读取历史最高分
best = read_best()
if best < score:best = score
text2 = write(str(best), height=14, color=GOLD)
text2_rect = text2.get_rect()
text2_rect.center = (left_of_window+165+30, left_of_window//2 + 40)
window.blit(text2, text2_rect)
#显示游戏操作提示
window.blit(write("使用上下左右方向键控制", height=16, color=GRAY), (left_of_window, window_height - bottom_of_Window))

判断用户操作并处理是通过无限循环完成的,代码如下:

while True:#通过事件机制获取当前用户操作for event in pygame.event.get():#用户操作为退出窗口或按下ESC键时写入最高分,并退出游戏窗口if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):write_best(best)pygame.quit ()exit ()#游戏没有正常结束时监听用户的操作elif not gameover:#用户按下键盘上的向上方向键if event.type == KEYUP and event.key == K_UP:up()#用户按下键盘上的向下方向键   elif event.type ==KEYUP and event.key == K DOWN:down()    #用户按下键盘上的向左方向键    elif event.type ==KEYUP and event.key == K_LEFT:left ()    # 用户按下键盘上的向右方向键    elif event.type ==KEYUP and event.key == K_ RHGHT:right ()#开始新游戏if newboard != board:set_random_number()newboard = deepcopy(board) draw_box()gameover = is_over()rect1 = pygame.draw.rect(window, FORESTGREEN,(left_ of_window+100, left_of_window//2 + 30, 60, 20))text1 = write(str(score), height=14, color=GOLD)text_rect = text1.get_rect()text_rect.center = (left_of_window+100+30Aleft_of_window//2 + 4 0)window.blit(text1, text_rect)rect2 = pygame.draw.rect(window, FORESTGREEN, (left_of_window+165, left_of_window//2 + 30, 60, 20))if best < score:best = scoretext2 = write(str(best), height=14, color=GOLD)text2_rect = text2.get_rect()text2_rect.center = (left_of_window+l65+30, left_of_window//2 + 4 0)window.blit(text2, text2_rect)#游戏正常结束(即用户合成了 2048或未合成2048但棋盘上已经无法继续下一步操作)else :write_best(best)window.blit(write("游戏结束! ", height = 40, color = FORESTGREEN), (left_of_windowz window_height // 2))

为了实现游戏效果,还有几个关键函数需要定义:一是对棋盘上的数字求和,用于当用户按下上下左右操作键后合并棋盘上的数字,代码如下:

def combinate(L):glbal scoreans = [0, 0, 0 , 0]num =[]for i in L:if i != 0:num. append. (i)length = len(num)
#当不为0的数字有4个时if length == 4:if num[0] == num[1]:ans[0] = num[0] + num[1]score += ans[0]if num[2] == num[3]:ans[1] = num[2] + num [3]score += ans[1]else :ans[1]=num[2]ans [2]=num[3]elif num[1] ==num[2]ans [0]= num[0] ans[1]= num[1] + num[2]ans [2]= num[3] score += ans[1] elif num[2] ==num[3]ans [ 0]= num[0] ans[1]= num[1] ans [2]= num[2] + num[3]score += ans[2] else :  for i in range(length): ans[i] = num[i]
#当不为0的数字有3个时elif length == 3:if num[0] == num[1]:ans[0] = num[0] + num[1]ans[1] = num[2]score += ans[0]elif num[1] == num[2]:ans [0] = num[0]ans[1]=num[1] + num[2]score += ans[1]else :for i in range(length):ans[i] = num[i]
#当不为0的数字有2个时elif length == 2:if num[0] == num[1]:ans[0] = num[0] + num[1]score += ans[0]else :for i in range(length):ans[i] = num[i]
#当不为0的数字只有1个时elif length == 1:ans[0] = num[0]else :passreturn ans

二是用户按下上下左右控制键后对应的操作,需要注意的是,我们定义存放棋盘上数字的列表是行式二维列表,故处理左右键相对容易,只需对左右相邻的数字判断是否应该合并即可,而处理上下键时则需要按照对应的列找到目标数字,再判断是否应该合并。最后,如果你的时间不是很紧张,并且又想快速的python提高,最重要的是不怕吃苦,建议你可以架尉♥信(同音):276 3177 065 ,那个真的很不错,很多人进步都很快,需要你不怕吃苦哦!大家可以去添加上看一下~,包括小编自己整理的一份2022最新的Python资料和0基础入门教程,欢迎初学和进阶中的小伙伴。在不忙的时间我会给大家解惑

代码如下:

def left():for i in range(4):temp = combinate (boa:rd [ i ])for j in range (4):board[i][j] = temp[j]
def right():for i in range(4):temp = combinate (boaird[i][::-1]for j in range (4):board[i][3-j] = temp[j]
def up():for i in range(4):to_comb =[]for j in range (4):to_comb.append(board[j][i])temp = combinate(to_comb)for k in range(4):board[k][i] = temp[k]
def down():for i in range(4):to_comb =[]for j in range (4):to_comb.append(board[3-j][i])temp = combina.te(to_comb)for k in range (4):board[3-k][i] = temp[k]

三是判断游戏是否结束的函数 is_over( )。按照游戏规则,当棋盘上仍然存在空格,或是同一行/列存在相邻且相同的数字时,游戏方可继续进行,否则游戏结束,该函数可做如下定义:

def is_over():
#棋盘上仍然存在空格for i in range(4):for j in range(4):if board[i][j]==0:return False
#同一行中存在相邻且相同的数字for i in range(4):for j in range(3):if board[i][j] == board[i][j+1]:return False
#同一列中存在相邻且相同的数字for i in range(3):for j in range(4):if board[i][j] == board[i+1][j]:return Falsereturn True

至此,小游戏 2048 的主要内容和关键代码介绍完毕。

【python教程入门学习】Python实例:小游戏2048相关推荐

  1. [python教程入门学习]Python标准库映射类型与可散列数据类型的关系

    本文章向大家介绍Python标准库映射类型与可散列数据类型的关系,主要包括Python标准库映射类型与可散列数据类型的关系使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋 ...

  2. [python教程入门学习]python学习笔记(CMD执行文件并传入参数)

    本文章向大家介绍python学习笔记(CMD执行文件并传入参数),主要包括python学习笔记(CMD执行文件并传入参数)使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋 ...

  3. [python教程入门学习]Python是什么?

    Python 是一种高级计算机编程语言,作者是荷兰人吉多·范罗苏姆.在 1989 年圣诞节期间,吉多打算开发一种新的脚本语言,用来取代 ABC 语言,就这样,一门新的编程语言 Python 诞生了. ...

  4. 【python教程入门学习】Python扑克牌21点游戏实例代码

    大家好,本篇文章主要讲的是Python扑克牌21点游戏实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览 废话还是说太多了 直接上代码 | `import` `random ...

  5. 【python教程入门学习】Python实现自动玩贪吃蛇程序

    这篇文章主要介绍了通过Python实现的简易的自动玩贪吃蛇游戏的小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学一学 实现效果 先看看效果 这比我手动的快多了,而且是单机的,自动玩没惹 ...

  6. 【python教程入门学习】第一个Pygame程序

    Pygame 作为一个入门级的游戏开发库,其实并不难学,只要掌握 Python 编程的相关知识就能很轻松地掌握它. Pygame 语法简单.明了,秉持了 Python 语言一贯的风格.同时,它作为一个 ...

  7. 【python教程入门学习】python能做什么

    python能做什么?[python教程入门学习]介绍,最近许多的朋友咨询,听说python很火,甚至可以超越JAVA,因此很想学这个python,但是不知道python能做什么,能完成一些什么项目呢 ...

  8. 【python教程入门学习】普通人学python有意义吗

    普通人学python有意义吗?普通人能不能学习python语言,难不难,是否容易上手,学了python能做那些事情,能挣多少钱?这些问题是很多同学关心的问题,今天python教程入门学习就从小白同学的 ...

  9. 【python教程入门学习】学python要多久,0基础学python有多难

    学python要多久,0基础学python有多难,这是很多想学习python语言同学绕不开的问题,都害怕花完钱最终没有应有的回报!对于毫无经验0基础的同学来说学习python什么最重要,方向选对坚持下 ...

  10. 【python教程入门学习】Python新年炫酷烟花秀代码

    先介绍下 Pygame 绘制烟花的基本原理,烟花从发射到绽放一共分为三个阶段: 1,发射阶段:在这一阶段烟花的形状是线性向上,通过设定一组大小不同.颜色不同的点来模拟"向上发射" ...

最新文章

  1. Agile PLM Item Title Block Tab
  2. 业绩-----我觉得最难得不是写代码,而是写业绩表
  3. MRP信息汇总BAPI(Z_IF_MRP_TOTAL_LIST)
  4. Oracle创建简单视图案例
  5. Python之异常追踪模块:traceback
  6. app的证书签名,eclipse的sha1和md5值
  7. HDU2206:IP的计算
  8. Jpcap包的安装与配置
  9. 上海不行 java 地址识别 省、市、区,包括直辖市
  10. [转载] 网络硬件发展史
  11. 【嵌入式蓝桥杯】程序执行完中断将不再触发 /* Go to infinite loop when Hard Fault exception occurs */
  12. ps中怎样测量标尺线之间的距离及怎样切换距离单位
  13. Java编写杨辉三角
  14. 女神节快乐 | 用编程语言解密京东云程序媛!
  15. QTableView 例三(代理)
  16. 赵小楼《天道》《遥远的救世主》深度解析(136)自由不是你为所欲为,而是可以选择你不想干的事
  17. 九河 打结_舌头打结? 与视觉效果更快地沟通
  18. 思迈特软件Smartbi:10分钟教会你制作高难度的数据地图!
  19. 解决jeb提示秘钥注册码过期
  20. 2020起重机司机(限桥式起重机)模拟考试系统及起重机司机(限桥式起重机)考试试题

热门文章

  1. 编译器构造c语言描述pdf,关于编译器构造:为什么每次都要在C中指定数据类型?...
  2. Docker定制mysql+Tomcat镜像
  3. npm,node更新最新版本
  4. 蚊子的linux笔记 - linux常用命令
  5. mmdetection训练报错
  6. 2019-11-29-win10-uwp-颜色转换
  7. 思科设备中DHCP 服务的配置
  8. 软件使用 | Pycharm使用技巧大全
  9. java this 多线程_Java多线程编程的常见陷阱
  10. 360使用什么php框架,[项目实战] 马震宇出品360问答系统项目实战 基于HDPHP框架