200行Python代码实现的2048小游戏
2048这个小游戏大家都不陌生,应该都玩过,之前已经在网上见过各个版本的2048实现了,有JAVA、HTML5等,今天我就给大家来一个我自己在 实验楼 学到的python版2048。所有代码加起来才200行,不用很麻烦很累就可以写一个 2048 游戏出来。
游戏的具体规则什么的就不多说了,自己亲自去玩一下就清楚了。
导入需要的包
import cursesfrom random import randrange, choicefrom collections import defaultdict
游戏主逻辑
用户行为
用户在玩游戏的主要输入分为六种,"上,下,左,右,游戏重置,退出"用 actions
表示
actions = ['Up', 'Left', 'Down', 'Right', 'Restart', 'Exit']
分别用 W(上),A(左),S(下),D(右),R(重置),Q(退出),进行输入来操作游戏,这里考虑到大写锁定键锁定的情况:
letter_codes = [ord(ch) for ch in 'WASDRQwasdrq']
将输入与行为进行关联:
actions_dict = dict(zip(letter_codes, actions * 2))
用户输入处理
阻塞+循环,直到获得用户有效输入才返回对应行为:
def get_user_action(keyboard): char = "N"while char not in actions_dict: char = keyboard.getch()return actions_dict[char]
矩阵转置与矩阵逆转
这两个操作主要是用户在操作游戏之后对棋盘状态的变化以及修改,拥有这两个函数能够节省不少的代码量。
矩阵转置:
def transpose(field):return [list(row) for row in zip(*field)]
矩阵逆转(不是逆矩阵):
def invert(field):return [row[::-1] for row in field]
创建棋盘
初始化棋盘的参数,可以指定棋盘的高和宽以及游戏胜利条件,默认是最经典的 4x4~2048。
class GameField(object):
def __init__(self, height=4, width=4, win=2048):self.height = height #高self.width = width #宽self.win_value = 2048 #过关分数self.score = 0 #当前分数self.highscore = 0 #最高分self.reset() #棋盘重置
棋盘操作
随机生成一个 2 或者 4
def spawn(self):new_element = 4 if randrange(100) > 89 else 2(i,j) = choice([(i,j) for i in range(self.width) for j in range(self.height) if self.field[i][j] == 0])self.field[i][j] = new_element
重置棋盘
def reset(self):if self.score > self.highscore:self.highscore = self.scoreself.score = 0self.field = [[0 for i in range(self.width)] for j in range(self.height)]self.spawn()self.spawn()
一行向左合并
(注:这一操作是在 move 内定义的,拆出来是为了方便阅读)
def move_row_left(row):def tighten(row): # 把零散的非零单元挤到一块new_row = [i for i in row if i != 0]new_row += [0 for i in range(len(row) - len(new_row))]return new_rowdef merge(row): # 对邻近元素进行合并pair = Falsenew_row = []for i in range(len(row)):if pair:new_row.append(2 * row[i])self.score += 2 * row[i]pair = Falseelse:if i + 1 < len(row) and row[i] == row[i + 1]:pair = Truenew_row.append(0)else:new_row.append(row[i])assert len(new_row) == len(row)return new_row#先挤到一块再合并再挤到一块return tighten(merge(tighten(row)))
棋盘走一步
通过对矩阵进行转置与逆转,可以直接从左移得到其余三个方向的移动操作
def move(self, direction):def move_row_left(row):#一行向左合并moves = {}moves['Left'] = lambda field: [move_row_left(row) for row in field]moves['Right'] = lambda field: invert(moves['Left'](invert(field)))moves['Up'] = lambda field: transpose(moves['Left'](transpose(field)))moves['Down'] = lambda field: transpose(moves['Right'](transpose(field)))if direction in moves:if self.move_is_possible(direction):self.field = moves[direction](self.field)self.spawn()return Trueelse:return False
判断输赢
def is_win(self):return any(any(i >= self.win_value for i in row) for row in self.field)def is_gameover(self):return not any(self.move_is_possible(move) for move in actions)
判断能否移动
def move_is_possible(self, direction):def row_is_left_movable(row): def change(i):if row[i] == 0 and row[i + 1] != 0: # 可以移动return Trueif row[i] != 0 and row[i + 1] == row[i]: # 可以合并return Truereturn Falsereturn any(change(i) for i in range(len(row) - 1))check = {}check['Left'] = lambda field: any(row_is_left_movable(row) for row in field)check['Right'] = lambda field: check['Left'](invert(field))check['Up'] = lambda field: check['Left'](transpose(field))check['Down'] = lambda field: check['Right'](transpose(field))if direction in check:return check[direction](self.field)else:return False
绘制游戏界面
(注:这一步是在棋盘类内定义的)
def draw(self, screen):help_string1 = '(W)Up (S)Down (A)Left (D)Right'help_string2 = ' (R)Restart (Q)Exit'gameover_string = ' GAME OVER'win_string = ' YOU WIN!'def cast(string):screen.addstr(string + '\n')#绘制水平分割线def draw_hor_separator():line = '+' + ('+------' * self.width + '+')[1:]separator = defaultdict(lambda: line)if not hasattr(draw_hor_separator, "counter"):draw_hor_separator.counter = 0cast(separator[draw_hor_separator.counter])draw_hor_separator.counter += 1def draw_row(row):cast(''.join('|{: ^5} '.format(num) if num > 0 else '| ' for num in row) + '|')screen.clear()cast('SCORE: ' + str(self.score))if 0 != self.highscore:cast('HGHSCORE: ' + str(self.highscore))for row in self.field:draw_hor_separator()draw_row(row)draw_hor_separator()if self.is_win():cast(win_string)else:if self.is_gameover():cast(gameover_string)else:cast(help_string1)cast(help_string2)
完成主逻辑
完成以上工作后,我们就可以补完主逻辑了!
def main(stdscr):def init():#重置游戏棋盘game_field.reset()return 'Game'def not_game(state):#画出 GameOver 或者 Win 的界面game_field.draw(stdscr)#读取用户输入得到action,判断是重启游戏还是结束游戏action = get_user_action(stdscr)responses = defaultdict(lambda: state) #默认是当前状态,没有行为就会一直在当前界面循环responses['Restart'], responses['Exit'] = 'Init', 'Exit' #对应不同的行为转换到不同的状态return responses[action]def game():#画出当前棋盘状态game_field.draw(stdscr)#读取用户输入得到actionaction = get_user_action(stdscr)if action == 'Restart':return 'Init'if action == 'Exit':return 'Exit'if game_field.move(action): # move successfulif game_field.is_win():return 'Win'if game_field.is_gameover():return 'Gameover'return 'Game'state_actions = {'Init': init,'Win': lambda: not_game('Win'),'Gameover': lambda: not_game('Gameover'),'Game': game}curses.use_default_colors()game_field = GameField(win=32)state = 'Init'#状态机开始循环while state != 'Exit':state = state_actions[state]()
运行
填上最后一行代码:
curses.wrapper(main)
运行看看吧!
$ python 2048.py
详细代码参见:http://git.shiyanlou.com/littlemonkey/shiyanlou_cs368/src/master/2048.py
转载于:https://www.cnblogs.com/snail-up/p/4682370.html
200行Python代码实现的2048小游戏相关推荐
- 20行python代码的入门级小游戏-200行Python代码实现的2048小游戏
2048这个小游戏大家都不陌生,应该都玩过,之前已经在网上见过各个版本的2048实现了,有JAVA.HTML5等,今天我就给大家来一个我自己在 实验楼 学到的python版2048.所有代码加起来才2 ...
- 【Python妙用】用200行Python代码制作一个迷宫小游戏
相信大家都玩过迷宫的游戏,对于简单的迷宫,我们可以一眼就看出通路,但是对于复杂的迷宫,可能要仔细寻找好久,甚至耗费数天,然后可能还要分别从入口和出口两头寻找才能找的到通路,甚至也可能找不到通路. 虽然 ...
- 50行Python代码玩转微信小游戏颜色王者
50行Python代码玩转微信小游戏"颜色王者" 游戏模式 在微信小程序里搜索"颜色王者",即可找到该游戏. 游戏的目标比拼色彩敏感度.点击图片中不一样的色块即 ...
- Python之路—200行Python代码搞了个打飞机游戏!!
早就知道pygame模块,就是没怎么深入研究过,恰逢这周未没约到妹子,只能自己在家玩自己啦,一时兴起,花了几个小时写了个打飞机程序. 很有意思,跟大家分享下. 先看一下项目结构 1 2 3 4 5 6 ...
- 详解200行Python代码实现控制台版2048【总有一款坑适合你】【超详细】
跟着实验楼学习了2048的Python实现,先丢个地址 200行Python代码实现2048 我接触Python时间不长,只了解一些基本的语法和容器,在学习的过程中遇到不少问题,这里做一个记录. cu ...
- Python实战2 - 200行Python代码实现2048(控制台)
Python实战系列用于记录实战项目中的思路,代码实现,出现的问题与解决方案以及可行的改进方向 本文为第2篇–200行Python代码实现2048 一.分析与函数设计 1.1 游戏玩法 2048这款游 ...
- python换脸完整程序_小 200 行 Python 代码做了一个换脸程序
原标题:小 200 行 Python 代码做了一个换脸程序 简介 在这篇文章中我将介绍如何写一个简短(200行)的 Python 脚本,来自动地将一幅图片的脸替换为另一幅图片的脸. 这个过程分四步: ...
- 用 200 行 Python 代码掌握基本音乐理论
本文作者是一位多年自学成才的吉他手,但对西方乐理一无所知,因此决定编写一些代码来搞懂它. 本文用了大约200行Python代码来帮助我们理解西方音乐理论的基础知识. 我们将首先查看西方音乐理论中的音符 ...
- python换脸教程_教你如何用200行Python代码“换脸”教程
原标题:教你如何用200行Python代码"换脸"教程 本文将介绍如何编写一个只有200行的Python脚本,为两张肖像照上人物的"换脸". 这个过程可分为四步 ...
- 炫酷!200 行 Python 代码实现马赛克拼图!
在一图胜千言的时代,没有什么比一张图片更有冲击力的了,那如果一千张图片拼接起来是什么效果呢? 别问,问就是两字 -- 炫酷! 你有没有想过上面的图片是怎么实现的,难道这是用 ps 一张张拼起来的?当然 ...
最新文章
- 屏蔽storm ui的kill功能
- 1-6 数据查询(下)——复杂查询
- 【Python】Pandas profiling 生成报告并部署的一站式解决方案
- phpMyAdmin开发人员访谈——4个人支持整个项目
- AJAX 带有 取消功能的 UpdateProgress
- NAPI 技术在 Linux 网络驱动上的应用和完善
- 什么是Reactive Streams in Java 译
- Oracle location,oracle秘境探索之11g tablespace prellocation
- linux导入多个文件到myql
- 离线中技术方案的场景
- 内点法(interior point method)求解二次规划,附python代码
- 黑群晖一键生成视频缩略图
- android 自带TextToSpeech没有声音
- 树莓派WiFi设置固定IP地址
- KICAD——手动生成嘉立创可识别的BOM和POS文件
- 银盒子智慧餐厅硬件尺寸规格推荐机型
- jQuery weui Select组件显示指定值
- 谷歌搜索 的几种方法
- OLED显示STM32
- 数据可视化软件有哪些?