大一计算机专业全栈工程师学习路线

路线说明

本路线面向已掌握 C 语言和数据结构的计算机专业大一学生,计划通过约 10 个月的系统学习,逐步形成 Java 后端与 Vue 前端的全栈开发能力,并为实习求职做好准备。

README 仅展示整体路线。每个阶段的知识安排、练习任务、验收标准和执行计划,请查看对应阶段的详细计划。

路线总览

阶段学习方向预计时间验收项目详细计划
阶段一前端入门2 个月官网还原、2048 游戏(均提供蓝湖设计图)查看计划
阶段二Java 基础2-2.5 个月控制台版学生信息管理系统查看计划
阶段三前端工程化1.5-2 个月后台管理前端项目查看计划
阶段四后端进阶与全栈整合3-4 个月全栈个人博客系统查看计划
阶段五AI Agent 提效持续学习使用 AI Agent 完成项目迭代查看计划

阶段一:前端入门

  • 核心目标:理解网页结构、样式与交互,能够使用原生前端技术完成基础项目
  • 技术方向:HTML、CSS、JavaScript、浏览器开发者工具
  • 验收项目:根据提供的官网蓝湖设计图完成纯静态页面还原;使用原生 JavaScript 实现 2048 游戏,并根据对应蓝湖设计图完成界面还原
  • 详细计划stage-1/PLAN.md

阶段二:Java 基础

  • 核心目标:建立面向对象思维,掌握 Java 核心语法,并能够操作关系型数据库
  • 技术方向:Java SE、Maven、JDBC、MySQL、Git、Linux 基础
  • 验收项目:控制台版学生信息管理系统
  • 详细计划stage-2/PLAN.md

阶段三:前端工程化

  • 核心目标:掌握组件化与模块化开发方式,能够独立开发现代前端应用
  • 技术方向:Node.js、Vite、Vue 3、Vue Router、Pinia、Axios、Element Plus
  • 验收项目:使用 Mock 数据的后台管理前端项目
  • 详细计划stage-3/PLAN.md

阶段四:后端进阶与全栈整合

  • 核心目标:掌握主流 Java Web 开发技术,完成前后端分离项目及部署
  • 技术方向:Spring Boot、MyBatis-Plus、Redis、JWT、Docker、Nginx
  • 验收项目:前后端分离的全栈个人博客系统
  • 详细计划stage-4/PLAN.md

阶段五:AI Agent 提效

  • 核心目标:理解 AI Agent 的基本工作方式,能够将其应用于学习和开发流程,提高交付效率
  • 技术方向:提示词编写、上下文管理、任务拆解、工具调用、代码审查、结果验证
  • 验收项目:使用 AI Agent 对已有项目完成一次需求分析、开发、调试和文档整理
  • 详细计划stage-5/PLAN.md

求职准备

求职准备贯穿整个学习过程,重点包括算法练习、计算机基础知识复习、项目总结、简历优化和模拟面试。建议从阶段二开始持续积累,在阶段四完成后集中进行实习投递。

阶段一:前端入门

阶段说明

  • 学习周期:8 周
  • 建议投入:每天 2-3 小时,每周学习 6 天,复盘和休息 1 天
  • 前置要求:掌握基本的计算机操作,具备 C 语言和数据结构基础
  • 阶段目标:掌握 HTML、CSS 和原生 JavaScript,能够独立完成静态页面和基础交互项目

主要学习资料

HTML 和 CSS 统一参考黑马程序员的《前端 Web 开发 HTML5+CSS3+移动 Web 视频教程》。课程共 200 节,前四周按视频分 P 顺序学习。

视频仅用于学习知识点和页面实现思路,不要求下载课程源码、切图或其他配套素材,也不要求完成视频中的案例项目。HTML/CSS 实践统一使用提供的官网蓝湖设计图及其可导出资源;蓝湖中没有对应效果的知识点,可以使用纯色块和自编文字完成最小练习。

JavaScript 参考视频待定。确定课程后,再把第 6-8 周的知识点映射到具体视频章节。

阶段成果

完成本阶段后,应能够:

  • 使用语义化 HTML 搭建结构清晰的网页
  • 使用 CSS 完成 PC 端、移动端和响应式布局
  • 根据蓝湖设计图独立还原纯静态官网
  • 使用 JavaScript 处理数据并实现基础业务逻辑
  • 使用 DOM 和事件完成网页交互
  • 使用浏览器开发者工具定位常见问题
  • 使用 Git 和 GitHub 管理并提交 2048 游戏项目

周计划

周次学习主题视频范围本周成果详细计划
第 1 周HTML 与 CSS 入门P1-P42完成基础内容页面查看计划
第 2 周CSS 盒模型与布局P43-P80完成蓝湖官网的基础组件和局部布局查看计划
第 3 周PC 端网页综合布局P81-P130完成蓝湖官网 PC 端主体查看计划
第 4 周CSS3、移动端与响应式P131-P200使用蓝湖官网内容完成高级样式与适配练习查看计划
第 5 周官网蓝湖设计图还原独立项目完成纯静态官网校对与验收查看计划
第 6 周JavaScript 基础参考视频待定完成基础可玩控制台版 2048查看计划
第 7 周DOM、Git 与 2048 网页化参考视频待定接入 DOM,并补充计分与重开查看计划
第 8 周2048 蓝湖设计图还原与验收2048 蓝湖设计图根据蓝湖设计图完善项目并验收查看计划

阶段验收

项目一:官网蓝湖设计图还原

  • 根据提供的蓝湖设计图,使用 HTML 和 CSS 完成页面还原
  • 不使用前端框架或 UI 组件库
  • 本项目不要求使用 Git 或提交至 GitHub
  • 详细要求与验收标准见第 5 周计划

项目二:2048 游戏

  • 使用 HTML、CSS 和原生 JavaScript 实现完整的 2048 游戏
  • 根据提供的 2048 蓝湖设计图完成游戏界面还原
  • 使用 Git 管理开发过程,并将项目提交至 GitHub
  • 仓库必须包含项目说明文档
  • 详细要求与验收标准见第 8 周计划

阶段完成清单

  • 完成 HTML/CSS 课程 P1-P200 及对应练习
  • 完成纯静态官网并通过验收
  • 完成 JavaScript 基础练习
  • 掌握 DOM 操作和常用事件处理
  • 完成 2048 游戏全部功能和规则测试
  • 2048 项目具有清晰、连续的 Git 提交记录
  • 2048 项目已推送至 GitHub,并包含完整 README
  • 能够独立讲解两个项目的结构和核心实现

附录:知识点参考

以下知识树仅用于查阅和复习,不属于周计划任务,也不纳入阶段验收:

第 1 周:HTML 与 CSS 入门

本周目标

本周完成后,应能够:

  • 不依赖模板写出完整的 HTML 文档结构
  • 根据内容选择合适的 HTML 标签,而不是全部使用 div
  • 正确处理图片、链接等资源的路径
  • 使用表格展示数据,使用表单收集基础信息
  • 使用外部 CSS 为页面设置文字、颜色和基础尺寸
  • 使用浏览器开发者工具检查 HTML 结构和 CSS 来源
  • 独立完成一个结构完整、样式清晰的内容型页面

学习资料与范围

视频范围学习模块学习结果
P1-P15环境、HTML 骨架、排版、图片、路径、链接和多媒体能够搭建基础内容页面
P16-P27列表、表格、表单、divspan 和字符实体能够组织列表、数据和用户输入
P28-P40CSS 引入、基础选择器、字体、文本和调试工具能够为页面添加基础视觉样式
P41-P42新闻详情与 CSS 简介案例能够综合运用本周内容

需要掌握的知识点

HTML 基础

  • DOCTYPEhtmlheadbody 的作用
  • 标签的开始、结束、嵌套、并列和包含关系
  • 标题、段落、换行、水平线和文本格式化标签
  • 图片的路径、替代文本、宽高和常见加载问题
  • 超链接的目标地址、页面内跳转和新窗口打开
  • 音频、视频等多媒体标签的基础用法
  • HTML 注释及清晰的代码缩进

页面结构

  • 有序列表、无序列表和定义列表的适用场景
  • 表格的表头、表体、行、单元格及单元格合并
  • input 的常见类型、下拉菜单、文本域、label 和按钮
  • divspan 的区别
  • headernavmainsectionarticleasidefooter 等语义化标签

路径与目录

  • 相对路径与绝对路径的区别
  • 当前目录、上级目录和子目录的写法
  • HTML、CSS、图片和媒体资源的分类存放
  • 文件重命名或移动后资源失效的排查方法

CSS 入门

  • 行内、内部和外部样式表的区别,项目中优先使用外部样式表
  • 标签、类、ID 和通配符选择器
  • 使用多个类复用样式
  • 字号、粗细、倾斜、行高和字体族
  • 文本缩进、对齐、装饰线和颜色
  • font 复合属性的顺序

调试

  • 使用 Elements 面板检查标签嵌套和页面结构
  • 使用 Styles 面板查看样式来源、覆盖和未生效规则
  • 根据控制台或 Network 面板定位资源路径错误

