用Pyhon写一款简单的益智类小游戏——2048
文字版——代码及讲解
代码——
import random# 初始化游戏棋盘
def init_board():return [[0] * 4 for _ in range(4)]# 在棋盘上随机生成一个2或4
def add_new_tile(board):empty_cells = [(i, j) for i in range(4) for j in range(4) if board[i][j] == 0]if empty_cells:i, j = random.choice(empty_cells)board[i][j] = 2 if random.random() < 0.9 else 4return board# 打印棋盘
def print_board(board):for row in board:for cell in row:print(str(cell).rjust(4), end="")print()# 向左移动
def move_left(board):new_board = [row[:] for row in board]for row in new_board:while 0 in row:row.remove(0)for i in range(len(row) - 1):if i + 1< len(row) and row[i] == row[i + 1]:row[i] *= 2row.pop(i + 1)while len(row) < 4:row.append(0)return new_board# 向右移动
def move_right(board):new_board = [row[::-1] for row in board]new_board = move_left(new_board)return [row[::-1] for row in new_board]# 向上移动
def move_up(board):new_board = list(map(list, zip(*board)))new_board = move_left(new_board)return list(map(list, zip(*new_board)))# 向下移动
def move_down(board):new_board = list(map(list, zip(*board)))new_board = move_right(new_board)return list(map(list, zip(*new_board)))# 检查是否还有可移动的位置
def is_game_over(board):for move in [move_left, move_right, move_up, move_down]:if move(board)!= board:return Falsereturn Truedef main():board = init_board()add_new_tile(board)add_new_tile(board)while not is_game_over(board):print_board(board)move = input("Enter a move (w: up, s: down, a: left, d: right): ")if move == "w":new_board = move_up(board)elif move == "s":new_board = move_down(board)elif move == "a":new_board = move_left(board)elif move == "d":new_board = move_right(board)else:print("Invalid move")continueif new_board!= board:board = new_boardadd_new_tile(board)print("Game Over!")if __name__ == "__main__":main()
讲解:
1.初始化游戏棋盘
def init_board():
return [[0] * 4 for _ in range(4)]
解释:这个函数用于创建一个 4x4 的二维列表,初始值都为 0,代表空的游戏棋盘
2.在棋盘上随机生成一个2或4
def add_new_tile(board):
empty_cells = [(i, j) for i in range(4) for j in range(4) if board[i][j] == 0]
if empty_cells:
i, j = random.choice(empty_cells)
board[i][j] = 2 if random.random() < 0.9 else 4
return board
解释:
首先找到棋盘上所有空的单元格(值为 0)
从空单元格中随机选择一个
在选中的单元格中,90% 的概率生成 2,10% 的概率生成 4
3.打印棋盘
def print_board(board):
for row in board:
for cell in row:
print(str(cell).rjust(4), end="")
print()
解释:
这个函数用于以美观的方式打印出游戏棋盘
对每一行和每一个单元格进行格式化处理,使其对齐显示
4. 向左移动
def move_left(board):
new_board = [row[:] for row in board]
for row in new_board:
while 0 in row:
row.remove(0)
for i in range(len(row) - 1):
if i + 1< len(row) and row[i] == row[i + 1]:
row[i] *= 2
row.pop(i + 1)
while len(row) < 4:
row.append(0)
return new_board
解释:
首先复制当前棋盘
对于每一行,移除所有的 0 元素,然后合并相同的数字,最后在末尾添加 0 元素使每行长度为 4
5.向右移动
def move_right(board):
new_board = [row[::-1] for row in board]
new_board = move_left(new_board)
return [row[::-1] for row in new_board]
解释:
先将每行反转
调用 move_left 函数进行移动操作
再将每行反转回来得到向右移动后的结果
6.向上移动
def move_up(board):
new_board = list(map(list, zip(*board)))
new_board = move_left(new_board)
return list(map(list, zip(*new_board)))
解释:
先对棋盘进行转置(行列互换)
调用 move_left 函数
再转置回来得到向上移动后的结果
7.向下移动
def move_down(board):
new_board = list(map(list, zip(*board)))
new_board = move_right(new_board)
return list(map(list, zip(*new_board)))
解释:
先对棋盘进行转置
调用 move_right 函数
再转置回来得到向下移动后的结果
8.检查是否还有可移动的位置
def is_game_over(board):
for move in [move_left, move_right, move_up, move_down]:
if move(board)!= board:
return False
return True
解释:
尝试所有的移动操作(左、右、上、下)
如果有任何一种移动操作得到的新棋盘与当前棋盘不同,说明游戏还可以继续,返回 False;否则返回 True,表示游戏结束
9.游戏循环
def main():
board = init_board()
add_new_tile(board)
add_new_tile(board)
while not is_game_over(board):
print_board(board)
move = input("Enter a move (w: up, s: down, a: left, d: right): ")
if move == "w":
new_board = move_up(board)
elif move == "s":
new_board = move_down(board)
elif move == "a":
new_board = move_left(board)
elif move == "d":
new_board = move_right(board)
else:
print("Invalid move")
continue
if new_board!= board:
board = new_board
add_new_tile(board)
print("Game Over!")
解释:
初始化棋盘并添加两个初始数字
进入游戏循环,在循环中:
打印当前棋盘
获取用户输入的移动方向
根据输入执行相应的移动操作
如果移动操作有效,更新棋盘并添加新的数字
当游戏结束时,打印 "Game Over!"
PPT版
相关文章:

用Pyhon写一款简单的益智类小游戏——2048
文字版——代码及讲解 代码—— import random# 初始化游戏棋盘 def init_board():return [[0] * 4 for _ in range(4)]# 在棋盘上随机生成一个2或4 def add_new_tile(board):empty_cells [(i, j) for i in range(4) for j in range(4) if board[i][j] 0]if empty_cells:i,…...

akshare股票涨跌幅自定义范围查询:A股、港股、美股
参看:https://stock.hexun.com/2024-10-31/215251914.html 涨幅计算公式:(当前价格 - 上一个交易日收盘价) 上一个交易日收盘价 100% 。 跌幅计算公式:(上一个交易日收盘价 - 当前价格) 上一个…...
通过js控制修改css变量
在JavaScript中,你可以通过操作CSS变量(也称为自定义属性)来动态改变样式。CSS变量在CSS中使用 – 前缀定义,例如 --main-color: red;。在JavaScript中,你可以使用 document.documentElement.style.setProperty 方法来…...

<HarmonyOS第一课>HarmonyOS SDK开放能力简介的课后习题
不出户,知天下; 不窥牖,见天道。 其出弥远,其知弥少。 是以圣人不行而知,不见而明,不为而成。 本篇<HarmonyOS第一课>HarmonyOS SDK开放能力简介是简单介绍了HarmonyOS SDK,不需要大家过多…...
深度学习:yolo的使用--图像处理
定义了一个名为 ListDataset 的类,它继承自 PyTorch 的 Dataset 类,这个数据集从一个包含图像文件路径的列表中读取图像和对应的标签文件 class ListDataset(Dataset):def __init__(self, list_path, img_size416, augmentTrue, multiscaleTrue, normalized_labelsT…...
TypeScript实用笔记(一):初始化、类型定义与函数使用
文章目录 一、ts初始化1. 初始化.json文件一2. 启动方式2.1 直接运行.ts文件2.2 转换运行 二、类型1. 参数类型1.1 常规参数1.2 symbol1.3 数组\[]1.4 元组\[]1.5 用字面量定义数据类型 2. Object3. 枚举类型\[Enum]3.1 数字枚举3.2 字符串枚举 三、 类型别名1. 数组别名使用2.…...

【大数据学习 | kafka】producer之拦截器,序列化器与分区器
1. 自定义拦截器 interceptor是拦截器,可以拦截到发送到kafka中的数据进行二次处理,它是producer组成部分的第一个组件。 public static class MyInterceptor implements ProducerInterceptor<String,String>{Overridepublic ProducerRecord<…...

零基础学西班牙语,柯桥专业小语种培训泓畅学校
No te comas el coco, seguro que te ha salido bien la entrevista. Ya te llamarn. 别瞎想了!我保证你的面试很顺利。他们会给你打电话的。 这里的椰子是"头"的比喻。在西班牙的口语中,我们也可以听到其他同义表达,比如&#x…...
C++学习:类和对象(三)
一、深入讲解构造函数 1. 什么是构造函数? 构造函数(Constructor)是在创建对象时自动调用的特殊成员函数,用于初始化对象的成员变量。构造函数的名称与类名相同,没有返回类型 2. 构造函数的类型 (1&…...

高阶数据结构--图(graph)
图(graph) 1.并查集1. 并查集原理2. 并查集实现3. 并查集应用 2.图的基本概念3. 图的存储结构3.1 邻接矩阵3.2 邻接矩阵的代码实现3.3 邻接表3.4 邻接表的代码实现 4. 图的遍历4.1 图的广度优先遍历4.2 广度优先遍历的代码 1.并查集 1. 并查集原理 在一…...

xxl-job java.sql.SQLException: interrupt问题排查
近期生产环境固定凌晨报错,提示 ConnectionManager [Thread-23069] getWriteConnection db:***,pattern: error, jdbcUrl: jdbc:mysql://***:3306/***?connectTimeout3000&socketTimeout180000&autoReconnecttrue&zeroDateTimeBehaviorCONVERT_TO_NUL…...

jmeter压测工具环境搭建(Linux、Mac)
目录 java环境安装 1、anaconda安装java环境(推荐) 2、直接在本地环境安装java环境 yum方式安装jdk 二进制方式安装jdk jmeter环境安装 1、jmeter单机安装 启动jmeter 配置环境变量 jmeter配置中文 2、jmeter集群搭建 多台机器部署jmeter集群…...
docker设置加速
sudo tee /etc/docker/daemon.json <<-‘EOF’ { “registry-mirrors”: [ “https://register.liberx.info”, “https://dockerpull.com”, “https://docker.anyhub.us.kg”, “https://dockerhub.jobcher.com”, “https://dockerhub.icu”, “https://docker.awsl95…...
使用requestAnimationFrame写防抖和节流
debounce.ts 防抖工具函数: function Animate() {this.timer null; }Animate.prototype.start function (fn) {if (!fn) {throw new Error(需要执行函数);}if (this.timer) {this.stop();}this.timer requestAnimationFrame(fn); }Animate.prototype.stop function () {i…...

Puppeteer 与浏览器版本兼容性:自动化测试的最佳实践
Puppeteer 支持的浏览器版本映射:从 v20.0.0 到 v23.6.0 自 Puppeteer v20.0.0 起,这个强大的自动化库开始支持与 Chrome 浏览器的无头模式和有头模式共享相同代码路径,为自动化测试带来了更多便利。从 v23.0.0 开始,Puppeteer 进…...
Java方法重写
在Java中,方法重写是指在子类中重新定义父类中已经定义的方法。以下是Java方法重写的基本原则: 子类中的重写方法必须具有相同的方法签名(即相同的方法名、参数类型和返回类型)。子类中的重写方法不能比父类中的原方法具有更低的…...

vscode通过.vscode/launch.json 内置php服务启动thinkphp 应用后无法加载路由解决方法
我们在使用vscode的 .vscode/launch.json Launch built-in server and debug 启动thinkphp应用后默认是未加载thinkphp的路由文件的, 这个就导致了,某些thinkphp的一些url路由无法访问的情况, 如http://0.0.0.0:8000/api/auth.admin/info这…...

Webserver(2.6)有名管道
目录 有名管道有名管道使用有名管道的注意事项读写特性有名管道实现简单版聊天功能拓展:如何解决聊天过程的阻塞 有名管道 可以用在没有关系的进程之间,进行通信 有名管道使用 通过命令创建有名管道 mkfifo 名字 通过函数创建有名管道 int mkfifo …...

四足机器人实战篇之一:波士顿spot机器人工程实现分析
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、机器人发展历史二、硬件系统及电机执行器篇硬件系统电机执行器传感器机处理器电气连接三、感知(视觉点云、局部地图、定位)篇1.深度相机获取…...
TensorFlow 预训练目标检测模型集合
Tensorflow 提供了一系列在不同数据集上预训练的目标检测模型,包括 COCO 数据集、Kitti 数据集、Open Images 数据集、AVA v2.1 数据集、iNaturalist 物种检测数据集 和 Snapshot Serengeti 数据集。这些模型可以直接用于推理,特别是当你对这些数据集中已…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...