用Python写一个无界面的2048小游戏


Posted in Python onMay 24, 2016

以前游戏2048火的时候,正好用其他的语言编写了一个,现在学习python,正好想起来,便决定用python写一个2048,由于没学过python里面的界面编程,所以写了一个极其简单的无界面2048。游戏2048的原理和实现都不难,正好可以拿来练手,要是不知道这游戏的话,可以去网上查一下,或者下载一个到手机来玩一下,我就不在说其原理。我知道不放图的话大家一点兴趣都没,下面首先放一张游戏成型图,然后我们在来讲如何一步步用最基础的知识来实现。

用Python写一个无界面的2048小游戏

一、生成4*4的矩阵

游戏的第一步便是生成一个4*4的矩阵,当作我们游戏的主界面,其实说起来也比较简单,这里用了最原始的方法,直接用

print将其打印出来。首先我们要生成一个全为0的4*4二维列表,然后用一些类似  '┌ ├└,┤,┘┐│,─,┬,┴'这样的字符来组成我们的边框,下面来看一下代码的实现

matix=[[ for i in range()] for i in range()]    # 用列表推导式初始化生成一个*的列表,列表元素全为 
# notzero函数的作用:游戏界面上非零的时候才显示,当为的时候,让其显示空,
def notzero(s):                    
  return s if s!= else ''             # 非零的话返回本身,否则返回 ''
def display():










# 显示界面函数,用┌ ├└,┤,┘┐│,─,┬,┴ 等显示边框,中间显示*矩阵里的的元素
  print("\r\
┌──┬──┬──┬──┐\n\
│%s│%s│%s│%s│\n\
├──┬──┬──┬──┤\n\
│%s│%s│%s│%s│\n\
├──┬──┬──┬──┤\n\
│%s│%s│%s│%s│\n\
├──┬──┬──┬──┤\n\
│%s│%s│%s│%s│\n\
└──┴──┴──┴──┘"\
%(notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),\
 notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),\
 notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]), \
 notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),notzero(matix[][]),)
     )
display()

来看一下上面代码的效果,是不是感觉一个游戏的框架已经到搭好了,由于初始化的时候,矩阵元素都为零,下面的图也就没有显示出0,是不是很简单,一个游戏的界面就被我们搭好了,不过毕竟没学过界面,所以大家就不要抱怨这界面有多么丑了哈。

用Python写一个无界面的2048小游戏

二、初始化生成随机数

这个游戏每次开始的时候都会随机在上面的一个矩阵中生成两个随机数2或4,那么我们要如何来实现在上面矩阵中随机的一个位置生成一个随机数2或4了,当然是用到我们前面学过的random模块以及divmod(),下面我们就来看一下如何用random模块实现着一功能。

def init():                      # 初始化矩阵
  initNumFlag = 
  while :
    k = if random.randrange(, ) > else  # 当生成随机数大于的时候k=否则k= 生成和的概率为:
    s = divmod(random.randrange(, ), )    # 生成矩阵初始化的下标 比如divmod(,)的话,s为(,)正好可以作为矩阵下标
    if matix[s[]][s[]] == :          # 只有当其值不为的时候才赋值,避免第二个值重复
      matix[s[]][s[]] = k
      initNumFlag += 
      if initNumFlag == :           # 当initNumFlag== 的话表示矩阵里两个随机数都已经生成了,退出循环
        break
init()
display( )

来看一下上面代码的效果,是不是已经在两个随机的位置生成了两个数,如果大家有时间的试一下,可以看见每次执行的时候,出现在矩阵上面位置不一样,而且每次出现的数也不一样,因为我上面设置了出现2:4的概率为9:1所以大多时候出现2,这也是游戏的需要。到了这里矩阵已经可以动起来了,游戏的功能也可以说完成了一半。

用Python写一个无界面的2048小游戏

三、游戏逻辑部分实现

 

如果玩过这游戏的话就知道,游戏中每次向上下左右移动的时候,比如像下移动的话,所有的数都会向下移动,碰到相同的数,就会成一个新的数,比如2和2碰到的话,就会生成4,然后再随机在其他位置生成一个2或4 ,同理4和4碰到的话也会生成8,直到合成了2048游戏就算成功了,或者说矩阵中的数字都不能移动那就是Game Over。当然我们在手机上玩游戏的话,随便滑动一下,所有的数字就可以向其中一个方向滑动,但是这里没有界面,条件比较艰苦,所以只能从控制台读入用户输入的字母,然后一个个来判断是向哪里移动了,所以我们要写4个函数来分别处理用户的上下左右移动,让后一个函数处理在每次用户移动后,如何添加一个随机数,下面先写一段伪代码来解释流程