必做练习

  1. 个人介绍页:包含标题、照片、简介、兴趣列表和相关链接。
  2. 课程表页面:使用表格展示一周课程,至少包含一次单元格合并。
  3. 报名表单:包含文本、单选、多选、下拉、文本域和提交按钮。
  4. 新闻详情页:使用外部 CSS 设置标题、来源、时间、摘要、正文和图片样式。
  5. 路径练习:将图片分别放在当前目录、子目录和同级资源目录中并正确引用。

本周综合任务

独立完成一个个人博客文章页,包含顶部导航、文章信息、正文、相关链接和页脚。

要求:

  • 使用语义化标签组织主要区域
  • HTML 与 CSS 分文件存放
  • 至少包含图片、列表和链接
  • 不复制课程案例的完整代码
  • 页面能够直接打开,资源无加载失败

本周产出

  • 个人介绍页
  • 课程表页面
  • 报名表单
  • 新闻详情页
  • 个人博客文章页
  • 一份本周 HTML 标签和 CSS 属性笔记

完成检查

  • 能够不参考模板写出完整 HTML 骨架
  • 能够根据内容选择合适的 HTML 标签
  • 能够正确使用图片、链接、列表、表格和表单
  • 能够区分并正确编写相对路径和绝对路径
  • 能够使用外部 CSS 和类选择器组织样式
  • 能够使用开发者工具定位结构、样式和路径问题
  • 已独立完成个人博客文章页

第 2 周:CSS 盒模型与布局

本周目标

本周完成后,应能够:

  • 根据页面结构编写准确且易维护的选择器
  • 解释 CSS 层叠、继承和优先级导致的样式结果
  • 准确计算元素在盒模型中的实际尺寸
  • 处理外边距塌陷、内容溢出和父元素高度塌陷
  • 使用 Flex 完成导航、两栏、卡片列表和换行布局
  • 根据简单截图独立完成一个 PC 端页面布局

学习资料与范围

视频范围学习模块学习结果
P43-P52复合选择器、伪类、CSS 三大特性、背景和显示模式能够控制样式作用范围和元素显示方式
P53-P68结构伪类、伪元素、盒模型、版心、溢出、圆角和阴影能够准确控制组件尺寸与视觉效果
P69-P73标准流、浮动和清除浮动理解传统布局方式及其问题
P74-P80Flex 组成、轴、对齐、伸缩、换行和案例能够使用 Flex 完成常见布局

需要掌握的知识点

选择器与 CSS 规则

  • 后代、子代、并集、交集和兄弟选择器
  • :hover 等常见伪类选择器
  • :nth-child() 等结构伪类选择器
  • ::before::after 伪元素及 content
  • 层叠性、继承性和优先级
  • Emmet 的常用 HTML/CSS 快速写法

背景与显示模式

  • 背景颜色、图片、重复、位置和缩放
  • 背景复合属性及多层背景的基本概念
  • 块级、行内和行内块元素的特点
  • display 对元素显示模式的影响

盒模型

  • 内容区、内边距、边框和外边距
  • 标准盒模型的实际尺寸计算
  • box-sizing: border-box 的作用
  • 版心宽度和水平居中
  • 浏览器默认样式清除
  • 内容溢出与 overflow
  • 相邻外边距合并、父子外边距塌陷及处理方式
  • 圆角、盒子阴影和基础卡片效果

布局

  • 标准流中的块级和行内元素排列规律
  • 浮动元素的特点和典型使用场景
  • 清除浮动及父元素高度塌陷
  • Flex 容器、项目、主轴和交叉轴
  • flex-directionjustify-contentalign-items
  • flex 伸缩比例、flex-wrap 和多行对齐
  • Flex 项目的单独对齐和顺序控制

必做练习

  1. 导航栏:包含默认、悬停和当前选中状态。
  2. 产品卡片:严格按照给定宽高、内边距和边框完成盒模型计算。
  3. 新闻列表:处理长标题截断和内容溢出。
  4. 两栏布局:分别使用浮动和 Flex 实现,并说明两种方式的差异。
  5. 商品列表:使用 Flex 实现固定间距、自动换行和统一卡片尺寸。
  6. 问题复现:主动制造并修复外边距塌陷和浮动导致的父元素高度塌陷。

练习涉及图片、图标或具体页面内容时,统一从提供的官网蓝湖设计图中选取,不使用视频课程的配套素材。

本周综合任务

从官网蓝湖设计图中选取一个包含导航、内容列表或卡片的页面区域,完成其 PC 端基础布局。

要求:

  • 主体布局使用 Flex
  • 尺寸、版心和区域间距以蓝湖标注为准
  • 卡片可以换行且尺寸稳定
  • 不使用表格布局,不大量使用绝对定位
  • 页面不存在内容溢出、遮挡或意外横向滚动

本周产出

  • 导航栏、产品卡片和新闻列表组件
  • 浮动版与 Flex 版两栏布局
  • 外边距塌陷和浮动问题调试记录
  • 官网蓝湖设计图局部布局
  • 一份盒模型和 Flex 属性笔记

完成检查

  • 能够解释层叠、继承和优先级
  • 能够准确计算盒模型尺寸
  • 能够处理外边距塌陷和内容溢出
  • 能够说明浮动后父元素高度塌陷的原因
  • 能够使用 Flex 完成单行、多行和两栏布局
  • 已独立完成 PC 页面布局综合练习

第 3 周:PC 端网页综合布局

本周目标

本周完成后,应能够:

  • 按“分析设计、划分区域、搭建结构、编写样式、对照调试”的流程制作 PC 网页
  • 使用版心和公共样式保持多个区域的一致性
  • 正确选择相对、绝对和固定定位
  • 使用字体图标、精灵图和过渡效果完善页面细节
  • 组织重复卡片和公共区域,减少无意义的重复代码
  • 使用蓝湖提供的标注和素材完成官网 PC 端主要区域

学习资料与范围

视频范围学习模块学习结果
P81-P93PC 页面项目制作流程掌握目录、版心、头部、Banner、内容区和页脚的制作方法
P94-P105定位、层叠、精灵图、字体图标、过渡和轮播图能够实现常见悬浮与装饰效果
P106-P119PC 项目目录、SEO、头部和底部能够组织项目公共区域与样式
P120-P130PC 项目主体区域能够完成较长、多模块的官网页面

视频中的项目只用于观察实现步骤,不要求下载课程素材或完成对应案例。所有编码实践均使用提供的官网蓝湖设计图和可导出资源。

需要掌握的知识点

页面分析与组织

  • 从截图或设计图识别版心、通栏、公共区域和重复模块
  • 先搭建 HTML 结构,再完成布局,最后处理视觉细节
  • 按页面区域拆分 CSS,避免选择器互相影响
  • 为导航、卡片、标题区和按钮等重复结构提取公共类
  • 图片和图标资源的分类、命名和引用

定位与层叠

  • 相对定位保留原位置的特点
  • 绝对定位的包含块和“子绝父相”
  • 固定定位相对视口的行为
  • z-index 生效条件和层叠顺序
  • 定位居中、角标、悬浮按钮和覆盖文字
  • 避免使用绝对定位承担整个页面主体布局

页面细节技术

  • CSS 精灵图的定位方式和适用场景
  • 字体图标的引入和使用
  • 图片与文字的垂直对齐
  • opacity、光标类型和悬停反馈
  • transition 的属性、时长和触发方式
  • 静态轮播图区域的结构和层叠关系

工程基础

  • 项目目录、公共 CSS 和页面 CSS
  • titledescriptionkeywords 等基础页面信息
  • Favicon 的配置
  • Header、导航、搜索、购物车和 Footer 等公共区域
  • 长页面中的样式复用和命名一致性

必做练习

  1. 分析官网蓝湖设计图,整理页面清单、版心、公共区域和重复模块。
  2. 使用蓝湖导出的 Logo、图片和图标完成官网 Header、导航和 Banner。
  3. 完成设计图中的主要内容区域、重复卡片和 Footer。
  4. 根据设计图中的元素完成固定按钮、角标或覆盖文字;设计图没有对应元素时不强行添加。
  5. 为设计图中具有交互含义的导航、按钮或卡片补充合理的悬停过渡效果。
  6. 检查官网页面中的重复样式,至少完成一次公共样式整理。

本周综合任务

根据官网蓝湖设计图,完成一个 PC 页面中的 Header、全部主要内容区域和 Footer。

要求:

  • 编码前先画页面结构草图
  • 不使用视频课程的源码和素材
  • 页面资源均来自蓝湖设计图或蓝湖导出文件
  • 公共区域和重复卡片样式得到复用
  • 版心、布局、间距和对齐符合蓝湖标注
  • 能够解释每处定位的参照对象和使用原因

本周产出

  • 官网蓝湖设计图页面清单和结构草图
  • 官网 PC 端公共头部、主体区域和页脚
  • 使用蓝湖元素完成的定位与悬浮效果组件
  • 一次公共样式和重复组件整理记录
  • 一份 PC 网页制作流程总结

