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

如何实现带历史记录功能的控制台2048游戏

如何实现带历史记录功能的控制台2048游戏

2048 是一款经典的单人益智游戏,玩家通过合并相同的方块以达成目标分数(2048)。本文将介绍如何在原版 Python 控制台 2048 游戏的基础上增加 游戏历史记录功能,使玩家能够保存每一局的游戏记录、恢复未完成的游戏,并查看历史分数和状态。

通过这篇文章,你将学会如何通过文件管理来持久化游戏数据,保存每一局游戏的操作步骤、网格状态、得分等信息,并且在需要时恢复游戏状态。


1. 游戏历史记录管理

为了让玩家能够查看并管理自己的游戏历史,我们将每局游戏的相关数据(例如:分数、网格状态等)保存到本地文件中。历史记录包括了每局游戏的操作步骤、分数、移动后的网格状态等。

关键点

  • 游戏ID生成:每局游戏会生成一个唯一的 ID,基于当前的时间戳。
  • CSV 文件记录:每一步游戏操作(包括方块的移动、得分和网格变化)会记录到 CSV 文件中。
  • JSON 文件记录:游戏的完整状态(例如:网格、分数、胜利状态等)会保存到 JSON 文件中,以供后续恢复。

代码实现

import csv
import json
import datetime
import osclass Console2048WithHistory:def __init__(self, grid_size=4):# 初始化游戏设置self.history_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "game_history")self.history_file = Noneself.game_id = Noneself.game_start_time = Noneself.current_move = 0if not os.path.exists(self.history_dir):os.makedirs(self.history_dir)def start_new_game(self):"""开始新游戏并记录历史"""self.game_id = datetime.datetime.now().strftime("%Y%m%d_%H%M%S_%f")self.game_start_time = datetime.datetime.now()game_dir = os.path.join(self.history_dir, self.game_id)os.makedirs(game_dir, exist_ok=True)self.history_file = os.path.join(game_dir, "history.csv")with open(self.history_file, 'w', newline='', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(["步数", "操作类型", "操作得分", "总分", "移动后的网格状态", "随机添加后的网格状态"])

2. 游戏状态保存与加载

为了增强用户体验,我们增加了游戏状态的保存与加载功能。每次玩家执行操作后,游戏的网格状态、分数等信息会保存为 JSON 文件。这样即使玩家退出游戏,下一次启动时也可以继续之前的游戏。

关键点

  • 状态保存:每执行一步操作后,游戏状态(如网格、分数等)会保存在 JSON 文件中。
  • 状态恢复:游戏支持恢复最近未完成的游戏,通过加载保存的状态继续游戏。

代码实现

def save_game_state(self):"""保存游戏状态"""if not self.game_id:returngame_dir = os.path.join(self.history_dir, self.game_id)state_file = os.path.join(game_dir, "game_state.json")game_state = {"grid": self.grid,"score": self.score,"best_score": self.best_score,"game_over": self.game_over,"won": self.won,"current_move": self.current_move,"last_updated": datetime.datetime.now().isoformat()}try:with open(state_file, 'w', encoding='utf-8') as f:json.dump(game_state, f, ensure_ascii=False, indent=2)except IOError as e:passdef load_game_state(self, game_id):"""加载指定游戏ID的状态"""game_dir = os.path.join(self.history_dir, game_id)state_file = os.path.join(game_dir, "game_state.json")if not os.path.exists(state_file):return Falsetry:with open(state_file, 'r', encoding='utf-8') as f:game_state = json.load(f)self.game_id = game_idself.grid = game_state.get('grid', [[0] * self.grid_size for _ in range(self.grid_size)])self.score = game_state.get('score', 0)self.best_score = game_state.get('best_score', 0)self.game_over = game_state.get('game_over', False)self.won = game_state.get('won', False)self.current_move = game_state.get('current_move', 0)return Trueexcept (json.JSONDecodeError, IOError) as e:return False

3. 游戏历史记录查看与管理

我们通过读取 index.json 文件来查看最近未完成的游戏,玩家可以选择加载最新的未完成游戏。这样玩家可以继续上一次的游戏,而不必从头开始。

关键点

  • 未完成游戏索引:通过读取 index.json 文件,可以查看所有未完成的游戏。
  • 加载历史游戏:玩家可以选择继续最近的一局未完成的游戏,恢复之前的网格状态和分数。

代码实现

def get_last_unfinished_game(self):"""获取最后一个未完成的游戏"""index_file = os.path.join(self.history_dir, "index.json")if not os.path.exists(index_file):return Nonetry:with open(index_file, 'r', encoding='utf-8') as f:index_data = json.load(f)unfinished_games = [game for game in index_data if not game.get('is_completed', False)]if not unfinished_games:return Noneunfinished_games.sort(key=lambda x: x.get('last_updated', ''), reverse=True)return unfinished_games[0]except (json.JSONDecodeError, IOError) as e:return None

