原标题:python 实现 2048 游戏 (二)

来源:Python高效编程

作者:flywind

我们之前梳理了实现简易版 2048 游戏的基本知识,这篇文章将介绍如何实现各个模块。换句话说,上一次我们确定了旅行的目的地,这一次就让我们自由畅行在山间田野。

主程序,即game函数按部就班地向下执行,该判断就判断,然后执行相应函数。

用户输入小写的 w s a d 对应上下左右

具体来说,移动方向最前面有空间或者有连续相同的数字。可以移动则执行move函数,并在棋盘上生成随机数字,否则原样输出。

其次判断:棋盘是否被填满。被填满时执行fail函数。

defgame(board, stdscr, rscore):

globalscore

globalchange

# curses.noecho

# 屏幕不显示用户输入的字符

curses.noecho

while1:

# stdscr.getch

# 读取用户输入的字符

order = stdscr.getch

# move对用户移动的响应

current_board, change = move(order, board)

# change 为 1 随机产生 2 或 4

ifchange:

current_board = choice(board)

# 打印棋盘

print_board(stdscr, current_board, rscore)

# 当棋盘被填满,判断是否游戏结束

if(current_board != 0).all:

fail(current_board)

# win 为 1 打印获胜提示

ifwin:

stdscr.addstr( 'You win')

首先是移动模块:

basic函数用来执行移动与碰撞的操作。move_{up,down,right,left}函数用来实现各个方向上的 basic函数操作。move函数用来响应用户指令,实现各个方向上的移动。

矩阵组成,0 代表该位置上没有数字。basic函数就是基于矩阵的运算,且以右移为基础移动。

矩阵:

向右滑动:

每一周期分为 4 轮,每一轮操作一行(共 4 行),从最左面的元素开始执行。设置 flag 用于提示这一轮是否发生了改变,如果发生了改变,这一轮就再进行一次循环,直到 flag 保持为 0 不变。对于循环的每一个元素,如果该元素不为 0 ,若下个元素为 0,就交换当前值与下个元素的值。若下个元素与当前元素相同,则当前元素置 0 ,且下一个元素增加一倍,分数还要增加 100 分。

举个例子:对于第一行 [2 2 0 4]

第一轮:

4 与 0 不交换 [2 2 0 4]

0 与 2 交换 [2 0 2 4]

0 与 2 交换 [0 2 2 4]

flag = 1 且 score + = 0

第二轮:

4 与 2 不交换 [0 2 2 4]

双倍 置 0 [0 0 4 4]

0 不变 [0 0 4 4]

flag = 1 且 score += 100

第三轮:

双倍 置 0 [0 0 0 8]

不变 [0 0 0 8]

不变 [0 0 0 8]

flag = 1 且 score += 100

不变

不变

不变

flag = 0 且 score += 0

即第一轮最后输出结果 [0 0 0 8]。

以上就是向右移动的操作,而对于其他方向上的移动其实就是在此基础上进行矩阵的转置与逆置操作。

# A 为 4*4 的矩阵

# 转置操作

A.T

# 逆置操作

A[:: -1,:: -1]

下图为原矩阵:

向下滑动:

将原矩阵转置得到新矩阵,新矩阵向右滑动,相当于原矩阵向下滑动,再转置变回原矩阵。

向左滑动:

将原矩阵逆置得到新矩阵,新矩阵向右滑动,相当于原矩阵向左滑动,再逆置变回原矩阵。

将原矩阵转置加逆置得到新矩阵,新矩阵向右滑动,相当于原矩阵向上滑动,再通过转置加逆置变回原矩阵。

# 基础移动

defbasic(board):

globalscore

globalwin

# 以右移为基础移动

fori inrange( 4):

flag = 1

whileflag:

flag = 0

j = 2

whilej >= 0:

ifboard[i, j] != 0:

ifboard[i, j + 1] == board[i, j]:

board[i, j + 1] = 2* board[i, j]

ifboard[i, j + 1] == 2048:

win = 1

board[i, j] = 0

score += 100

flag = 1

elifboard[i, j + 1] == 0:

temp = board[i, j]

board[i, j] = board[i, j + 1]

board[i, j + 1] = temp

flag = 1

j -= 1

returnboard

# 右移

defmove_right(board):

returnbasic(board)

# 上移

defmove_up(board):

# 逆置 + 转置

board = board[:: -1, :: -1].T

board = basic(board)

board = board[:: -1, :: -1].T

returnboard

# 左移

defmove_left(board):

# 逆置

board = board[:: -1, :: -1]

board = basic(board)

board = board[:: -1, :: -1]

returnboard

# 下移

defmove_down(board):

# 转置

board = board.T

board = basic(board)

board = board.T

returnboard

# 移动

defmove(order, board):

# ord 求码值

globalscore

globalwin

change = 1

tempboard = copy.deepcopy(board)

# 退出游戏

iforder == ord( 'q'):

save_score(score)

exit

# 重置游戏