def addRandomNum():


  
#每次移动后随机在矩阵中在生成一个数
  pass  



def moveDown():






#向上移动的处理函数
  pass<br>  addRandomNum()





 #移动处理完成后,随机生成一个数
def moveLeft():






 #向左移动的处理函数
  pass
  addRandomNum()
def moveUp():






  #向上移动的处理函数
  pass
  addRandomNum()
def moveRight():





  #向右移动的处理函数
  pass
  addRandomNum()
def main():
  while flag:












#定义一个死循环,不断读入用户的输入,然后在做判断,看是向哪里移动
    d = input(' (↑:w) (↓:s) (←:a) (→:d),q(uit) :“)
    if d == 'a':
      moveLeft() 
    elif d == 's':
      moveDown()
    elif d == 'w':
      moveUp()
    elif d == 'd':
      moveRight()
    elif d == 'q':
      break
    else:
      pass

上面是一段为了理解的伪代码,下面我们来看一下如何实现移动处理函数,这里是整个游戏中最难处理的部分,完成了这一部分的话,整个游戏也就基本上实现了,这里我以向下的移动处理函数为例,其他的都一样,当用户输入向下移动的时候,所有的数字都向下移动,如果碰到相同的数字要和并,有数字的方块向没有数字的方块移动。这里需要用循环实现,有4列所以最外层的循环有4次,每一列里面又需要循环处理,下面来看一下具体怎么实现,

def addRandomNum():










# 跟初始化生成随机数一样,只不过这里只是生成一个随机数
  while :
    k = if random.randrange(, ) > else 
    s = divmod(random.randrange(, ), )
    if matix[s[]][s[]] == :
      matix[s[]][s[]] = k
      break
  display()












 # 随机数添加完成后就直接调用显示函数,直接显示一下游戏界面
def moveDown():















#处理向下移动的函数
  for i in range():













#外层次循环处理例,内层两个层循环,来处理相邻的两个数
    for j in range(, , -):
      for k in range(j - , -, -):
        if matix[k][i] > :









# 从最下面的数开始处理相邻的两个数
          if matix[j][i] == :
            matix[j][i] = matix[k][i]




  # 如果下面的数为空,上面的数字不为空就移动上面的数为下面的数
            matix[k][i] = 
          elif matix[j][i] == matix[k][i]:




# 如果相邻的两个数相等的话,就和并,并把上面的输置零,下面的数变成两倍
            matix[j][i] *= 
            matix[k][i] = 
          break
  addRandomNum()














# 移动完成后再随机生成一个数

写完了向下移动的处理函数,那么向其他方向的移动函数也一样,照着写,就可以,到这里游戏中最难的部分就完成,可以说胜利就在眼前了,好了在这之前,我们还需要处理一下其他问题,那就是每次移动后都要检查,游戏是不是Game Over了,还有就是定义一个变量来纪录分数了,这些实现起来都比较简单。

四、游戏纪录分数和检查游戏是否结束

游戏结束的标志是矩阵中所有的数都不为0,而且所有相邻的数都不能合并,根据这个我们就可以来写一个函数来判断游戏是否GG,至于分数纪录,我们只需定义一个变量,然后每次有何并的时候,就加上一定的分数即可。下面我们来看检查函数的实现。

def check():





  for i in range(4):



#按每一排循环4 次
    for j in range(3):

  # 如果矩阵中有0存在,或者有相邻的数就表示游戏还可以继续经行,否则就是GG
      if matix[i][j] == 0 or matix[i][j] == matix[i][j + 1] or matix[j][i] == matix[j + 1][i]:
        return True
  else:
    return False

五、完整游戏源码

完成了上面的部分,整个游戏的过程就实现了,下面附上整个游戏的源码。游戏还有很多不够完善的地方,比如说游戏中如果出现2048的话,就表示玩家胜利,游戏结束,但是我这里没有做处理,所以这个游戏可以一直玩到4096....没有结束,除非你游戏中GG了,要处理也很简单,还可以将矩阵存在文件中,完成一个游戏存档的功能。有兴趣的话大家去实现一下。

import random
score = 0










 # 纪录游戏的分数
matix = [[0 for i in range(4)] for i in range(4)] # 初始化生成一个4*4的列表
def notzero(s):
  return s if s != 0 else ''
def display():
  print("\r\
     ┌──┬──┬──┬──┐\n\
     │%4s│%4s│%4s│%4s│\n\
     ├──┬──┬──┬──┤\n\
     │%4s│%4s│%4s│%4s│\n\
     ├──┬──┬──┬──┤\n\
     │%4s│%4s│%4s│%4s│\n\
     ├──┬──┬──┬──┤\n\
     │%4s│%4s│%4s│%4s│\n\
     └──┴──┴──┴──┘" \
     % (notzero(matix[0][0]), notzero(matix[0][1]), notzero(matix[0][2]), notzero(matix[0][3]), \
       notzero(matix[1][0]), notzero(matix[1][1]), notzero(matix[1][2]), notzero(matix[1][3]), \
       notzero(matix[2][0]), notzero(matix[2][1]), notzero(matix[2][2]), notzero(matix[2][3]), \
       notzero(matix[3][0]), notzero(matix[3][1]), notzero(matix[3][2]), notzero(matix[3][3]),)
     )
def init(): 














# 初始化矩阵
  initNumFlag = 0
  while 1:
    k = 2 if random.randrange(0, 10) > 1 else 4 


# 随机生成 2 或 4
    s = divmod(random.randrange(0, 16), 4) 



 # 生成矩阵初始化的下标
    if matix[s[0]][s[1]] == 0: 







 # 只有当其值不为0的时候才赋值,避免第二个值重复
      matix[s[0]][s[1]] = k
      initNumFlag += 1
      if initNumFlag == 2:
        break
  display()
def addRandomNum():











#处理完移动后添加一个新的随机数
  while 1:
    k = 2 if random.randrange(0, 10) > 1 else 4
    s = divmod(random.randrange(0, 16), 4)
    if matix[s[0]][s[1]] == 0:
      matix[s[0]][s[1]] = k
      break
  display()
def check():













#检查游戏是否GG
  for i in range(4):
    for j in range(3):
      if matix[i][j] == 0 or matix[i][j] == matix[i][j + 1] or matix[j][i] == matix[j + 1][i]:
        return True
  else:
    return False
def moveRight():











 # 向右移动处理函数
  global score
  for i in range(4):
    for j in range(3, 0, -1):
      for k in range(j - 1, -1, -1):
        if matix[i][k] > 0:
          if matix[i][j] == 0:
            matix[i][j] = matix[i][k]
            matix[i][k] = 0
          elif matix[i][j] == matix[i][k]:
            matix[i][j] *= 2
            score += matix[i][j]


 #将当前数作为score加上
            matix[i][k] = 0
          break
  addRandomNum()
def moveUp():
  global score
  for i in range(4):
    for j in range(3):
      for k in range(j + 1, 4):
        if matix[k][i] > 0:
          if matix[j][i] == 0:
            matix[j][i] = matix[k][i]
            matix[k][i] = 0
          elif matix[k][i] == matix[j][i]:
            matix[j][i] *= 2
            score += matix[j][i]
            matix[k][i] = 0
          break
  addRandomNum()
def moveDown():
  global score
  for i in range(4):
    for j in range(3, 0, -1):
      for k in range(j - 1, -1, -1):
        if matix[k][i] > 0:
          if matix[j][i] == 0:
            matix[j][i] = matix[k][i]
            matix[k][i] = 0
          elif matix[j][i] == matix[k][i]:
            matix[j][i] *= 2
            score += matix[j][i]
            matix[k][i] = 0
          break
  addRandomNum()
def moveLeft():
  global score
  for i in range(4):
    for j in range(3):
      for k in range(1 + j, 4):
        if matix[i][k] > 0:
          if matix[i][j] == 0:
            matix[i][j] = matix[i][k]
            matix[i][k] = 0
          elif matix[i][j] == matix[i][k]:
            matix[i][j] *= 2
            score += matix[i][j]
            matix[i][k] = 0
          break
  addRandomNum()
def main():
  print("    \033[33;1mWelcome to the Game of 2048!\033[0m")
  flag = True
  init()
  while flag:

















#循环的标志
    print('        \033[33;1m You Score:%s\033[0m' % (score))
    d = input('\033[33;1m (↑:w) (↓:s) (←:a) (→:d),q(uit) :\033[0m')  #不断处理用户输入
    if d == 'a':

















      moveLeft()
      if not check():













 #检查游戏是否GG
        print('GG')
        flag = False













 #GG的话直接退出
    elif d == 's':
      moveDown()
      if not check():
        print('GG')
        flag = False
    elif d == 'w':
      moveUp()
      if not check():
        print('GG')
        flag = False
    elif d == 'd':
      moveRight()
      if not check():
        print('GG')
        flag = False
    elif d == 'q':












# 退出
      break
    else:














  # 对用户的其他输入不做处理
      pass
if __name__ == '__main__':
  main()

最后在附上一张图片最为结束

 用Python写一个无界面的2048小游戏

以上所述是小编给大家介绍的用Python写一个无界面的2048小游戏,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
《Python之禅》中对于Python编程过程中的一些建议
Apr 03 Python
Python制作简易注册登录系统
Dec 15 Python
Python并发:多线程与多进程的详解
Jan 24 Python
Python3.5常见内置方法参数用法实例详解
Apr 29 Python
Python获取数据库数据并保存在excel表格中的方法
Jun 12 Python
Python pandas DataFrame操作的实现代码
Jun 21 Python
使用python模拟高斯分布例子
Dec 09 Python
python实现FTP循环上传文件
Mar 20 Python
python实现交并比IOU教程
Apr 16 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
Jun 09 Python
详解python命令提示符窗口下如何运行python脚本
Sep 11 Python
python3.8.3安装教程及环境配置的详细教程(64-bit)
Nov 28 Python
Python实现二叉树结构与进行二叉树遍历的方法详解
May 24 #Python
Python中set与frozenset方法和区别详解
May 23 #Python
python实现多线程的两种方式
May 22 #Python
python实现简单购物商城
May 21 #Python
python字符串的常用操作方法小结
May 21 #Python
python实现用户登录系统
May 21 #Python
python列表的常用操作方法小结
May 21 #Python
You might like
火车采集器 免费版使出收费版本功能实现原理
2009/09/17 PHP
php获取通过http协议post提交过来xml数据及解析xml
2012/12/16 PHP
PHP获取当前页面完整URL的实现代码
2013/06/10 PHP
ThinkPHP的RBAC(基于角色权限控制)深入解析
2013/06/17 PHP
PHP Session 变量的使用方法详解与实例代码
2013/09/11 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
php猜单词游戏
2015/09/29 PHP
php 判断过去离现在几年的函数(实例代码)
2016/11/15 PHP
Javascript实现的分页函数
2006/12/22 Javascript
js弹出层之1:JQuery.Boxy (二)
2011/10/06 Javascript
jquery实现鼠标拖拽滑动效果来选择数字的方法
2015/05/04 Javascript
JS轮播图中缓动函数的封装
2020/11/25 Javascript
nodejs中解决异步嵌套循环和循环嵌套异步的问题
2017/07/12 NodeJs
Angular中使用better-scroll插件的方法
2018/03/27 Javascript
AngularJS 应用模块化的使用
2018/04/04 Javascript
ES6 Array常用扩展的应用实例分析
2019/06/26 Javascript
python实现图书管理系统
2018/03/12 Python
python实现excel读写数据
2021/03/02 Python
对Python3 goto 语句的使用方法详解
2019/02/16 Python
解决python3中的requests解析中文页面出现乱码问题
2019/04/19 Python
python的turtle库使用详解
2019/05/10 Python
python中用logging实现日志滚动和过期日志删除功能
2019/08/20 Python
关于阿里云oss获取sts凭证 app直传 python的实例
2019/08/20 Python
python对Excel的读取的示例代码
2020/02/14 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
基于注解实现 SpringBoot 接口防刷的方法
2021/03/02 Python
Alba Moda德国网上商店:意大利时尚女装销售
2016/11/14 全球购物
日本PLST在线商店:日本时尚杂志刊载的人气服装
2016/12/10 全球购物
以色列的身体护理及家居香薰品牌:Sabon NYC
2018/02/23 全球购物
柏林通行证:Berlin Pass
2018/04/11 全球购物
会计学专业学生的求职信范文
2014/01/27 职场文书
广播体操口号
2014/06/18 职场文书
妈妈活动方案
2014/08/15 职场文书
校本研修个人总结
2015/02/28 职场文书
《游戏公平》教学反思
2016/02/20 职场文书
详解Vue的列表渲染
2021/11/20 Vue.js