完成检查

  • 已完成官网蓝湖设计图要求的 PC 端主要区域
  • 页面图片、图标和文字资源均来自蓝湖设计图或导出文件
  • 能够正确选择相对、绝对和固定定位
  • 能够组织公共样式和重复卡片样式
  • 能够从蓝湖设计图中划分结构和布局层次
  • 未依赖课程源码或课程配套素材

第 4 周:CSS3、移动端与响应式

本周目标

本周完成后,应能够:

  • 使用变换、过渡和关键帧动画实现基础视觉效果
  • 解释移动端视口、物理像素、CSS 像素和二倍图
  • 使用 rem 或 vw 完成移动端页面适配
  • 使用 Less 的变量、嵌套、运算和导入组织样式
  • 使用媒体查询处理手机与桌面布局差异
  • 理解 Bootstrap 栅格的基本思想,但不依赖它完成阶段项目
  • 独立完成一个无横向滚动的响应式页面

学习资料与范围

视频范围学习模块学习结果
P131-P144平面变换、转换原点、渐变和案例能够实现常见二维视觉效果
P145-P1563D 变换、关键帧动画和综合案例能够实现基础 3D 与动画效果
P157-P172移动端、rem、flexible 和 Less能够使用 rem 组织移动端页面
P173-P184vw/vh 移动端布局能够使用 vw 完成移动端适配
P185-P200媒体查询、Bootstrap 和响应式项目能够理解并实现响应式页面

视频中的 3D、移动端和响应式案例只用于理解知识点,不要求下载课程素材或还原案例。练习统一选用官网蓝湖设计图中的文字、图片、图标和页面模块。

需要掌握的知识点

变换、过渡与动画

  • translaterotatescaleskew
  • transform-origin 和多重变换的执行顺序
  • 使用平移实现未知尺寸元素居中
  • 线性渐变和径向渐变
  • 3D 视距、空间旋转和立体呈现
  • @keyframesanimation 常用属性
  • 过渡和动画的区别及适用场景

移动端基础

  • 屏幕分辨率、物理像素和 CSS 像素
  • 视口的概念和标准 viewport 配置
  • 二倍图的使用原因和显示方式
  • 固定宽度、rem、vw/vh 和响应式方案的差异
  • 移动端固定头部、内容避让和点击区域
  • 图片在不同屏幕下保持比例的方法

rem、vw/vh 与 Less

  • rem 相对于根元素字号的计算方式
  • 使用媒体查询改变根元素字号
  • flexible 适配方案的基本原理
  • vw/vh 与视口尺寸的换算
  • Less 变量、嵌套、运算、导入和导出
  • 将设计稿尺寸转换为 rem 或 vw 的思路

响应式布局

  • 媒体查询的条件和常见断点思路
  • 不同宽度下的显示、隐藏、换行和列数变化
  • 移动优先与桌面优先的基本区别
  • Bootstrap 容器、栅格、断点、全局样式和组件
  • 不依赖框架使用原生 CSS 实现响应式布局

必做练习

  1. 从蓝湖官网中选择图片卡片和图标,完成缩放、旋转或悬停过渡练习。
  2. 使用蓝湖官网的导航内容完成变换练习;设计图未要求 3D 效果时,只在独立练习文件中验证属性。
  3. 选取蓝湖官网的一个页面,使用其内容和资源制作移动端适配练习。
  4. 使用蓝湖官网的卡片或列表,分别练习 rem 和 vw 两种尺寸换算方式。
  5. 使用媒体查询让蓝湖官网中的导航或卡片区域适配手机与桌面宽度。
  6. 使用原生 CSS 完成蓝湖官网页面的响应式练习,不使用 Bootstrap。

本周综合任务

使用官网蓝湖设计图中的导航、Banner 和卡片内容,完成一个响应式练习页面。

要求:

  • 至少适配手机和桌面两类宽度
  • 使用原生 CSS,不使用 Bootstrap
  • 页面文字、图片和图标使用蓝湖设计图及其导出资源
  • 手机端和桌面端均无意外横向滚动
  • 图片比例稳定,文字不遮挡、不溢出
  • 卡片列数能随可用宽度合理变化
  • 动画只用于必要反馈,不影响内容阅读

本周产出

  • 使用蓝湖图片、图标完成的变换与动画练习组件
  • 使用蓝湖页面内容完成的 rem 和 vw 适配练习
  • 使用蓝湖页面内容完成的媒体查询练习
  • 官网蓝湖设计图响应式练习页面
  • 一份移动端适配方案对比笔记

完成检查

  • 已完成课程 P131-P200
  • 能够使用变换、过渡和关键帧动画
  • 能够说明视口和二倍图的作用
  • 能够使用 rem 或 vw 完成移动端布局
  • 能够编写基础媒体查询
  • 已独立完成响应式介绍页

第 5 周:官网蓝湖设计图还原与验收

本周目标

本周在前几周实现结果的基础上完成最终校对和交付。完成后,应能够:

  • 从蓝湖设计图中读取页面尺寸、颜色、字体、间距、圆角和切图信息
  • 在编码前完成页面区域划分、公共结构识别和资源整理
  • 使用语义化 HTML、标准流和 Flex 搭建页面主体
  • 合理划分公共样式与页面样式,复用重复组件
  • 使用设计图对比和浏览器开发者工具定位视觉偏差
  • 独立交付一个结构完整、视觉接近设计图的纯静态官网

项目约束

  • 使用提供的蓝湖设计图作为唯一视觉标准
  • 仅使用 HTML 和 CSS,不使用 JavaScript、前端框架或 UI 组件库
  • 本项目不要求使用 Git,也不要求提交至 GitHub
  • 必须独立完成,不直接复制现成网站源码

需要掌握的知识点

设计图分析

  • 确认页面数量、入口、目标尺寸和页面之间的关系
  • 区分通栏背景、版心内容、公共区域和重复模块
  • 读取宽高、间距、字体、行高、颜色、边框、圆角和阴影
  • 判断图片应作为内容图片还是 CSS 背景
  • 识别导航、按钮和卡片的默认、悬停、选中等状态
  • 在编码前画出页面结构草图

资源管理

  • 从蓝湖导出合适格式和清晰度的图片、图标等资源
  • 按图片、图标、字体等类型分类存放
  • 使用表达用途的英文或拼音命名资源
  • 避免重复资源、临时截图和无用文件进入最终目录
  • 检查相对路径,保证移动整个项目后仍能正常运行

页面实现

  • 使用合适的语义化标签组织 Header、导航、主体和 Footer
  • 使用版心、标准流和 Flex 完成主要布局
  • 仅在覆盖、角标和悬浮等场景中使用定位
  • 提取公共颜色、字体、按钮、卡片和标题样式
  • 控制图片比例、文字换行、内容溢出和固定区域尺寸
  • 保持选择器范围清晰,避免页面样式互相污染

视觉检查与调试

  • 在设计图对应的浏览器尺寸下对比页面
  • 按整体布局、区域尺寸、间距、文字、颜色和装饰的顺序检查
  • 使用 Elements、Styles 和 Computed 面板定位偏差来源
  • 使用 Network 面板检查图片、字体和样式资源
  • 建立问题清单,逐项记录、修复和复查

项目任务

  1. 设计分析:输出页面清单、设计标注表和结构草图。
  2. 资源整理:导出并分类存放全部项目资源。
  3. 项目初始化:建立 HTML、公共 CSS、页面 CSS 和资源目录。
  4. 公共区域:完成公共头部、导航和页脚。
  5. 主体区域:完成设计图要求的全部页面和内容模块。
  6. 状态样式:补充设计中存在的悬停、选中等状态。
  7. 视觉对比:输出设计图与实现页面的对比截图和问题清单。
  8. 最终整理:清除临时内容、无效样式和无用资源,提交完整目录。

本周产出

  • 页面清单和结构草图
  • 蓝湖关键标注记录
  • 分类清晰的资源目录
  • 纯静态官网完整源码
  • 设计图与实现页面的对比截图
  • 已关闭的视觉问题清单

验收标准

页面完整性

  • 设计图要求的页面和区域全部完成
  • 文案、图片、图标和链接无遗漏
  • 直接打开入口 HTML 后能够正常访问页面
  • 图片、字体和样式资源全部加载成功

视觉还原

  • 在指定浏览器和设计尺寸下,整体布局与设计图一致
  • 版心、主要区域尺寸和对齐方式符合蓝湖标注
  • 字体、字号、行高、颜色、背景、边框和圆角符合标注
  • 页面无明显错位、遮挡、溢出、图片拉伸或意外横向滚动

代码质量

  • HTML 结构清晰,主要区域使用合适的语义化标签
  • CSS 按公共样式和页面样式合理组织
  • 重复样式得到复用,类名能够表达用途
  • 未大量使用无意义的绝对定位完成主体布局
  • 项目中没有调试代码、临时资源和无效文件

第 6 周:JavaScript 基础与控制台版 2048

本周目标