eliforder == ord( 'r'):

win = 0

save_score(score)

score = 0

stdscr.clear

wrapper(main)

# 胜利后,只有退出和重置游戏

elifwin:

change = 0

newboard = tempboard

returnnewboard, change

# 上下左右移动

eliforder == ord( 'w'):

newboard = move_up(board)

eliforder == ord( 's'):

newboard = move_down(board)

eliforder == ord( 'a'):

newboard = move_left(board)

eliforder == ord( 'd'):

newboard = move_right(board)

# 按其他键程序不响应

else:

newboard = board

if(newboard == tempboard).all:

change = 0

returnnewboard, change

接下来,我们讲choice模块:首先获取值为 0 的矩阵元素的位置,并储存在字典里,以序号( 最大值为 count ) 为索引。其次产生 [0,count) 范围内的随机数(随机抽取值为 0 的元素),并且产生随机数 2 或 4 (概率为 75% 与 25%)。最后将随机抽取的元素更改为生成的随机数(2 或 4)。

# 随机产生 2 或 4

defchoice(board):

udict = {}

# 统计0的个数

count = 0

fori inrange( 4):

forj inrange( 4):

# board[i,j] 为 0

# eg. {0:(1,3),1:(2,1),3:(3,2)}

# 根据 key 可以获得元素 0 在棋盘上的位置

ifnotboard[i, j]:

udict[count] = (i, j)

count += 1

# np.random.randint(0, count)

# 产生 [0,count) 范围内的随机数

random_number = np.random.randint( 0, count)

# np.random.choice([2,2,2,4])

# 随机选取列表 [2,2,2,4] 中的元素

two_or_four = np.random.choice([ 2, 2, 2, 4])

# 更改棋盘上 0 元素为随机数

board[udict[random_number]] = two_or_four

returnboard

然后是生成分数:

首先游戏开始时加载一次分数(历史最高分),游戏结束时保存最高分。每次打印棋盘前,都比较当前分数与当前最高分,并更改当前最高分数。

# 加载最高分

defload_score:

rank_score = np.load(FILENAME)

returnrank_score

# 保存最高分

defsave_score(score):

rscore = load_score

ifscore > rscore:

np.save(FILENAME, score)

# 比较当前分数与当前最高分

defcompare_score(score, rscore):

ifscore > rscore:

rscore = score

returnrscore

# 打印棋盘

defprint_board(stdscr, board, rscore):

globalscore

rscore = compare_score(score, rscore)

# stdscr.clear

# 清除屏幕

# stdsscr.addstr

# 打印字符串

stdscr.clear

stdscr.addstr( '得分:'+ str(score) + 'n')

stdscr.addstr( '历史最高:'+ str(rscore) + 'n')

fori inrange( 4):

stdscr.addstr( '-'* 22+ 'n')

forj inrange( 4):

stdscr.addstr( '|')

ifboard[i, j]:

stdscr.addstr( '{:^4d}'.format(board[i, j]))

else:

stdscr.addstr( ' '.format)

stdscr.addstr( '|')

stdscr.addstr( 'n')

stdscr.addstr( '-'* 22+ 'n')

首先我们要初始化程序,初次运行游戏会在当前目录生成 ‘out.npy’ 文件,并且储存 0 在文本中。其次初始化棋盘,最后就可以愉快地开始游戏了。

importnumpy asnp

importcurses

importcopy

importos

fromcurses importwrapper

stdscr = curses.initscr

# 分数

score = 0

# 判断是否获胜

win = 0

#

FILENAME = 'out.npy'

# 初始化

definit:

# 初始化棋盘

# 初始棋盘 2 或 4 的随机数字

ifFILENAME notinos.listdir:

np.save(FILENAME, 0)

init_board = choice(np.zeros(( 4, 4), dtype=np.int))

returninit_board

# 主程序

defmain(stdscr):

# 初始化程序

init_board = init

rscore = load_score

# 打印棋盘

print_board(stdscr, init_board, rscore)

# 游戏主进程

game(init_board, stdscr, rscore)

if__name__ == "__main__":

wrapper(main)

以上便是 python 实现 2048 游戏的完结版,如果想获取源代码,在微信后台回复 2048 ,或者点击阅读原文即可。返回搜狐,查看更多

责任编辑:

python2048游戏代码_python 实现 2048 游戏 (二)相关推荐

  1. python扫雷游戏代码_python实现扫雷游戏的示例

    扫雷是一款益智类小游戏,最早于 1992 年由微软在 Windows 上发行,游戏适合于全年龄段,规则简单,即在最短的时间内找出所有非雷格子且在中间过程中不能踩到雷, 踩到雷则失败,需重新开始. 本文 ...

  2. 拼图游戏代码html5,HTML5拼图游戏代码.doc

    HTML5拼图游戏代码 sliding.html 拼图游戏 拼图游戏 简单 困难 返回菜单 Sliding.jsvar context = document.getElementById('puzzl ...

  3. python2048游戏撤销上一部功能怎么实现_python 实现 2048 游戏 (一)

    初学 python ,大家恐怕都想找到一条终南捷径,会产生譬如 3 天精通 python 这样不太切合实际的想法.这种想法是很危险的,一旦你发现你根本不可能做到,你就会变得灰心丧气,甚至演变成 pyt ...

  4. python之穿越火线游戏代码_Python 大作业之五子棋游戏(附代码)

    Python 大作业--五子棋游戏 姓名:吴欣 学号: 姓名:张雨清 学号: 一 游戏介绍: 我们设计的是五子棋游戏,支持两人一个鼠标对下,黑方用左 键单击,白方用右键单击,谁先下均可,落子无悔,下过 ...

  5. python打地鼠游戏代码_Python 0基础开发游戏:打地鼠(详细教程)VS code版本

    如果你没有任何编程经验,而且想尝试一下学习编程开发,这个系列教程一定适合你,它将带你学习最基本的Python语法,并让你掌握小游戏的开发技巧.你所需要的,就是付出一些时间和耐心来尝试这些代码和操作.文 ...

  6. python塔防小游戏代码_Python制作塔防小游戏

    开发工具 Python版本:3.6.4 相关模块: pygame模块: 以及一些Python自带的模块. ​ 原理介绍 游戏规则简介: 玩家通过建造箭塔抵御敌人的进攻. 每隔一段时间,将会有一波敌人从 ...

  7. python编写小游戏代码_Python小游戏之300行代码实现俄罗斯方块

    Python小游戏之300行代码实现俄罗斯方块 来源:中文源码网 浏览: 次 日期:2019年11月5日 [下载文档: Python小游戏之300行代码实现俄罗斯方块.txt ] (友情提示:右键点上 ...

  8. python双人格斗游戏代码_Python:游戏:贪吃蛇

    一.游戏介绍 贪吃蛇是个非常简单的游戏,适合练手.先来看一下我的游戏截图: 玩法介绍: 回车键:开始游戏 空格键:暂停 / 继续 ↑↓←→方向键 或 WSAD 键:控制移动方向. 食物分红.绿.蓝三种 ...

  9. python拍7游戏代码_Python基础语法-7(小游戏)

    代码太长?内容太复杂? 不用担心!往下看↓ 知道为什么python简洁,省力么? 就是因为python有很多写好的工具箱可以直接调用,我们只要开头给一个命令,在我们的代码 就可以直接使用它的功能了,这 ...

  10. python制作猜拳游戏代码_python实现猜拳游戏项目

    本文实例为大家分享了python实现猜拳游戏的具体代码,供大家参考,具体内容如下 项目功能: 1.系统生成随机的石头剪刀布,玩家输入石头剪刀布 2.因为玩家可能会输入shitou st这样的输入,需要 ...

最新文章

  1. delphi xe 文件服务器,DelphiXE7中创建WebService(服务端+客户端)
  2. 在页面之间传递信息--查询字符串
  3. php pdo字符,PHP:(PDO)Mysql最有效的方式来添加字符串以返回db的值
  4. 北京内推 | 微软亚洲研究院自然语言计算组招聘NLP研究型实习生
  5. Python_ collections_defaultdict默认字典
  6. 7-1 叶节点求和 (30 分)
  7. 通过IDE生成和手动call调用webservice
  8. 树莓派摄像头基础配置及测试
  9. MapReduce操作时Error:The method setInputPaths(JobConf, String) in the type FileInputFormat is not
  10. 【德国】德累斯顿工业大学 机器学习和图像分析研究助理/博士生 招生
  11. 自定义托管宿主WCF解决方案开发配置过程详解
  12. Android笔记 fragment入门 动态加载fragment demo+ 判断横竖屏
  13. onnx格式转tensorRT
  14. FAST DFS服务搭建说明
  15. CPC客户端安装教程
  16. paypal java开发_paypal开发指南
  17. 电容或电感的电压_阻碍电流流通的“双子星”,电容与电感
  18. 简单的python爬虫--爬取Taobao淘女郎信息
  19. 机器学习算法之聚类算法拓展:Mini Batch K-Means算法
  20. Objective-C 属性

热门文章

  1. html怎么画虚线空心圆,PS如何画虚线圆圈 photoshop快速画虚线圆圈方法教程
  2. python gui 之库tkinter笔记
  3. 微型计算机课程设计电子密码锁,《微机原理及应用》课程设计基于74LS112的电子密码锁设计报告初版...
  4. FBX模型格式和FbxSDK
  5. In library(package, lib.loc = lib.loc,character.only = TRUE, there is no package called ‘kknn’
  6. 动手实现对外安全的接口(写于天寒地冻的正月初九)
  7. 公共DNS服务器IP地址
  8. 曲苑杂坛--修改数据库服务器名称
  9. 打飞机小游戏C语言实现
  10. 微信号可以一年内第二次修改技巧吗?