4. 游戏退出与数据更新

当玩家退出游戏时,我们会更新游戏的索引,确保当前游戏数据被及时保存。退出时,游戏的状态会标记为未完成,玩家可以随时恢复上次的状态。

关键点

  • 游戏结束时更新索引:每当一局游戏结束时,游戏的结果会更新到 index.json 文件中。
  • 游戏退出时保存未完成状态:当玩家退出时,游戏状态会被标记为未完成,以便玩家以后继续。

代码实现

def update_index(self, is_completed=None):"""更新目录文档"""if not self.game_id or not self.game_start_time:returnindex_file = os.path.join(self.history_dir, "index.json")# 读取现有索引index_data = []if os.path.exists(index_file):try:with open(index_file, 'r', encoding='utf-8') as f:index_data = json.load(f)except (json.JSONDecodeError, IOError) as e:index_data = []completed_status = is_completed if is_completed is not None else (self.game_over or self.won)# 创建或更新当前游戏的索引条目game_info = {"game_id": self.game_id,"start_time": self.game_start_time.isoformat(),"score": self.score,"best_score": self.best_score,"is_completed": completed_status,"last_updated": datetime.datetime.now().isoformat()}# 更新索引文件try:with open(index_file, 'w', encoding='utf-8') as f:json.dump(index_data, f, ensure_ascii=False, indent=2)except IOError as e:pass

5. 示例文件内容

  1. index.json:记录游戏的基本信息,包括游戏ID、开始时间、分数等。
[{"game_id": "20251115_011133_522512","start_time": "2025-11-15T01:11:33.522512","score": 2940,"best_score": 2940,"is_completed": false,"last_updated": "2025-11-15T01:16:45.692189"},{"game_id": "20251115_022750_959447","start_time": "2025-11-15T02:27:50.959447","score": 1164,"best_score": 12060,"is_completed": true,"last_updated": "2025-11-15T02:33:44.991410"}
]
  1. best_score.json:记录游戏的最佳分数。
{"best_score": 12060
}
  1. game_state.json:记录每局游戏的完整状态,包括网格、分数、是否结束等。
{"grid": [[2, 4, 8, 4],[16, 32, 16, 2],[8, 16, 64, 8],[32, 64, 32, 2]],"score": 1164,"best_score": 12060,"game_over": false,"won": false,"current_move": 139,"last_updated": "2025-11-15T02:33:44.965340"
}
  1. history.csv:记录每一步操作的信息,包括步数、操作类型、得分等。
步数,操作类型,操作得分,总分,移动后的网格状态,随机添加后的网格状态
1,初始状态,0,0,"[[0, 2, 4, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]","[[0, 2, 4, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]"
2,向down移动,0,0,"[[0, 2, 4, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]","[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [2, 2, 4, 0]]"
3,向left移动,4,4,"[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [2, 2, 4, 0]]","[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 2], [4, 4, 0, 0]]"

6. 总结

通过这些新增的功能,我们不仅让 2048 游戏 更具交互性,还提升了用户体验。通过游戏历史记录功能,玩家可以查看过往的游戏数据,恢复未完成的游戏,或继续挑战更高的分数。

http://www.dtcms.com/a/613770.html

相关文章:

  • gitlab cicd首次操作
  • 建设学院网站意义比价 wordpress 插件下载
  • 电子毕业设计代做网站上海雷蒙威手表网站
  • LangChain Memory
  • 【ZeroRange WebRTC】NACK(Negative Acknowledgment)技术深度分析
  • 物联网架构
  • 网站推广公司兴田德润在哪儿wordpress 手机支付
  • 如何在 VSCode 中创建 Vue 项目
  • 【ZeroRange WebRTC】PLI(Picture Loss Indication)技术深度分析
  • 神马影视 8.8 源码 2025 版,HDR + 杜比音效 + 零卡顿
  • MFC编程实战:全面掌握Combo Box(组合框)控件的高级应用
  • 归并排序 (BM20 数组中的逆序对)
  • Spring @Around 注解
  • 建设企业网站需要考虑的因素有哪些店铺logo设计免费
  • 50019_基于微信小程序的校园互助系统
  • (120页PPT)ChatGPT与数字化转型的业财融合(附下载方式)
  • Java面试中等测试题
  • 爱站库全栈网站开发工程师
  • docker避免每次sudo方法
  • 计算机图形学·15 计算机视图(Computer Viewing)
  • 使用rufus制作系统盘及Ubantu24.04.3LTS镜像文件下载
  • opencart做视频网站做网站盈利方式
  • Polar MISC(下)
  • DNS基础介绍
  • Spring Boot 3.4 正式发布,结构化日志!
  • Docker安装和使用kkfileview
  • 做超市dm的网站淘宝联盟网站建设不完整
  • 手机终端传输模式深入介绍
  • 深圳工程造价建设信息网站为什么不做网站做公众号
  • 发那科机器人指令详解:从入门到精通