本周完成后,应能够:

  • 使用变量、数据类型和运算符表达程序状态与计算过程
  • 使用条件和循环解决基础流程问题
  • 使用数组和对象组织一组数据
  • 使用函数拆分逻辑并减少重复代码
  • 使用常用字符串、数组、Math 和日期能力处理数据
  • 阅读基础错误信息,并使用控制台和断点定位问题
  • 综合使用数组、对象和纯函数完成可操作的控制台版 2048

学习资料

JavaScript 参考视频待定。当前按以下知识范围和练习任务执行,确定课程后再补充视频章节映射。

需要掌握的知识点

运行环境与语法基础

  • JavaScript 在浏览器中的运行方式
  • 内部脚本和外部脚本的引入方式
  • console.log()、浏览器控制台和基础断点
  • 语句、表达式、注释和代码块
  • letconst 的使用场景和命名规范

数据类型与运算

  • 字符串、数字、布尔值、undefinednull
  • typeof 和基础类型判断
  • 显式与隐式类型转换
  • 算术、赋值、比较和逻辑运算符
  • ===== 的区别,默认使用严格相等
  • 模板字符串和字符串拼接

流程控制

  • ifelse ifelse
  • switch 的使用场景
  • forwhile 循环
  • breakcontinue
  • 循环边界、初始化条件和终止条件
  • 使用流程图或伪代码描述复杂判断

数组

  • 数组创建、索引、长度和遍历
  • 数组元素的增加、删除和修改
  • pushpopshiftunshiftsplice
  • 查找、筛选、转换和汇总的基本思路
  • 二维数组的结构和遍历

纯函数与二维数组处理

  • 函数的结果只由参数决定,不依赖或修改外部状态
  • 返回新数组,不直接修改传入的数组
  • 使用嵌套循环遍历二维数组
  • 比较两个二维数组的内容是否一致
  • 将复杂规则拆分为多个可单独测试的小函数

函数

  • 函数声明、函数表达式和箭头函数
  • 参数、默认值、返回值和提前返回
  • 局部作用域与外部变量
  • 将复杂问题拆分为多个职责单一的函数
  • 回调函数的基本概念

对象与常用能力

  • 对象、属性、方法和遍历
  • 数组与对象组合的数据结构
  • 字符串常用方法
  • Math 的随机数、取整和极值能力
  • 日期对象的基础使用
  • 解构和展开语法

调试与代码质量

  • SyntaxErrorReferenceErrorTypeError 等基础错误
  • 使用日志缩小问题范围
  • 使用断点观察变量和执行顺序
  • 变量、函数命名和适当的函数长度
  • 为练习准备输入、预期输出和实际输出

控制台输入与输出

  • 使用 console.table() 输出二维棋盘
  • 使用 console.clear() 清理上一轮输出
  • 使用 prompt() 接收玩家指令
  • 对输入进行大小写转换和合法性检查
  • 使用循环维持游戏流程,并提供明确的退出条件

必做练习

以下练习用于掌握 JavaScript 基础,同时为控制台版 2048 准备可复用函数。

  1. 方向指令判断:实现 isValidDirection(input),判断输入是否为 WASD,不区分大小写。
  2. 创建空棋盘:实现 createEmptyBoard(size = 4),使用循环返回指定尺寸的二维数组,所有位置初始值为 0。
  3. 统计空位数量:实现 countEmptyCells(board),使用嵌套循环统计二维棋盘中 0 的数量。
  4. 查找最大数字:实现 getMaxTile(board),返回棋盘中的最大数字;空棋盘返回 0。
  5. 反转一行数字的位置:实现 reverseLine(line),将数组元素按照原位置从后往前重新排列。反转只改变元素顺序,不修改数字本身,也不是按数字大小排序。例如,输入 [2, 0, 4, 8],输出 [8, 4, 0, 2];输入 [2, 2, 4, 0],输出 [0, 4, 2, 2]。函数必须返回新数组,不能修改传入数组。
  6. 复制二维棋盘:实现 cloneBoard(board),修改返回的棋盘时不能影响原棋盘。
  7. 提取指定列:实现 getColumn(board, colIndex),把二维棋盘中的指定列提取为一维数组。
  8. 写回指定列:实现 setColumn(board, colIndex, column),把一维数组写入指定列,并返回新棋盘。
  9. 随机整数:实现 randomIndex(length),返回 0length - 1 之间的随机整数;length 不合法时返回明确结果。
  10. 记录测试结果:为以上每个函数至少准备一个正常用例和一个边界用例,记录输入、预期输出和实际输出。

这些练习分别对应后续综合任务中的输入校验、棋盘初始化、空位查找、左右移动、上下移动、状态复制和随机数字生成。

本周综合任务:控制台版 2048

使用原生 JavaScript 实现一个可以在浏览器控制台中运行的基础可玩版 2048。游戏使用 console.table() 显示棋盘,使用 prompt() 接收操作。

难度评估:中等,约为完整版本的 60%-70%。完成上述必做练习后,大部分辅助函数可以直接复用。应按以下任务顺序逐步实现,每完成一个函数先通过测试,再进入下一项任务。

输入约定:本综合任务按标准 2048 棋盘验收。line 参数为长度 4 的一维数组,元素为 0 或正整数;board 参数为 4×4 二维数组,每个格子为 0 或正整数;玩家指令为字符串或关闭输入框得到的 null

任务一:压缩一行数字

实现 compactLine(line),将所有非零数字移动到左侧,并在右侧补零。

  • 函数签名:compactLine(line)
  • 输入:长度 4 的一维数组 line,表示棋盘中的一行,例如 [2, 0, 2, 4]
  • 输出:新的同长度一维数组,非零数字保持原相对顺序并移动到左侧,例如 [2, 2, 4, 0]
  • 约束:返回新数组,保持传入的 line 不变
查看提示

先使用 filter() 或循环取出所有非零数字,再根据缺少的数量补 0。复制数组后再处理,避免修改参数。

任务二:向左合并一行数字

实现 mergeLineLeft(line),返回合并后的数组。一次移动中,每个数字最多参与一次合并。

  • 函数签名:mergeLineLeft(line)
  • 输入:长度 4 的一维数组 line,表示移动前的一行数字
  • 输出:新的同长度一维数组,表示向左移动并合并后的结果
  • 示例:[2, 2, 2, 2] 返回 [4, 4, 0, 0]
  • 示例:[2, 2, 4, 0] 返回 [4, 4, 0, 0]
  • 示例:[4, 0, 4, 4] 返回 [8, 4, 0, 0]
  • 示例:[0, 0, 0, 0] 返回 [0, 0, 0, 0]
  • 约束:返回新数组,保持传入的 line 不变
查看提示

先压缩,再从左向右扫描;发现相邻数字相同时合并,并让索引额外前进一步,避免同一个数字连续合并两次。

任务三:查找所有空位

实现 getEmptyCells(board),返回 4×4 棋盘中所有值为 0 的位置。每个位置使用 { row, col } 表示。

  • 函数签名:getEmptyCells(board)
  • 输入:4×4 二维数组 board,表示当前棋盘
  • 输出:数组,每一项是一个空位坐标对象 { row, col }
  • 示例:输入 [[2, 0, 0, 0], [0, 4, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]],输出包含 { row: 0, col: 1 }{ row: 1, col: 0 } 等空位
  • 边界:没有空位时输出空数组 []
查看提示

在必做练习 countEmptyCells() 的两层循环基础上,把“数量加一”改为将 { row, col } 加入结果数组。

任务四:比较两个棋盘

实现 boardsEqual(boardA, boardB),逐项比较两个二维数组。尺寸或任意数字不同都返回 false

  • 函数签名:boardsEqual(boardA, boardB)
  • 输入:两个二维数组 boardAboardB;主要用于比较两个 4×4 棋盘,也要能识别尺寸不同的情况
  • 输出:布尔值;完全一致返回 true,否则返回 false
  • 示例:boardsEqual([[2, 0]], [[2, 0]]) 返回 true
  • 示例:boardsEqual([[2, 0]], [[0, 2]]) 返回 false
  • 边界:行数不同、列数不同都返回 false
查看提示

先比较行数和每行长度,再逐项比较;发现不同后立即返回 false

任务五:判断是否达到目标数字

实现 hasTarget(board, target = 2048),判断棋盘中是否存在目标数字。

  • 函数签名:hasTarget(board, target = 2048)
  • 输入:4×4 二维数组 board;可选正整数 target,默认值为 2048
  • 输出:布尔值;棋盘中存在目标数字返回 true,否则返回 false
  • 示例:hasTarget([[2, 4, 8, 16], [32, 64, 128, 256], [512, 1024, 2048, 0], [0, 0, 0, 0]]) 返回 true
  • 示例:hasTarget([[2, 4, 8, 16], [32, 64, 128, 256], [512, 1024, 0, 0], [0, 0, 0, 0]], 2048) 返回 false
查看提示

可以使用两层循环,也可以组合 some();找到目标后不需要继续遍历。

任务六:判断是否还可以移动

