当前位置: 首页 > article >正文

DQN 玩 2048 实战|第一期!搭建游戏环境(附 PyGame 可视化源码)

视频讲解:

DQN 玩 2048 实战|第一期!搭建游戏环境(附 PyGame 可视化源码)

代码仓库:GitHub - LitchiCheng/DRL-learning: 深度强化学习

2048游戏介绍,引用维基百科

《2048》在4×4的网格上进行。玩家可以使用上、下、左、右四个方向键移动所有方块。[1]但在部分情形下,不可向某些方向移动。[2]:66游戏开始时,网格上会出现两个数值为2或4的方块。每次移动后,另一个数值为2或4的新方块会随机出现在空方格上。[2]:66方块会沿着指定的方向滑动,直到被其它方块或网格边缘阻挡。如果两个相同数值的方块碰撞,它们将合并成一个方块,其数值等于两个方块的数值之和。[3][4]如果三个数值相同的方块碰撞,则只会合并靠近终点方向的两个方块,距起点最近的方块的数值不变。若一行或一列中的方块数值均相同,则沿着该行或该列滑动会合并前两个和后两个方块。[5]在同一移动过程中,新生成的方块不能再与其他方块合并。[6]数值较高的方块会发出柔和的光芒;但随着得分增加,光芒会不断变暗。[6]方块数值都是2的幂,最大为131072。[7]界面右上方的记分牌会记录玩家的分数。玩家的初始分数为零,每当两个方块合并时,分数会增加,得分取决于合并后方块的数值。[8]

玩家获取胜利的条件是获得数值为2048的方块。达到这一目标后,玩家可以继续游戏,以获得更高的分数。[9][10][11]当玩家没有合法的移动方法时,即出现了网格上没有空方格,且相邻方块的数值均不相同的情况,游戏就直接结束。[6][12]

使用pygame创建一个交互环境,实际作为env使用的时候可以不用pygame,换成matplotlib只做一个简单的显示即可,安装pygame

pip3 install pygame -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

创建一个Env2048Gui.py

