【记录与感想】CS61b-21sp project0(2048游戏)

项目概述

本项目是cs61b课程开课以来的第一个项目,游戏本身非常简单。它在 4×4 的方格网格上进行,每个方格可以是空的,也可以包含一个带有整数(大于或等于 2 的 2 的幂)的图块。在第一步之前,应用程序会将一个包含 2 或 4 的图块添加到最初为空的棋盘上的随机方格中。选择 2 或 4 是随机的,选择 2 的概率为 75%,选择 4 的概率为 25%。

然后玩家通过箭头键选择一个方向来倾斜棋盘:北、南、东或西。所有方块都朝那个方向滑动,直到运动方向上没有空隙(一开始可能没有)。一个方块可能会与另一个方块合并,从而为玩家赢得积分。

在这个项目中,您将构建这款游戏的核心逻辑。也就是说,我们已经整合了所有 GUI 代码、处理按键和大量其他框架。 您的工作将是完成最重要和最有趣的部分。

具体来说,您将填写 Model.java 文件中的 4 个方法,这些方法控制用户按下某些按键后发生的情况。

三个函数(易)

要求我们实现三个测试函数emptySpaceExists(Board b)、maxTileExists(Board b)、atLeastOneMoveExists(Board b),难度不大,跟随作者的思路就能够按部就班地写下来,用时1.5h
其中第三个函数的实现要求判断上下左右能否移动,我使用的是二维数组来存(之前打竞赛有些基础),更加简洁易懂一些。