实现 canMove(board)。满足以下任意条件时返回 true

  • 棋盘中仍有空位
  • 水平方向存在相邻且相同的数字
  • 垂直方向存在相邻且相同的数字

只需要向右和向下检查相邻位置,避免重复判断或数组越界。

  • 函数签名:canMove(board)
  • 输入:4×4 二维数组 board,表示当前棋盘
  • 输出:布尔值;仍可移动返回 true,不能移动返回 false
  • 示例:canMove([[2, 0, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]]) 返回 true
  • 示例:canMove([[2, 4, 2, 4], [4, 2, 4, 2], [2, 4, 2, 4], [4, 2, 4, 2]]) 返回 false
  • 示例:canMove([[2, 2, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]]) 返回 true
查看提示

先调用 getEmptyCells() 判断是否存在空位;没有空位时,只比较当前位置与右侧、下方的数字。

任务七:判断游戏是否失败

实现 isGameOver(board)。棋盘没有空位,并且水平方向、垂直方向都不存在可合并数字时,返回 true

  • 函数签名:isGameOver(board)
  • 输入:4×4 二维数组 board,表示当前棋盘
  • 输出:布尔值;游戏失败返回 true,否则返回 false
  • 示例:isGameOver([[2, 4, 2, 4], [4, 2, 4, 2], [2, 4, 2, 4], [4, 2, 4, 2]]) 返回 true
  • 示例:isGameOver([[2, 2, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]]) 返回 false
  • 示例:isGameOver([[2, 0, 4, 8], [16, 32, 64, 128], [256, 512, 1024, 2], [4, 8, 16, 32]]) 返回 false
查看提示

不要重复编写判断规则,可以直接复用 canMove() 并对结果取反。

任务八:实现四个方向移动