import numpy as np
import random
import pygame# 2048 游戏环境类
class Game2048:def __init__(self):self.board = np.zeros((4, 4), dtype=int)self.add_random_tile()self.add_random_tile()def add_random_tile(self):empty_cells = np.argwhere(self.board == 0)if len(empty_cells) > 0:index = random.choice(empty_cells)self.board[index[0], index[1]] = 2 if random.random() < 0.9 else 4def move_left(self):reward = 0new_board = np.copy(self.board)for row in range(4):line = new_board[row]non_zero = line[line != 0]merged = []i = 0while i < len(non_zero):if i + 1 < len(non_zero) and non_zero[i] == non_zero[i + 1]:merged.append(2 * non_zero[i])reward += 2 * non_zero[i]i += 2else:merged.append(non_zero[i])i += 1new_board[row] = np.pad(merged, (0, 4 - len(merged)), 'constant')if not np.array_equal(new_board, self.board):self.board = new_boardself.add_random_tile()return rewarddef move_right(self):self.board = np.fliplr(self.board)reward = self.move_left()self.board = np.fliplr(self.board)return rewarddef move_up(self):self.board = self.board.Treward = self.move_left()self.board = self.board.Treturn rewarddef move_down(self):self.board = self.board.Treward = self.move_right()self.board = self.board.Treturn rewarddef step(self, action):if action == 0:reward = self.move_left()elif action == 1:reward = self.move_right()elif action == 2:reward = self.move_up()elif action == 3:reward = self.move_down()done = not np.any(self.board == 0) and all([np.all(self.board[:, i] != self.board[:, i + 1]) for i in range(3)]) and all([np.all(self.board[i, :] != self.board[i + 1, :]) for i in range(3)])state = self.board.flatten()return state, reward, donedef reset(self):self.board = np.zeros((4, 4), dtype=int)self.add_random_tile()self.add_random_tile()return self.board.flatten()# 颜色定义
COLORS = {0: (205, 193, 180),2: (238, 228, 218),4: (237, 224, 200),8: (242, 177, 121),16: (245, 149, 99),32: (246, 124, 95),64: (246, 94, 59),128: (237, 207, 114),256: (237, 204, 97),512: (237, 200, 80),1024: (237, 197, 63),2048: (237, 194, 46)
}# 绘制游戏板
def draw_board(screen, board, tile_size, margin):for i in range(4):for j in range(4):value = board[i][j]color = COLORS.get(value, (0, 0, 0))pygame.draw.rect(screen, color,(j * (tile_size + margin) + margin,i * (tile_size + margin) + margin,tile_size, tile_size))if value != 0:font = pygame.font.Font(None, 36)text = font.render(str(value), True, (0, 0, 0))text_rect = text.get_rect(center=(j * (tile_size + margin) + margin + tile_size // 2,i * (tile_size + margin) + margin + tile_size // 2))screen.blit(text, text_rect)# 主函数
def main():pygame.init()tile_size = 100margin = 10width = height = 4 * (tile_size + margin) + marginscreen = pygame.display.set_mode((width, height))pygame.display.set_caption("2048 Game")game = Game2048()done = Falseclock = pygame.time.Clock()while not done:for event in pygame.event.get():if event.type == pygame.QUIT:done = Trueelif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:_, _, done = game.step(0)elif event.key == pygame.K_RIGHT:_, _, done = game.step(1)elif event.key == pygame.K_UP:_, _, done = game.step(2)elif event.key == pygame.K_DOWN:_, _, done = game.step(3)screen.fill((187, 173, 160))draw_board(screen, game.board, tile_size, margin)pygame.display.flip()clock.tick(60)pygame.quit()if __name__ == "__main__":main()

运行后,可以通过上下左右键进行控制

python3 Env2048Gui.py

相关文章:

DQN 玩 2048 实战|第一期!搭建游戏环境(附 PyGame 可视化源码)

视频讲解&#xff1a; DQN 玩 2048 实战&#xff5c;第一期&#xff01;搭建游戏环境&#xff08;附 PyGame 可视化源码&#xff09; 代码仓库&#xff1a;GitHub - LitchiCheng/DRL-learning: 深度强化学习 2048游戏介绍&#xff0c;引用维基百科 《2048》在44的网格上进行。…...

高频面试题(含笔试高频算法整理)基本总结回顾24

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…...

大模型token和字符串的关系

一 主要区别 token 是使用分词器拆分后的最小单位&#xff0c;不同的分词方式会导致同样的字符具有不同的token数量。如你好&#xff0c;可以拆分为【你、好】两个token&#xff0c; 【你好】一个token。 同一个文本的 Token 数量可能远少于字符数&#xff08;英文&#xff09…...

第八节:红黑树(初阶)

【本节要点】 红黑树概念红黑树性质红黑树结点定义红黑树结构红黑树插入操作的分析 一、红黑树的概念与性质 1.1 红黑树的概念 红黑树 &#xff0c;是一种 二叉搜索树 &#xff0c;但 在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是 Red和 Black 。 通过对 任何…...

【动态规划】- 线性dp

目录 第 N 个泰波那契数 三步问题 使用最小花费爬楼梯 解码方法 第 N 个泰波那契数 1137. 第 N 个泰波那契数 - 力扣&#xff08;LeetCode&#xff09; 状态表示 是什么&#xff1f;dp表里面的值所表示的含义怎么来&#xff1f;①题目要求->dp[ i ]表示第 i 个泰波那契…...

Python Cookbook-4.3 若列表中某元素存在则返回之

任务 你有一个列表L&#xff0c;还有一个索引号i&#xff0c;你希望当i是L,的有效索引时获取L[i]&#xff0c;若不是有效索引&#xff0c;则返回一个默认值v。如果L是字典&#xff0c;可以使用L.get(i,v)来满足需求&#xff0c;可是列表并没有 get这个方法。 解决方案 很明显…...

Webpack vs Rollup vs Parcel:构建工具深度对比

文章目录 1. 核心特性对比1.1 功能定位1.2 技术架构对比 2. 配置与使用2.1 Webpack 配置示例2.2 Rollup 配置示例2.3 Parcel 使用示例 3. 性能对比3.1 构建速度3.2 输出质量 4. 生态系统4.1 插件生态4.2 学习曲线 5. 适用场景分析5.1 Webpack 适用场景5.2 Rollup 适用场景5.3 P…...

Centos7使用docker搭建redis集群

前置准备&#xff1a; Centos7安装docker就不多说了… 本次目的是搭建3主3从&#xff08;当然你也可以按需扩展&#xff09;准备三台服务器&#xff0c;假定IP分别为&#xff1a;192.168.75.128、192.168.75.129、192.168.75.130安装 redis&#xff1a; #拉取redis docker p…...

蓝桥杯备赛-二分-跳石头

问题描述 一年一度的"跳石头"比赛又要开始了&#xff01; 这项比赛将在一条笔直的河道中进行&#xff0c;河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间&#xff0c;有 NN 块岩石&#xff08;不含起点和终点的岩石&a…...

【09】单片机编程核心技巧:变量赋值,从定义到存储的底层逻辑

【09】单片机编程核心技巧&#xff1a;变量赋值&#xff0c;从定义到存储的底层逻辑 &#x1f31f; 核心概念 单片机变量的定义与赋值是程序设计的基础&#xff0c;其本质是通过 RAM&#xff08;随机存储器&#xff09; 和 ROM&#xff08;只读存储器&#xff09; 的协作实现…...

数字孪生像魔镜,映照出无限可能的未来

在当今科技飞速发展的时代&#xff0c;数字孪生作为一项极具潜力的前沿技术&#xff0c;正逐渐崭露头角&#xff0c;成为众多领域关注的焦点。它犹如一面神奇的魔镜&#xff0c;以数字化的方式精准映照出现实世界中的各种实体与系统&#xff0c;为我们开启了一扇通往无限可能未…...

加密算法逆向与HOOK技术实战

1. 密码学基础与逆向特征识别 1.1 算法分类与模式特征 常见算法指纹库&#xff1a; # 算法特征识别字典 CRYPTO_SIGNATURES { "AES": { "init": ["AES/ECB", "AES/CBC", "AES/GCM"], "key_len": [128, 2…...

前端知识点---原型-原型链(javascript)

文章目录 原型原型链:实际应用面试题回答 原型 原型:每个函数都有prototype属性 称之为原型 因为这个属性的值是个对象&#xff0c;也称为原型对象 只有函数才有prototype属性 作用: 1.存放一些属性和方法 2.在Javascript中实现继承 const arr new Array(1, 2, 3, 4) con…...

数据类设计_图片类设计之6_混合图形类设计(前端架构)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇,讨论混合图形类设计 方法论-现在能做什么 这段属于聊天内容---有句话是这么说的&#xff1a;不要只埋头拉车&#xff0c;还要抬头看路。写代码也是…...

2024年12月CCF-GESP编程能力等级认证C++编程一级真题解析

一级真题的难度: ‌ CCF-GESP编程能力等级认证C++编程一级真题的难度适中‌。这些真题主要考察的是C++编程的基础知识、基本语法以及简单的算法逻辑。从搜索结果中可以看到,真题内容包括了选择题、编程题等题型,涉及的内容如C++表达式的计算、基本输入输出语句的理解…...

尤瓦尔·诺亚·赫拉利(Yuval Noah Harari)作品和思想深度报告

尤瓦尔诺亚赫拉利&#xff08;Yuval Noah Harari&#xff09;作品和思想深度报告 引言 尤瓦尔诺亚赫拉利&#xff08;Yuval Noah Harari&#xff09;是当今最具影响力的公众知识分子之一 ynharari.com 。作为一名历史学家和哲学家&#xff0c;他以宏大的视角和清晰生动的语言…...

JConsole:JDK性能监控利器之JConsole的使用说明与案例实践

&#x1fa81;&#x1f341; 希望本文能给您带来帮助&#xff0c;如果有任何问题&#xff0c;欢迎批评指正&#xff01;&#x1f405;&#x1f43e;&#x1f341;&#x1f425; 文章目录 一、背景二、JConsole的启动与连接2.1 JConsole的启动2.2 进程连接2.2.1 本地进程连接2.2…...

Neural Architecture Search for Transformers:A Survey

摘要 基于 Transformer 的深度神经网络架构因其在自然语言处理 (NLP) 和计算机视觉 (CV) 领域的各种应用中的有效性而引起了极大的兴趣。这些模型是多种语言任务&#xff08;例如情绪分析和文本摘要&#xff09;的实际选择&#xff0c;取代了长短期记忆 (LSTM) 模型。视觉 Tr…...

Browser Copilot 开源浏览器扩展,使用现有或定制的 AI 助手来完成日常 Web 应用程序任务。

一、软件介绍 文末提供源码和开源扩展程序下载 Browser Copilot 是一个开源浏览器扩展&#xff0c;允许您使用现有或定制的 AI 助手来帮助您完成日常 Web 应用程序任务。 目标是提供多功能的 UI 和简单的框架&#xff0c;以实现和使用越来越多的 copilots&#xff08;AI 助手&…...

基于PSO粒子群优化的XGBoost时间序列预测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 XGBoost算法原理 4.2 XGBoost优化 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2024b 3.部分核心程序 &#xff08;完整版代码包含…...

股票查询系统

使用sql创建一个database&#xff0c;名称为&#xff1a;stock&#xff0c;在stock中创建一个表&#xff0c;名称为&#xff1a;stocks&#xff0c; 表中的各个字段为&#xff1a; stock_code 最大6位整数数字&#xff0c;必须填写 stock_name, 最大20个汉字&#xff0c;必须填…...

aws(学习笔记第三十三课) 深入使用cdk 练习aws athena

文章目录 aws(学习笔记第三十三课) 深入使用cdk学习内容&#xff1a;1. 使用aws athena1.1 什么是aws athena1.2 什么是aws glue1.2 为什么aws athena和aws glue一起使用 2. 开始练习aws athena2.1 代码链接2.2 整体架构2.3 代码解析2.3.1 创建测试数据的S3 bucket2.3.2 创建保…...

基于RAGFlow本地部署DeepSpeek-R1大模型与知识库:从配置到应用的全流程解析

作者&#xff1a;后端小肥肠 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; DeepSpeek服务器繁忙&#xff1f;这几种替代方案帮你流畅使用&#xff01;&#xff08;附本地部署教程&#xff09;-CSDN博客 10分钟上手…...

ESP-IDF中FreeRTOS的三种任务调度算法

本文内容参考: STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)_freertos最多支持多少个任务-CSDN博客 浅析FreeRTOS任务调度器的三种调度算法和应用-电子发烧友网 特此致谢! FreeRTOS中的任务调度算法 FreeRTOS支持多种任务调度算法,可通过配置来…...

SpringBoot 集成logback日志链路追踪

项目场景 有时候一个业务调用链场景&#xff0c;很长&#xff0c;调了各种各样的方法&#xff0c;看日志的时候&#xff0c;各个接口的日志穿插&#xff0c;确实让人头大。 为了解决这个痛点&#xff0c;就使用了 TraceId&#xff0c;根据 TraceId 关键字进入服务器查询日志中…...

【Python办公】Excel通用匹配工具(双表互匹)

目录 专栏导读1、背景介绍2、库的安装3、核心代码4、完整代码总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该系列文章专栏:请点击——>Python办公自动化专…...

【JAVA】七、基础知识“if+switch+循环结构”详细讲解~简单易懂!

目录 7、逻辑控制 7.1 分支结构 7.1.1 if 语句 语法格式1 语法格式2 语法格式3 7.1.2 switch语句 基本语法 执行流程 7.2 循环结构 7.2.1 while循环 语法格式 7.2.2 Break 7.2.3 Continue 7.2.4 for循环 语法格式 执行过程 7.2.5 do while循环 语法格式 7.3 …...

【C++】每日一练(轮转数组)

本篇博客给大家带来的是用C语言来解答轮转数组&#xff01; &#x1f41f;&#x1f41f;文章专栏&#xff1a;每日一练 &#x1f680;&#x1f680;若有问题评论区下讨论&#xff0c;我会及时回答 ❤❤欢迎大家点赞、收藏、分享&#xff01; 今日思想&#xff1a;不服输的少年啊…...

Java 反射机制学习

Java 反射机制详解 Java 反射&#xff08;Reflection&#xff09;是 Java 语言的一种强大特性&#xff0c;允许程序在运行时动态地获取类的信息并操作类或对象的属性、方法和构造器。反射机制打破了 Java 的封装性&#xff0c;但也提供了极大的灵活性&#xff0c;常用于框架开…...

GetCurrentTime

在实际编程中难免要获取当前时间并且进行格式化&#xff0c;本文给出了多种 GetCurrentTime() 方法以供选择。 C语言下使用strftime C 语言中可以使用 <time.h> 中的函数来获取和格式化时间 #include <stdio.h> #include <time.h>char* getCurrentTime() …...