/** Returns true if at least one space on the Board is empty.*  Empty spaces are stored as null.* */public static boolean emptySpaceExists(Board b) {// TODO: Fill in this function.boolean judge = false;for(int i = 0; i < 4; i++){for(int j = 0; j < 4; j++){if(b.tile(i,j) == null){judge = true;break;}}}return judge;}
/*** Returns true if any tile is equal to the maximum valid value.* Maximum valid value is given by MAX_PIECE. Note that* given a Tile object t, we get its value with t.value().*/public static boolean maxTileExists(Board b) {// TODO: Fill in this function.boolean judge = false;for(int i = 0; i < 4; i++){for(int j = 0; j < 4; j++){if(b.tile(i,j) != null){if(b.tile(i,j).value() == MAX_PIECE){judge = true;break;}}}}return judge;}
/*** Returns true if there are any valid moves on the board.* There are two ways that there can be valid moves:* 1. There is at least one empty space on the board.* 2. There are two adjacent tiles with the same value.*/public static boolean atLeastOneMoveExists(Board b) {// TODO: Fill in this function.boolean judge = false;if(emptySpaceExists(b)){return true;}int [][] directions = {{-1,0}, {1,0}, {0,-1}, {0,1}};	//二维数组代表方向for(int i = 0; i < 4; i++){for(int j = 0; j < 4; j++){for(int t = 0; t < 4; t++){int newRow = i + directions[t][0];int newColumn = j + directions[t][1];if(borderJudge(newRow) && borderJudge(newColumn)){if(b.tile(i,j).value() == b.tile(newRow,newColumn).value())return true;}}}}return judge;}

核心函数(难)

难点一:与直觉相反

以往做的算法题以及线性代数中,从上到下的 i 是逐渐增大的过程,一般是从 i = 0开始,但是在该项目中,方阵的起点左下角,这也就意味着第四行的下标 i = 0,在仔细研究给出的实例和Google表单测验后才恍然领悟

难点二:不兼容问题

在看到youtube上实例视频的评论后得知,照抄Josh Hug教授的代码但无法运行的原因是,win11英文语言和中文语言的箭头代表参数不同。
例如:向上箭头在英文系统中就是 “↑” ,然而在中文的windows系统中却是 “向上箭头”
如果不在GUISource.java文件中修改,项目将不能运行

public String getKey() {	//修改的函数String command = _source.readKey();switch (command) {case "向上箭头" :command = "Up";break;case "向右箭头" :command = "Right";break;case "向下箭头" :command = "Down";break;case "向左箭头" :command = "Left";break;default :break;}

难点三:核心逻辑的编写(以north为主,其他方向类比即可)

①当运动方向上的三个相邻的图块具有相同的值时,则运动方向上的前两个图块会合并,而后一个图块则不会合并

如一列元素是 (2, 2, 2, 0)^(T),当按下 后,应该显示的是 (4, 2, 0, 0)^(T),而不是 (2, 4, 0, 0)^(T) ,因此在程序中的 i 和 j 都是从3到0(从上到下)进行循环。

②合并后的图块不会在该格子处再次合并。因此,每次移动时,每个图块最多只能成为一次合并的一部分(可能为零)

如一列元素是 (2, 2, 2, 2)^(T),当按下 后,应该显示的是 (4, 4, 0, 0)^(T),而不是 (8, 0, 0, 0)^(T),这就需要我们运用一个boolean类型的book数组,用于记录在本次操作中该格子是否已经合并过。

同时我们可以将每一列都看作是单独的一部分,因此没有必要开一个二维book,只需要在循环 i 时更新[ ]book即可。

③除north外的其他三个方向的类比

一开始的思路是想读取键盘的输入,找了一圈没有发现对应的函数,后想在接受键盘输入的play( )函数中插入自己的一段代码,用于将参数同步到正在写的tilt( )函数中。后来忽然发现,tilt( )函数传的参数是Side side,虽然project的指引中没说,但我敏锐地感觉到这就是要用的参数。经尝试,验证了我的猜想。

④核心逻辑的编写

见下图,系本人手写的思路概要请添加图片描述

实现代码

public boolean tilt(Side side) {boolean changed;changed = false;// TODO: Modify this.board (and perhaps this.score) to account// for the tilt to the Side SIDE. If the board changed, set the// changed local variable to true.//向侧面倾斜。如果棋盘发生变化,则将改变的局部变量设置为 trueif(side == Side.EAST){board.setViewingPerspective(Side.EAST);}if(side == Side.SOUTH){board.setViewingPerspective(Side.SOUTH);}if(side == Side.WEST){board.setViewingPerspective(Side.WEST);}for(int i = 3; i >= 0; i--){   //不考虑行boolean []book=new boolean[4];for(int j = 3; j >= 0; j--){   //只考虑单列if(board.tile(i,j) != null && j != 3){int j2 = j + 1;Tile t = board.tile(i, j);while(j2 < 3 && board.tile(i, j2) == null){j2++;}if(j2 == 3 && board.tile(i, j2) == null) {   //上面全是0board.move(i, 3, t);changed = true;}else if(t.value() == board.tile(i, j2).value()){   //上面最近的一个相等if(!book[j2]) {board.move(i, j2, t);book[j2] = true;score += 2 * t.value();}else{board.move(i,j2-1,t);}changed = true;}else if(j2 != j){ //上面最近的一个不等 + 不挨着,要是挨着直接没变化board.move(i, j2 - 1, t);changed = true;}}}}board.setViewingPerspective(Side.NORTH);checkGameOver();if (changed) {setChanged();}return changed;}

运行效果请添加图片描述

写在最后

本项目是我在上大学以来严格来说接触到的第一个项目,在此之前在编程上的学习大多都是语法与算法,集中在算法题上,一道题几十行最多百来行的代码。在真正结束落地项目后才能更真切地感受到,算法是项目中的一个个高性能片段,除算法之外项目还有许许多多的组成部分。

同时,学习CS61B这门课程也培养了我相当的自学能力和独立解决问题的能力,很多问题在国内外的论坛或技术博客中很难找到立竿见影的解决方法,往往需要自己去摸索。

我碰到过的问题如下:

  1. intellij idea的环境配置问题,甚至intellij都卸载重装了好几次
  2. GitHub仓库同步课程仓库,以及拉取代码到本地
  3. git版本控制的操作
  4. 提交作业到Gradescope的autograder
  5. 做homework、lab和project遇到的问题
  6. 运用步入、步进、步出、junit来调试程序

可以说,学习这门课程的过程就是一个逐渐解决问题的过程,也是一个不断碰壁的过程,经过这些才能变得更坚韧。同时也认识到国内外的大学计算机教育的差距,我就读于上海的一所211大学,大一就一门专业课,还是c++语言入门课,老师上课的方式也是上课讲ppt,课下做线上OJ。

像CS61B这样顶尖的课程,它不仅仅能教会学生怎么写代码,更多的还有如何使用各种工具,如github、git等,以及完善的项目评测机,不会出现一个期末大作业,老师就看word报告的情况。

计算机学习没有止境,我们一同前行!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/27260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python第二语言(十四、高阶基础)

目录 1. 闭包 1.1 使用闭包注意事项 1.2 小结 2. 装饰器&#xff1a;实际上也是一种闭包&#xff1b; 2.1 装饰器的写法&#xff08;闭包写法&#xff09; &#xff1a;基础写法&#xff0c;只是解释装饰器是怎么写的&#xff1b; 2.2 装饰器的语法糖写法&#xff1a;函数…

半导体笔记汇总

半导体笔记汇总 介于导体与绝缘体之间的材质就叫做半导体。半导体器件主要分三类&#xff1a;二极管、三极管、MOS管。 一、半导体理论基础 1、导体、半导体和绝缘体 我们根据物质的导电性能强弱将物质分为导体、半导体和绝缘体。电导率与电阻率互为倒数&#xff0c;下图中…

3d模型文件格式有那些,什么区别?---模大狮模型网

3D模型文件格式有很多种&#xff0c;每种格式都有其特点和应用场景。常见的3D模型文件格式包括OBJ、FBX、STL、3DS、DAE等&#xff0c;下面将逐一介绍这些格式的区别。 1. OBJ格式&#xff1a;OBJ是一种开放的3D模型文件格式&#xff0c;可以被几乎所有的3D软件所支持。OBJ格式…

小程序 UI 风格,构建美妙视觉

小程序 UI 风格&#xff0c;构建美妙视觉

【DIY飞控板PX4移植】BARO模块BMP388气压计的PCB硬件设计和PX4驱动配置

BARO模块BMP388气压计的PCB硬件设计和PX4驱动配置 BMP388简介硬件设计封装原理图PCB设计引脚选择问题 PX4驱动配置飞控板的配置文件夹结构default.px4board文件nuttx-config/nsh/defconfig文件nuttx-config/include/board.h文件src/board_config.h文件src/i2c.cpp文件init/rc.b…

安卓/iOS/Linux系统影音边下边播P2P传输解决方案

在当今的数字时代&#xff0c;IPTV 影音行业正经历着快速的发展和变革&#xff0c;但影音行业的流量带宽成本一直很高&#xff0c;有没有什么办法既能保证现有的用户观看体验&#xff0c;又能很好降低流量带宽成本呢? P2P技术可能是一个很好的选择&#xff0c;它不仅仅可以提…

Vue2+Element-ui后台系统常用js方法

el-dialog弹框关闭清空form表单并清空验证 cancelDialog(diaLog, formRef) {this[diaLog] falseif (formRef) {this.$refs[formRef].resetFields()} }页面使用&#xff1a; <el-dialog :visible.sync"addSubsidyDialog.dialog" close"cancelDialog(addSub…

大模型赛道有前景吗?普通人该如何入门大模型?(附AI大模型资源)

大模型赛道有前景吗&#xff1f; 这个问题&#xff0c;是个热门话题&#xff0c;但不是个好问题。 因为&#xff0c;它基于不同的提问人、提问意图&#xff0c;会有不同的答案。 对于一个职业发展初期的新人&#xff0c;提问的意图可能是&#xff1a;我要不要转行去大模型赛…

如何实现一个合格的分布式锁

1、概述 在多线程的环境下&#xff0c;为了保证一个代码块在同一时间只能由一个线程访问&#xff0c;Java中我们一般可以使用 synchronized 语法和 ReentrantLock 去保证&#xff0c;这实际上是本地锁的方式。而在如今分布式架构的热潮下&#xff0c;如何保证不同节点的线程同…

聚道云软件连接器:企业数字化转型新动力

在当今数字化浪潮中&#xff0c;企业如何高效整合内部资源、优化业务流程、提升客户满意度&#xff0c;已成为每个企业亟需解决的问题。该公司作为行业内的佼佼者&#xff0c;近期借助聚道云软件连接器成功实现了飞鱼CRM与金蝶云星辰的对接&#xff0c;开启了数字化转型的新篇章…

macOS Sequoia 将 Mac 生产力与智能化提升至全新高度

本文转载自 官方新闻&#xff1a;https://www.apple.com.cn/newsroom/2024/06/macos-sequoia-takes-productivity-and-intelligence-on-mac-to-new-heights/ 文章目录 1、借助 iPhone 镜像 直接在 Mac 上无线使用 iPhone2、Safari 浏览器迎来重大更新3、升级的游戏体验与备受瞩…

资源分享—2021版乡级制图规范符号库

汇总整理超图平台软件相关的各类资源&#xff08;包括但不限于符号库、地图模板、地理处理模型等&#xff09;&#xff0c;助力项目的高效制图、提高数据生产效率等业务。 本次分享新版国土空间规划【2021版乡级制图规范符号库】&#xff0c;提供SuperMap格式符号库下载。 符…

Python学习笔记8:入门知识(八)

前言 本篇是元组的知识点学习以及知识点的补充 元组 概念 不可变的列表&#xff0c;叫做元组。 在之前列表的特性中&#xff0c;我们就说过列表是可变的&#xff0c;但是在实际使用过程中&#xff0c;我们有时候仍然需要一系列不可变的元素&#xff0c;这个时候就需要元组出…

代码解读 | Hybrid Transformers for Music Source Separation[06]

一、背景 0、Hybrid Transformer 论文解读 1、代码复现|Demucs Music Source Separation_demucs架构原理-CSDN博客 2、Hybrid Transformer 各个模块对应的代码具体在工程的哪个地方 3、Hybrid Transformer 各个模块的底层到底是个啥&#xff08;初步感受&#xff09;&#xff1…

八爪鱼现金流-022-mybatis插件加密和国密SM4算法

背景&#xff1a; 用户的金额数据&#xff0c;不希望被别人看到。 业务场景分析&#xff1a; 用户在页面上添加金额数据 -----> 服务器内存&#xff08;加密、解密&#xff09; -----> 存储数据库 调研及结果&#xff1a; 使用mybatis的拦截器插件&#xff0c;进行数…

win11电脑桌面倒计时提醒怎么设置?

在日常工作中&#xff0c;我们经常需要处理大量的工作任务&#xff0c;而且很多任务都有时间限制。如果将这些任务记录在桌面上&#xff0c;并设置倒计时提醒&#xff0c;无疑会大大提高我们的工作效率。想象一下&#xff0c;在繁忙的工作间隙&#xff0c;你只需一瞥桌面&#…

文件简单做二维码的方法,几步就能够完成操作

怎样用二维码来查看文件内容&#xff1f;随着网络的快速发展&#xff0c;通过二维码来查看文件是现在很常用的一种形式&#xff0c;能够更快让其他人获取文件内容&#xff0c;从而提升传播的速度和效率。比如用这种方式来下发通知文件、分享学习资料、浏览海报图片、传递个人简…

ESP32基础应用之esp32连接腾讯云并使用微信小程序控制的智能灯

文章目录 1. 项目简介1.1 功能接收1.2 使用资源1.3 测试平台 2 腾讯云物联网开发平台3 esp32设备开发3.1 准备参考例程3.2 vscode平台创建测试工程3.3 修改工程 问题总结使用PowerShell命令行终端生成的二维码不能用 1. 项目简介 1.1 功能接收 实现腾讯云创建项目与设备&…

防止暴力破解,教你如何在登录失败后实施10分钟账户锁定策略!

最近&#xff0c;在服务器上发现了异常的登录尝试。尽管您的团队已经采取了强密码策略和其他安全措施来加固服务器&#xff0c;但恶意程序仍然通过暴力破解的方式试图多次尝试猜测正确的凭据以获取访问权限。为了增强系统的安全性&#xff0c;特别是防止此类暴力破解攻击&#…

文章分享 | Ribo-seq与RNA-seq联合分析揭示uAUG-ds翻译调控机制

技术简介 RNA-seq主要从转录组水平分析基因的表达调控机制&#xff0c;检测用于核糖体翻译的RNA序列及二级结构。Ribo-seq主要用于检测核糖体翻译的起始位置、翻译富集区和翻译终止位置。RNA-seq与Ribo-seq联合分析可以准确检测mRNA上游5’UTR区的uORFs翻译调控结构&#xff0…