mergeLineLeft() 的基础上实现 moveLeft()moveRight()moveUp()moveDown()。每次移动返回新棋盘及棋盘是否变化。

  • 函数签名:moveLeft(board)moveRight(board)moveUp(board)moveDown(board)
  • 输入:4×4 二维数组 board,表示移动前的棋盘
  • 输出:对象 { board: newBoard, changed }
  • 输出说明:newBoard 是移动后的新棋盘;changed 是布尔值,表示棋盘是否发生变化
  • 示例:moveLeft([[2, 0, 2, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]) 输出 { board: [[4, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], changed: true }
  • 示例:moveLeft([[2, 4, 8, 16], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]) 输出 changed: false
  • 约束:返回新棋盘,保持传入的 board 不变
查看提示

复用必做练习中的 reverseLine()getColumn()setColumn()。向右移动可以先反转每一行,左移后再反转;上下移动可以先提取一列,按一行处理后再写回新棋盘。先完成左右,再处理上下。

任务九:生成随机数字

实现 addRandomTile(board),随机选择一个空位并生成数字 2

  • 函数签名:addRandomTile(board)
  • 输入:4×4 二维数组 board,表示生成新数字前的棋盘
  • 输出:新的二维数组,在一个随机空位上写入数字 2
  • 示例:输入一个全 0 的 4×4 棋盘,输出棋盘中应只有一个位置是 2,其他位置仍是 0
  • 边界:如果没有空位,返回与输入内容一致的新棋盘
  • 约束:返回新棋盘,保持传入的 board 不变
查看提示

复用 getEmptyCells()randomIndex()cloneBoard(),先选择随机空位并复制棋盘,再写入数字。

任务十:初始化游戏

创建 4×4 空棋盘,并随机生成两个初始数字。

  • 函数签名:initGame()
  • 输入:无
  • 输出:4×4 二维数组,包含两个随机生成的数字 2
  • 示例:输出棋盘中应有 2 个非零格子,并且这 2 个格子的值都为 2
  • 约束:两个初始数字不能出现在同一个格子
查看提示

复用必做练习中的 createEmptyBoard(),再连续调用两次 addRandomTile() 生成初始棋盘。

任务十一:实现控制台游戏循环

使用循环输出棋盘和操作提示,并通过 prompt() 接收指令:W 上、A 左、S 下、D 右。指令不区分大小写。

  • 函数建议:startGame()
  • 输入:玩家通过 prompt() 输入的字符串,例如 WASD;关闭输入框时输入值为 null
  • 输出:通过 console.table() 输出当前棋盘;通过 alert()console.log() 输出无效输入、胜利或失败提示
  • 流程输出:每次有效移动后展示更新后的棋盘
  • 边界:无效指令保持棋盘不变;无效移动保持棋盘不变;关闭输入框时结束脚本
查看提示

先将输入统一转换为大写,再使用对象映射或 switch 选择移动函数。根据移动结果中的 changed 判断是否生成新数字;关闭输入框时可以结束脚本。

任务十二:完成胜负流程

出现 2048 时提示胜利;棋盘无法继续移动时提示失败,随后结束游戏循环。

  • 函数建议:在 startGame() 中调用 hasTarget()isGameOver()
  • 输入:每次有效移动并生成新数字后的棋盘
  • 输出:胜利时输出明确胜利提示并结束循环;失败时输出明确失败提示并结束循环
  • 示例:棋盘中出现 2048 时,输出 你赢了
  • 示例:isGameOver(board)true 时,输出 游戏结束
  • 约束:胜负判断应发生在棋盘状态更新之后
查看提示

一次有效移动的顺序应为“移动 -> 判断棋盘变化 -> 生成数字 2 -> 检查胜负 -> 输出新棋盘”。

实现要求

  • 每个函数只负责一个明确任务
  • 使用控制台完成输入输出
  • 通过函数参数和返回值传递游戏状态
  • 不直接修改传入的数组或棋盘
  • 核心函数至少包含一个正常用例和一个边界用例
  • 游戏逻辑与控制台输入输出分开组织
  • 游戏代码放入 console-2048.js
  • 核心逻辑测试放入 console-2048.test.js 或独立测试区域

本周产出

  • 2048 JavaScript 基础练习及测试记录
  • 可实际游玩的控制台版 2048
  • 2048 核心逻辑测试记录
  • 一份错误与调试记录
  • 一份 JavaScript 与 C 语言差异笔记

完成检查

  • 能够区分 letconst
  • 能够正确使用条件、循环和函数
  • 能够选择数组或对象组织数据
  • 能够把长逻辑拆成多个职责清晰的函数
  • 能够使用控制台和断点定位基础错误
  • 已完成可实际游玩的控制台版 2048
  • 支持四向移动、固定生成数字 2 及胜负判断
  • 无效输入和无效移动不会改变棋盘
  • 核心逻辑未直接修改输入数据
  • 每个 2048 核心函数均具有可重复执行的测试用例

第 7 周:DOM、Git 与 2048 网页化

本周目标

本周完成后,应能够:

  • 使用 DOM 查询、修改、创建和删除页面元素
  • 使用事件监听实现点击和键盘交互
  • 解释事件对象、事件冒泡和阻止默认行为
  • 使用 Git 完成暂存、提交、查看历史和推送
  • 将第 6 周的控制台版 2048 迁移为网页界面
  • 将游戏数据、移动逻辑和页面渲染分离
  • 复用已完成的四向移动、合并和状态判断逻辑,并补充计分与重新开始

学习资料

JavaScript 参考视频待定。DOM 相关视频范围将在课程确定后补充;Git 使用基础命令完成本周项目管理。

需要掌握的知识点

DOM 操作

  • DOM 树及 HTML 与节点的关系
  • querySelectorquerySelectorAll
  • 文本内容、HTML 内容和表单值
  • 元素属性、自定义属性、样式和 classList
  • 创建、追加、插入和删除节点
  • 遍历节点集合并批量更新页面

事件

  • addEventListener 和事件处理函数
  • 点击、输入和键盘事件
  • 事件对象及按键判断
  • 事件冒泡和事件委托的基本概念
  • 阻止默认行为
  • 避免重复绑定事件

Git 与 GitHub

  • 仓库、工作区、暂存区和提交历史
  • git initgit statusgit addgit commitgit log
  • .gitignore 的用途
  • 创建 GitHub 仓库、关联远程仓库和推送代码
  • 使用清晰提交信息描述已完成的功能
  • 每完成一个独立功能进行一次提交

2048 状态建模

  • 复用第 6 周控制台版的 4×4 棋盘和初始化逻辑
  • 根据棋盘数据渲染 DOM
  • 页面只负责显示,JavaScript 数据作为游戏状态来源
  • 复用第 6 周的棋盘比较函数,判断移动是否有效

移动与合并算法

  • 复用第 6 周的 compactLine()mergeLineLeft()
  • 扩展单行合并结果,将合并产生的数字计入当前分数
  • 使用反转、行列转换等方法处理不同移动方向
  • 将单行算法扩展到左、右、上、下四个方向

随机数字生成

  • 复用第 6 周的空位查找和随机数字函数
  • 在固定生成数字 2 的基础上,增加小概率生成数字 4
  • 仅在棋盘发生有效变化后生成新数字
  • 棋盘无空位时不执行生成操作

必做练习

  1. 实现点击切换内容的标签页。
  2. 实现支持添加、完成和删除的待办事项列表。
  3. 实现方向键控制页面方块移动。
  4. 创建 2048 Git 仓库和 GitHub 远程仓库。
  5. 将第 6 周的棋盘状态接入数据驱动的 DOM 渲染。
  6. 复用控制台版的移动、合并和胜负判断函数,并增加计分。
  7. 使用键盘事件替换 prompt() 指令输入。
  8. 增加重新开始按钮及游戏状态重置。
  9. 增加小概率生成数字 4,并保证核心合并规则不变。

核心规则测试

  • [2, 2, 2, 2] 左移得到 [4, 4, 0, 0]
  • [2, 2, 4, 0] 左移得到 [4, 4, 0, 0]
  • [4, 0, 4, 4] 左移得到 [8, 4, 0, 0]
  • [0, 0, 0, 0] 左移后保持不变
  • 只有位置变化但没有合并时,分数不增加
  • 棋盘没有变化时,不生成新数字

Git 提交要求

本周至少通过独立提交体现以下开发步骤:

  • 初始化项目结构和页面
  • 完成棋盘数据与渲染
  • 迁移第 6 周控制台版核心逻辑
  • 完成 DOM 棋盘渲染
  • 使用键盘事件完成四向控制
  • 完成计分、重新开始和数字 4 的随机生成

本周产出

  • 标签页与待办事项 DOM 练习
  • 2048 GitHub 仓库
  • 可以操作的 2048 网页游戏主体
  • 核心移动规则测试记录
  • 一份游戏输入、状态更新和页面渲染流程图

完成检查

  • 能够使用 DOM 和事件实现基础交互
  • 棋盘数据与页面展示保持一致
  • 四个方向均可正常移动和合并
  • 一次移动中每个方块最多参与一次合并
  • 无效移动不会生成新数字
  • 能够正确计分并通过按钮重新开始
  • Git 提交能够体现主要功能的开发过程
  • 2048 已推送至 GitHub

第 8 周:2048 蓝湖设计图还原与验收

本周目标

本周完成后,应能够:

  • 使用第 7 周完成的计分与重新开始功能,完成完整游戏流程
  • 使用本地存储保存并恢复最高分
  • 根据提供的 2048 蓝湖设计图完成游戏界面还原
  • 编写稳定、不因数字和状态变化而错位的游戏界面
  • 为核心规则设计并执行明确的测试用例
  • 根据测试结果定位并修复逻辑问题
  • 整理代码结构、Git 提交和 GitHub 项目说明
  • 独立讲解 2048 的状态、移动算法和渲染流程

需要掌握的知识点

蓝湖设计图分析

  • 确认设计图对应的页面尺寸和目标浏览器宽度
  • 读取棋盘、方块、间距、圆角、颜色、字体和阴影标注
  • 导出设计图中的图片、图标和字体等资源
  • 划分标题区、分数区、操作区、棋盘和状态提示区域
  • 识别默认、胜利、失败和重新开始等界面状态
  • 使用对比截图记录并修复视觉偏差

分数与状态

  • 仅在数字合并时增加当前分数
  • 每次合并增加新方块对应的数值
  • 区分进行中、胜利和失败状态
  • 复用第 6 周的 hasTarget() 进行胜利判断
  • 复用第 6 周的 isGameOver() 进行失败判断
  • 避免游戏结束后继续修改状态

游戏生命周期

  • 初始化棋盘和两个随机数字
  • 处理一次用户输入和完整状态更新
  • 重新开始时清空棋盘、当前分数和提示状态
  • 在合适时机保留或更新最高分
  • 处理连续点击重新开始等重复操作

本地存储

  • localStorage 的读取、写入和删除
  • 字符串与数字之间的转换
  • 首次访问时不存在存储值的处理
  • 存储值异常时使用合理默认值
  • 刷新页面后恢复最高分

界面稳定性

  • 棋盘和方块尺寸、间距、颜色及圆角符合蓝湖标注
  • 不同数字的字体和背景色符合蓝湖设计
  • 当前分数、最高分、状态提示和按钮布局符合设计图
  • 文本不会遮挡棋盘或操作区域
  • 在设计图对应尺寸下无明显错位或溢出
  • 控制台无错误,图片和样式资源无加载失败

测试与调试

  • 为移动函数准备确定的棋盘输入和预期输出
  • 分别测试正常情况、边界情况和无效操作
  • 记录实际结果与预期结果的差异
  • 修复问题后重新执行全部规则测试
  • 临时测试入口在最终提交前移除

代码与项目整理

  • 将状态、移动、渲染、输入和存储逻辑合理拆分
  • 函数和变量名称能够表达实际用途
  • 删除调试日志、重复代码和无用资源
  • README 包含项目介绍、功能、运行方式、操作方法和截图
  • 最终代码推送至 GitHub

必做任务

  1. 分析 2048 蓝湖设计图,整理页面结构、关键标注和资源清单。
  2. 根据设计图调整第 7 周完成的 HTML 结构和页面区域。
  3. 根据蓝湖标注完成标题、分数区、操作区、棋盘、方块、提示和按钮样式。
  4. 检查并完善当前分数、最高分、胜利、失败、重新开始和状态提示。
  5. 使用 localStorage 保存并恢复最高分。
  6. 在设计图对应尺寸下截图对比,并逐项修复视觉偏差。
  7. 执行全部规则测试并记录结果。
  8. 整理核心函数、命名、目录和静态资源。
  9. 编写项目 README 并推送最终代码。
  10. 准备一次 5 分钟项目讲解。

功能验收

  • 使用 HTML、CSS 和原生 JavaScript 开发,未使用游戏框架
  • 使用 4×4 棋盘,通过键盘方向键控制移动
  • 开始游戏时随机生成两个数字方块
  • 仅在有效移动后于空白位置生成新数字
  • 相同数字按照 2048 规则合并并正确累计分数
  • 支持胜利、失败判定和重新开始
  • 使用本地存储保存并恢复最高分

规则测试

  • [2, 2, 2, 2] 向左移动后得到 [4, 4, 0, 0]
  • [4, 4, 8, 0] 向左移动后得到 [8, 8, 0, 0]
  • [2, 2, 4, 0] 向左移动后得到 [4, 4, 0, 0],不能连续合并为 8
  • [4, 0, 4, 4] 向左移动后得到 [8, 4, 0, 0]
  • 仅移动位置但未合并时,分数不增加
  • 棋盘状态没有变化时,不生成新数字
  • 棋盘填满且不存在可合并的相邻数字时,游戏失败
  • 出现 2048 方块时,显示胜利状态
  • 重新开始后,棋盘和当前分数正确重置
  • 刷新页面后,最高分能够正确恢复

工程验收

  • 使用 Git 管理项目,提交记录能够体现主要开发过程
  • 最终代码已推送至 GitHub
  • 仓库包含项目介绍、运行方式、操作说明和截图
  • HTML、CSS 和 JavaScript 文件职责清晰
  • 核心移动和合并逻辑已拆分为独立函数
  • 页面无明显错位、遮挡或控制台报错
  • 能够独立讲解棋盘状态、移动合并算法和渲染流程

视觉验收

  • 页面结构和区域顺序与 2048 蓝湖设计图一致
  • 棋盘、方块、间距、圆角和阴影符合蓝湖标注
  • 字体、字号、文字颜色和背景颜色符合设计图
  • 分数、按钮和状态提示在内容变化时不会引起布局跳动
  • 页面无明显错位、遮挡、溢出或资源加载失败
  • 已提供设计图与最终页面的对比截图

本周产出

  • 2048 最终验收版本
  • 完整的规则测试记录
  • 蓝湖设计图标注记录和视觉对比截图
  • 包含说明和截图的 GitHub 仓库
  • 一份阶段一知识复盘和待补强清单
  • 两个阶段项目的口头讲解提纲
graph LR
    %% ===== 根节点 =====
    HTML["HTML 知识树"]

    %% ===== 一级分支 =====
    HTML --> Basic["① 文档基础"]
    HTML --> Text["② 文本与内容语义"]
    HTML --> Link["③ 链接与导航"]
    HTML --> Image["④ 图片与图形"]
    HTML --> Data["⑤ 列表与表格"]
    HTML --> Form["⑥ 表单"]
    HTML --> Semantic["⑦ 语义化布局"]
    HTML --> Media["⑧ 多媒体与嵌入内容"]
    HTML --> Metadata["⑨ head 与元数据"]
    HTML --> A11y["⑩ 可访问性"]
    HTML --> Quality["⑪ 规范、调试与质量"]

    %% ===== ① 文档基础 =====
    Basic --> Skeleton["HTML 文档骨架"]
    Basic --> Syntax["标签、元素与属性"]
    Basic --> Nesting["嵌套与父子关系"]
    Basic --> Void["空元素"]
    Basic --> Comment["注释"]
    Basic --> GlobalAttr["全局属性"]
    Basic --> Path["资源路径"]
    Basic --> Entity["字符实体"]

    Skeleton --> Doctype["<!DOCTYPE html>"]
    Skeleton --> HtmlTag["html / head / body"]
    Syntax --> StartEnd["开始标签 / 结束标签"]
    Syntax --> AttrValue["属性名 / 属性值"]
    Void --> VoidTags["img / input / br / hr / meta / link"]
    GlobalAttr --> IdClass["id / class"]
    GlobalAttr --> TitleAttr["title / hidden"]
    GlobalAttr --> DataAttr["data-* 自定义数据"]
    Path --> AbsolutePath["绝对 URL"]
    Path --> RelativePath["相对路径 ./ ../"]
    Entity --> CommonEntity["< / > / & /  "]

    %% ===== ② 文本与内容语义 =====
    Text --> Heading["标题层级 h1-h6"]
    Text --> Paragraph["段落与分隔"]
    Text --> Emphasis["强调与重要性"]
    Text --> Edit["编辑标记"]
    Text --> CodeText["代码与预格式文本"]
    Text --> Quote["引用"]
    Text --> Meaning["时间、缩写与联系信息"]
    Text --> Generic["无特定语义容器"]

    Paragraph --> PTag["p"]
    Paragraph --> BrHr["br / hr"]
    Emphasis --> StrongEm["strong / em"]
    Emphasis --> BI["b / i / mark / small"]
    Edit --> DelIns["del / ins"]
    CodeText --> CodePre["code / pre / kbd / samp"]
    Quote --> BlockInlineQuote["blockquote / q / cite"]
    Meaning --> TimeAbbr["time / abbr / address"]
    Generic --> DivSpan["div / span"]

    %% ===== ③ 链接与导航 =====
    Link --> Anchor["a 与 href"]
    Link --> LinkPath["链接地址"]
    Link --> Fragment["页内锚点 #id"]
    Link --> NewWindow["新窗口与安全"]
    Link --> Protocol["特殊协议"]
    Link --> Download["下载链接"]
    Link --> NavTag["nav 导航区域"]

    LinkPath --> ExternalLink["外部链接"]
    LinkPath --> InternalLink["站内相对链接"]
    NewWindow --> TargetBlank["target=_blank"]
    NewWindow --> RelNoopener["rel=noopener noreferrer"]
    Protocol --> MailTel["mailto: / tel:"]

    %% ===== ④ 图片与图形 =====
    Image --> Img["img"]
    Image --> Alt["替代文本 alt"]
    Image --> ImgSize["width / height"]
    Image --> Lazy["loading=lazy"]
    Image --> Figure["figure / figcaption"]
    Image --> ResponsiveImage["响应式图片"]
    Image --> SVG["SVG"]
    Image --> Canvas["canvas"]

    Img --> Src["src"]
    ResponsiveImage --> SrcsetSizes["srcset / sizes"]
    ResponsiveImage --> PictureSource["picture / source"]
    SVG --> SvgUse["矢量图形 / 图标"]
    Canvas --> CanvasUse["像素画布 / 脚本绘制"]

    %% ===== ⑤ 列表与表格 =====
    Data --> List["列表"]
    Data --> Table["表格"]

    List --> Unordered["ul / li"]
    List --> Ordered["ol / li"]
    List --> Description["dl / dt / dd"]
    Table --> TableBase["table / tr / th / td"]
    Table --> TableGroup["thead / tbody / tfoot"]
    Table --> Caption["caption"]
    Table --> HeaderScope["表头与 scope"]
    Table --> MergeCell["colspan / rowspan"]

    %% ===== ⑥ 表单 =====
    Form --> FormTag["form"]
    Form --> Label["label 与控件关联"]
    Form --> Input["input"]
    Form --> Choice["选择类控件"]
    Form --> Textarea["textarea"]
    Form --> Select["select / option / optgroup"]
    Form --> Button["button"]
    Form --> Group["fieldset / legend"]
    Form --> Validation["原生表单校验"]
    Form --> State["控件状态"]
    Form --> Autofill["自动填充"]

    FormTag --> SubmitTarget["action / method"]
    FormTag --> Encode["enctype"]
    Input --> InputType["text / password / email / number / date / file"]
    Input --> NameValue["name / value"]
    Input --> Placeholder["placeholder"]
    Choice --> Radio["radio"]
    Choice --> Checkbox["checkbox"]
    Button --> ButtonType["submit / button / reset"]
    Validation --> Required["required"]
    Validation --> Pattern["pattern / min / max / minlength / maxlength"]
    State --> DisabledReadonly["disabled / readonly"]
    Autofill --> Autocomplete["autocomplete"]

    %% ===== ⑦ 语义化布局 =====
    Semantic --> Header["header"]
    Semantic --> Nav["nav"]
    Semantic --> Main["main"]
    Semantic --> Section["section"]
    Semantic --> Article["article"]
    Semantic --> Aside["aside"]
    Semantic --> Footer["footer"]
    Semantic --> HeadingOutline["标题层级"]
    Semantic --> SemanticVsDiv["语义元素 vs div"]

    %% ===== ⑧ 多媒体与嵌入内容 =====
    Media --> Audio["audio"]
    Media --> Video["video"]
    Media --> Source["source 多格式资源"]
    Media --> Track["track 字幕"]
    Media --> Iframe["iframe"]
    Media --> EmbedLegacy["embed / object"]

    Audio --> MediaControls["controls / autoplay / loop / muted"]
    Video --> VideoAttr["poster / width / height"]
    Track --> CaptionTrack["captions / subtitles"]
    Iframe --> IframeTitle["title"]
    Iframe --> IframeSafe["sandbox / allow"]
    Iframe --> IframeLazy["loading=lazy"]

    %% ===== ⑨ head 与元数据 =====
    Metadata --> Charset["meta charset"]
    Metadata --> Viewport["meta viewport"]
    Metadata --> Title["title"]
    Metadata --> DescriptionMeta["meta description"]
    Metadata --> Language["html lang"]
    Metadata --> LinkTag["link"]
    Metadata --> StyleTag["style"]
    Metadata --> ScriptTag["script"]
    Metadata --> SocialMeta["社交分享元数据"]
    Metadata --> RobotMeta["robots"]

    LinkTag --> Stylesheet["stylesheet"]
    LinkTag --> Favicon["favicon"]
    LinkTag --> ResourceHint["preload / preconnect"]
    ScriptTag --> ScriptLoad["defer / async"]
    SocialMeta --> OpenGraph["Open Graph"]

    %% ===== ⑩ 可访问性 =====
    A11y --> NativeSemantic["优先使用原生语义"]
    A11y --> AccessibleName["可访问名称"]
    A11y --> Keyboard["键盘操作"]
    A11y --> Focus["焦点顺序"]
    A11y --> ImageA11y["图片替代文本"]
    A11y --> FormA11y["表单标签与错误提示"]
    A11y --> TableA11y["表格标题与表头"]
    A11y --> MediaA11y["字幕与文字稿"]
    A11y --> ARIA["ARIA"]

    AccessibleName --> NameSource["文字 / label / alt / aria-label"]
    Keyboard --> NativeControl["button / a / input"]
    Focus --> Tabindex["tabindex"]
    ARIA --> AriaRule["无 ARIA 胜过错误 ARIA"]
    ARIA --> AriaState["aria-expanded / aria-current / aria-live"]

    %% ===== ⑪ 规范、调试与质量 =====
    Quality --> DOM["DOM 树"]
    Quality --> DevTools["浏览器开发者工具"]
    Quality --> Validator["HTML 校验"]
    Quality --> Formatting["缩进与可读性"]
    Quality --> Deprecated["废弃与表现型标签"]
    Quality --> Compatibility["浏览器兼容与渐进增强"]
    Quality --> SEO["基础 SEO"]
    Quality --> Performance["资源与加载性能"]
    Quality --> Security["基础安全意识"]

    DevTools --> ElementsPanel["Elements / Accessibility"]
    Validator --> W3CValidator["标签嵌套 / 属性错误"]
    Deprecated --> OldTags["font / center / marquee"]
    SEO --> SeoBasic["语义 / title / description / heading"]
    Performance --> ImgPerformance["图片尺寸 / 懒加载"]
    Performance --> LoadOrder["CSS / JavaScript 加载"]
    Security --> ExternalSafe["外部链接安全"]
    Security --> IframeSecurity["iframe 限权"]
    Security --> UserContent["不信任用户输入"]

    %% ===== 学习优先级 =====
    classDef root fill:#6366f1,stroke:#4338ca,color:#fff,stroke-width:3px
    classDef level1 fill:#3b82f6,stroke:#2563eb,color:#fff,stroke-width:2px
    classDef must fill:#16a34a,stroke:#15803d,color:#fff
    classDef know fill:#f59e0b,stroke:#d97706,color:#fff

    class HTML root
    class Basic,Text,Link,Image,Data,Form,Semantic,Media,Metadata,A11y,Quality level1
    class Skeleton,Heading,Paragraph,Anchor,Img,Alt,List,TableBase,FormTag,Label,Input,Button,Header,Nav,Main,Section,Article,Footer,Charset,Viewport,Title,Language,NativeSemantic,DevTools must
    class ResponsiveImage,SVG,Canvas,Validation,Iframe,SocialMeta,ARIA,Validator,SEO,Performance,Security know
graph LR
    %% ===== 根节点 =====
    CSS["🎨 CSS 知识树"]

    %% ===== 一级分支 =====
    CSS --> Basic["① 基础语法"]
    CSS --> Box["② 盒模型"]
    CSS --> Layout["③ 布局"]
    CSS --> Visual["④ 视觉样式"]
    CSS --> Typo["⑤ 文字排版"]
    CSS --> Anim["⑥ 动画与过渡"]
    CSS --> Responsive["⑦ 响应式设计"]
    CSS --> Modern["⑧ 现代CSS特性"]
    CSS --> Advanced["⑨ 高级概念"]
    CSS --> Practice["⑩ 最佳实践"]
    CSS --> Tools["⑪ 调试与工具"]

    %% ===== ① 基础语法 =====
    Basic --> Sel["选择器"]
    Basic --> Cascade["层叠与优先级"]
    Basic --> Units["单位"]

    Sel --> SelBasic["元素/类/ID/通配符"]
    Sel --> SelAttr["属性选择器"]
    Sel --> SelCombo["组合选择器"]
    Sel --> SelPseudo["伪类 & 伪元素  :hover ::before"]
    Sel --> SelStruct["结构伪类  :nth-child :not"]

    Cascade --> Inherit["继承 inherit/initial"]
    Cascade --> Specificity["优先级计算"]
    Cascade --> Important["!important"]

    Units --> Abs["绝对 px/pt/cm"]
    Units --> RelFont["相对 em/rem"]
    Units --> Viewport["视口 vw/vh/vmin"]

    %% ===== ② 盒模型 =====
    Box --> Content["content"]
    Box --> Padding["padding"]
    Box --> Border["border"]
    Box --> Margin["margin"]
    Box --> Sizing["box-sizing"]

    Border --> BorderRadius["border-radius"]
    Border --> BorderImg["border-image"]
    Margin --> MarginCollapse["margin 折叠"]
    Margin --> NegMargin["负 margin"]
    Sizing --> ContentBox["content-box"]
    Sizing --> BorderBox["border-box ★"]

    %% ===== ③ 布局 =====
    Layout --> Display["display"]
    Layout --> Float["float"]
    Layout --> Position["position"]
    Layout --> Flex["Flexbox ★"]
    Layout --> Grid["Grid ★★"]
    Layout --> MultiCol["多列布局"]

    Display --> Block["block / inline"]
    Display --> InlineBlock["inline-block"]
    Display --> None["none / contents"]

    Float --> FloatLR["left / right"]
    Float --> Clearfix["clearfix"]
    Float --> BFC["BFC 触发"]

    Position --> Static["static"]
    Position --> Relative["relative"]
    Position --> Absolute["absolute"]
    Position --> Fixed["fixed"]
    Position --> Sticky["sticky"]

    Flex --> FlexContainer["容器: justify-content / align-items"]
    Flex --> FlexItem["项目: flex-grow / shrink / basis"]
    Flex --> FlexDir["flex-direction / wrap"]

    Grid --> GridContainer["容器: grid-template / gap"]
    Grid --> GridItem["项目: grid-column / area"]
    Grid --> GridArea["grid-template-areas"]

    %% ===== ④ 视觉样式 =====
    Visual --> Color["颜色"]
    Visual --> Background["背景"]
    Visual --> Gradient["渐变"]
    Visual --> Shadow["阴影"]
    Visual --> Filter["滤镜 filter"]
    Visual --> Blend["混合模式"]
    Visual --> Clip["裁剪 clip-path"]

    Color --> Hex["十六进制 #fff"]
    Color --> RGB["rgb / rgba"]
    Color --> HSL["hsl / hsla"]
    Color --> CurrentColor["currentColor"]

    Background --> BgImg["background-image"]
    Background --> BgSize["background-size"]
    Background --> BgMulti["多重背景"]

    Gradient --> Linear["linear-gradient"]
    Gradient --> Radial["radial-gradient"]
    Gradient --> Conic["conic-gradient"]

    Shadow --> BoxShadow["box-shadow"]
    Shadow --> TextShadow["text-shadow"]

    Blend --> MixBlend["mix-blend-mode"]
    Blend --> BgBlend["background-blend-mode"]

    %% ===== ⑤ 文字排版 =====
    Typo --> FontFamily["font-family"]
    Typo --> FontSize["font-size / weight"]
    Typo --> LineHeight["line-height"]
    Typo --> TextAlign["text-align"]
    Typo --> Decoration["text-decoration"]
    Typo --> Spacing["letter / word-spacing"]
    Typo --> Overflow["text-overflow ellipsis"]
    Typo --> FontFace["@font-face"]
    Typo --> WhiteSpace["white-space nowrap"]

    %% ===== ⑥ 动画与过渡 =====
    Anim --> Transition["transition"]
    Anim --> Keyframes["@keyframes"]
    Anim --> Animation["animation"]
    Anim --> Transform["transform"]

    Transition --> TransProp["transition-property"]
    Transition --> TransTime["timing-function  cubic-bezier"]
    Transition --> TransDur["duration / delay"]

    Keyframes --> KeyframeRule["@keyframes name"]
    Keyframes --> KeyframePct["0% / 50% / 100%"]

    Animation --> AnimName["animation-name"]
    Animation --> AnimIter["iteration-count"]
    Animation --> AnimDir["direction / fill-mode"]

    Transform --> Translate["translate / rotate"]
    Transform --> Scale["scale / skew"]
    Transform --> Transform3D["3D transform  perspective / translateZ"]

    %% ===== ⑦ 响应式设计 =====
    Responsive --> ViewportMeta["viewport meta"]
    Responsive --> MediaQuery["@media 媒体查询"]
    Responsive --> MobileFirst["移动优先策略"]
    Responsive --> ResponsiveImg["响应式图片"]

    MediaQuery --> MQWidth["min / max-width"]
    MediaQuery --> MQRatio["aspect-ratio"]
    MediaQuery --> MQOrient["orientation"]
    MediaQuery --> MQHover["hover / pointer"]

    ResponsiveImg --> Srcset["srcset / sizes"]
    ResponsiveImg --> Picture["picture 元素"]

    %% ===== ⑧ 现代CSS特性 =====
    Modern --> CSSVar["自定义属性  --var / var()"]
    Modern --> Supports["@supports 特性查询"]
    Modern --> Calc["calc()"]
    Modern --> MinMaxClamp["min / max / clamp()"]
    Modern --> AspectRatio["aspect-ratio"]
    Modern --> ContainerQuery["@container 容器查询"]
    Modern --> HasSel[":has() 父选择器"]
    Modern --> CascadeLayer["@layer 层叠层"]
    Modern --> ColorMix["color-mix / contrast"]

    %% ===== ⑨ 高级概念 =====
    Advanced --> BFCConcept["BFC 块级格式上下文"]
    Advanced --> IFCConcept["IFC 行内格式"]
    Advanced --> Stacking["层叠上下文 z-index"]
    Advanced --> ContainBlock["包含块"]
    Advanced --> Reflow["重绘与回流"]
    Advanced --> FormatModel["视觉格式化模型"]

    %% ===== ⑩ 最佳实践 =====
    Practice --> BEM["BEM 命名规范"]
    Practice --> OOCSS["OOCSS / SMACSS"]
    Practice --> CSSMod["CSS Modules"]
    Practice --> CSSinJS["CSS-in-JS"]
    Practice --> Utility["Tailwind / Utility-first"]
    Practice --> Reset["reset / normalize"]
    Practice --> Prefix["浏览器前缀"]
    Practice --> Perf["性能优化"]

    Perf --> CritCSS["关键CSS内联"]
    Perf --> NoImport["避免 @import"]
    Perf --> WillChange["will-change"]

    %% ===== ⑪ 调试与工具 =====
    Tools --> DevTools["浏览器 DevTools"]
    Tools --> PostCSS["PostCSS"]
    Tools --> AutoPrefix["Autoprefixer"]
    Tools --> PreProc["预处理器"]
    Tools --> Lint["Stylelint"]

    PreProc --> Sass["Sass / SCSS"]
    PreProc --> Less["Less"]
    PreProc --> Stylus["Stylus"]

    %% ===== 样式高亮 =====
    classDef root fill:#6366f1,stroke:#4338ca,color:#fff,stroke-width:3px
    classDef level1 fill:#3b82f6,stroke:#2563eb,color:#fff,stroke-width:2px
    classDef hot fill:#f59e0b,stroke:#d97706,color:#fff

    class CSS root
    class Basic,Box,Layout,Visual,Typo,Anim,Responsive,Modern,Advanced,Practice,Tools level1
    class Flex,Grid,ContainerQuery,HasSel,CSSVar hot

阶段二:Java 基础

详细计划待补充。

阶段三:前端工程化

详细计划待补充。

阶段四:后端进阶与全栈整合

详细计划待补充。

阶段五:AI Agent 提效

详细计划待补充。