点击蓝字 关注我们
张刚老师在《ChatGPT结对编程实录:提升生产力,还是被代替?》一文中,在没有编写任何一行代码的情况下自己指导ChatGPT实现了俄罗斯方块这个游戏。在看完整篇文章后我们深刻感受到了ChatGPT在其中体现的代码生成的能力,于是抱着下面的一些疑问也开始了我们关于ChatGPT结对编程的探索:
1、如果是对于完全没有开发俄罗斯方块游戏经验的人来说,ChatGPT真的可以提供端到端的开发帮助吗?
2、如果ChatGPT有这么强大的开发能力,那么对于程序员我们如何更好的利用ChatGPT去辅助我们的开发呢?
在这次探索中,我们一共进行了三种试验,这三种试验使用的都是GPT-4,并且全程人工没有写一行代码,只是将GPT生成的代码拷贝到编译器中。
前两种试验是在没有看文章思路的情况下,由一位完全没有俄罗斯方块开发经验的学生全程借助ChatGPT,自己尝试去复现这个游戏产生的两种实现思路。第三种试验是按照文章中的思路去实现这个游戏,下面是我们整个探索的过程。
第一种试验:逐类实现
第一步:创建游戏框架
在最开始,ChatGPT给出了具体实现游戏的步骤,和整体的游戏框架。
第二步:实现Board类
按照ChatGPT在第一步给出的步骤,首先让其实现Board类。
第三步:实现Tetriminos类
第四步:实现GameWindow类
第五步:实现游戏循环和控制
最后完善GameWindow类,实现游戏的循环控制,例如方块的下落、用户的输入响应等。
在最开始的试验中,我们按照第零个提问——“你能一步一步指导我编写java代码去实现这个游戏吗?”所给出的回答,让ChatGPT逐步地帮我们把每个类全部实现,将这些代码运行后我们得到了下面的结果:
可以看到这是一个完全静止的面板,一个方块都没有显示在这上面,于是我们又尝试将得到的代码给ChatGPT让它帮我们找出原因,但是修改过的代码运行后仍然是同样的静态面板。
第二种试验:逐feature实现
在得到这样不理想的结果后,我们进行了一些思考——在平常的项目开发中我们会用这样的逐类生成的方式去进行开发吗?对于俄罗斯方块来说,这是一个业务需求很明确的项目,或许尝试把整个要实现的游戏拆解成一个一个要实现的feature,然后去逐feature实现,这样的方式会更好一些,于是我们有了第二种试验:
第一步:创建游戏框架
和第一种试验思路一样,在最开始,让ChatGPT给出了具体实现游戏的步骤,和整体的游戏框架。
第二步:实现方块自动下落
第三步:实现图形化界面
游戏没有图形化的界面,我们继续提出要求,让其生成图形化的界面。
第四步:实现方块在底部的沉积
第五步:实现方块之间的碰撞检测
接下来我们增加一个碰撞检测机制,这个机制需要检测方块是否即将与底部方块接触。
第六步:增加方块样式
目前展示的方块都是单个正方形方块,我们让方块形式丰富起来
有一些报错,我们直接交给ChatGPT解决。
在增加方块形式后,发现了方块沉积到底部后不显示的问题,同样也交给ChatGPT去解决。
第七步:检测游戏结束
同样有一些报错,交给ChatGPT去解决。
第八步:实现方块的左右移动
第九步:实现方块的旋转
第十步:实现整行消除和计分
第十一步:让方块随机出现
目前每次出现的方块是固定形状的,我们让它变得随机
在这样逐feature向ChatGPT提问实现后的结果如下所示:
可以看到最终实现了一个简易的俄罗斯方块游戏,这要比之前逐类实现的尝试效果好很多。但是在进行的过程中产生错误代码的情况也比较多,需要不断地去尝试生成新代码,或者将错误代码重新给ChatGPT进行修改,整体来说也花费了不少时间。
第三种试验:按有过开发经验程序员的思路
第一步:创建游戏框架
第二步:创建游戏游戏窗口
第三步:在GUI上显示一个L形方块
第四步:可以移动方块并且进行碰撞检测
第五步:可以旋转方块
第六步:可以落下方块并且创建一个新的方块
第七步:可以检测游戏结束
第八步:增加整行消除和计分
文章中的思路和第二种试验类似,也是逐feature去进行实现。按照文章中的思路实现的结果如下面的视频所示:
可以看到同样也实现出来了一个简易的俄罗斯方块游戏。但是在进行尝试时,我们明显感受到按照文章中的思路整体要顺畅一些,ChatGPT生成的代码正确率更高,少了很多需要重复生成和错误修改的步骤。
总结与体会
相对于单看张刚老师在文章中的分享,经过这次探索后,我们更加深刻感受到了ChatGPT在实际代码生成设计上的能力。并且这三种试验的不同结果也给我们带来了新的思考和体会:
一、对项目进行feature分离
首先逐类实现这种试验的失败让我们觉得,在实际的软件开发中借助ChatGPT进行代码生成时,或许将要实现项目去细化成逐个的feature,再向ChatGPT提出,ChatGPT能够给出更加准确的代码。
二、细粒度的feature和合理的实现顺序
而我们的第二种试验和文章中进行的试验唯一的差别体现在实现这些feature的粒度和顺序上,而这样的不同或许正是导致了第二种方法在生成代码的正确率上要低于文章中的方法,从而导致整体复现的顺畅程度要低一些。第二种试验实现的顺序是:
1、实现方块自动下落的功能
2、方块到达最底部的时候能够沉积在底部
3、方块之间的相互碰撞
4、游戏结束的功能
5、实现方块左右移动的功能
6、增加方块的旋转功能
7、整行消除的功能
而文章中的实现顺序是:
1、先显示一个静态的L形方块
2、实现方块的左右移动
3、实现方块的碰撞检测、边界检测
4、旋转方块
5、按下键可以下落方块、沉积底部后创建新的方块
6、可以检测游戏结束
7、整行消除的功能
可以看到文章中的思路首先实现的是一个静态的L形方块的展示,再逐一在L型方块上增加feature。而我们自己的尝试中,首先去实现了方块自动下落这一feature,明显来说文章中的思路在进行提问的时候粒度更加的细。并且在顺序上,由于自动下落涉及到其余方法中的渲染和更新,所以相对来说,这样的feature在整个拓扑排序中不是优先级最高的,而如果将这样的feature放在前面先去实现,可能会导致ChatGPT在后续的feature实现时生成的代码正确率降低。所以更细粒度的划分和更合理的实现顺序或许会让ChatGPT生成正确代码的概率更高。
而这三种试验方法的不同思路或许也体现了人们在使用ChatGPT时的差异,在没有太多开发经验的情况下,人们或许会更加倾向于按照ChatGPT给出的最初回答,按照一个一个类去进行生成。而在有开发经验和先验知识的情况下,人们或许会更加清楚以逐个feature的形式向ChatGPT进行提问并且按照合适的顺序去实现会得到更好的效果。
总的来说,ChatGPT生成代码的能力是有目共睹的,但如何更好地使用ChatGPT,也紧密取决于使用者本身对于开发项目的理解和开发设计规划。在对项目有合理规划,并且对项目整体进行细粒度feature的拆解,甚至按照合理的顺序去逐步实现的情况下,ChatGPT能够发挥出更强的能力。
全部的代码已经放在:https://github.com/FudanSELab/TetrisGame.git
作者:王瀚林
编辑:孙婕
审核:娄一翎、刘名威