3

使用 GPT-4 开发熄灯游戏

 1 year ago
source link: https://oldj.net/article/2023/04/28/lights-out-by-gpt-4/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用 GPT-4 开发熄灯游戏

2023-04-28

最近一段时间,我一直在体验 ChatGPT / GPT-4,这个工具给了我很大的震撼和帮助。网上有很多人使用 GPT 生成简单项目的介绍,我也尝试了一下,本文记录的就是这样一次尝试。

多年前我写过一篇博客,介绍了熄灯游戏,这是一个简单但又需要一定逻辑的小游戏,我决定试试让 GPT-4 来实现一下。

首先我给 GPT-4 输入了游戏的定义以及我的要求:

熄灯游戏(Lights Out)是一个规则很简单的游戏,在一个 n * n 个格子的面板上,每个格子中有一个灯,灯有亮着和熄灭两种状态,初始状态下,所有的灯都是亮着的,点击某一个格子,会影响到那个格子以及它上、下、左、右四个相邻格子中的灯的状态,影响的规则为如果灯原来亮着则将其熄灭,如果原来熄灭则将其打开。游戏的目标是要将面板上所有的灯全部熄灭。

请写一个网页,实现这个游戏。

GPT-4 很快给出了一个 HTML 页面,初步实现了需求。这个页面的 JavaScript 逻辑基本正确,但在样式方面却有很多问题,比如所有格子都横向排列了,并没有排成 n * n 的方格,同时灯的开和关状态也没有正确显示。

于是我继续向它提要求:

样式似乎有错误,没有区分灯的开和关状态,另外灯的排列位置也有误。

它立刻承认了错误,并给出了修改后的代码片断。我将新的代码片断复制到文档后,发现功能正常了。此时,游戏的界面看起来如下图所示:

lights-out_01.png

游戏可以玩了,但代码中写死了格子的尺寸为 5x5,如果想玩其他尺寸怎么办呢?于是我继续向 GPT-4 提要求:

接下来,我想让用户可以直接在页面上调整格子的数量,怎么修改?

GPT-4 给出了方案,在页面上添加一个 <input> 组件让用户输入数字,再添加一个按钮进行确认。

我觉得让用户手动输入太麻烦了,继续提要求:

不要让用户输入数字,改为下拉框的形式,让用户可以从 2 ~ 30 之间的数字选择。

GPT-4 又给出了新的方案,但这次,它又犯了一个错误,给出的 HTML 代码片断如下:

<select id="grid-size">
  <!-- 使用for循环生成下拉框选项 -->
  <% for (let i = 2; i <= 30; i++) { %>
    <option value="<%= i %>"><%= i %></option>
  <% } %>
</select>
<button id="update-grid">更新面板</button>

我告诉它,这是纯静态页面,不能使用类似 <% ... %> 这样的模板语言,另外又告诉它,<select> 的值变化后就直接生成新的游戏,不要再让用户点击按钮确认。几个来回之后,GPT-4 终于实现了我想要的功能。

此时,游戏界面如下图所示:

lights-out_02.png

可以看到,现在可以手动指定格子的尺寸(比如调整为 5x5、6x6 等)了,但在之前的调整中,一些样式也发生了期望之外的变化,比如两行格子之间多了 2px 的空隙,看起来不是很美观。

接下来,我又给了 GPT-4 一系列指令,让它调整游戏界面的样式,最后得到了这样的结果:

lights-out_03.png

老实说,我对这个结果已经挺满意了。

不过这个时候,页面的代码比较混乱,因为这些代码是经过和 GPT-4 的多次交流生成的,除了第一次之外,后面的交流中 GPT-4 都只给出了有变化的部分,我则从对话中将这些代码片断复制到源文件中。现在代码虽然能工作了,但看起来并不是很整洁,于是我将整个游戏的代码(120 行)复制了一份,丢回给 GPT-4,让它整理优化一下。

很快,GPT-4 返回了结果,代码变短了一些(114 行),结构上也更清晰了。

此时这个游戏已经可以游玩了,但作为一个游戏,总该再显示一些必要信息,比如一共点了多少次?还有多少个格子亮着?以及如果我想重新开局怎么办?

于是我继续向 GPT-4 提要求:

接下来,在游戏面板下方添加以下内容:

1. 点击数次,记录各个格子被点击的次数,点到其余地方不计数。当改变格子数或者点击重置按钮时此项清零。
2. 剩余亮着的格子数。
3. 重置游戏按钮,点击后重新生成当前游戏,所有格子的灯全部恢复为点亮状态,点击数次也重设为0。

GPT-4 很快就完成了任务。

我又注意到,当格子全部被点灭时代表着游戏胜利,这时应该给用户一个提示。于是继续向 GPT-4 提要求:

当剩余亮着的格子数为 0 时,表示游戏胜利,在页面上显示游戏胜利信息。

GPT-4 轻松地完成了任务,当用户游戏胜利时,界面上会显示“恭喜!你赢了!”的提示语。

我觉得纯文字的提示有一点单调,让 GPT-4 加一些 emoji,于是 GPT-4 又将提示语改成了“🎉 恭喜!你赢了! 🎉”。

另外,我也让 GPT-4 调整了一下文案,最后,游戏的效果(胜利时)如下:

lights-out_04.png

这时,这个小游戏的功能已经算是完备了,但样式上还不是很好看,尤其是那个下拉框以及按钮。能否让 GPT-4 改进一下样式外观呢?我又向 GPT-4 继续提要求。

由于之前的会话已经很长,我开启了一个新的会话,将最新的代码复制了进去:

// 游戏完整代码
请优化上面的代码,将其中的下拉框以及按钮的样式改得漂亮一些。

很快,GPT-4 返回了结果,效果如下:

lights-out_06.png

可以看到,它将下拉列表改成了绿色,将重置游戏按钮改成了红色。也许这个样式无法与人工实现的优秀设计相比,但与原来的样式相比已经是很不错的效果了,我决定采纳这个设计。

最后,我又想到,GPT-4 有着强大的翻译能力,那么能否给这个小游戏添加多语言版本呢?于是继续向它提要求:

给这个页面添加一个多语言切换菜单,允许在中文和英文之间切换。

GPT-4 果然轻松地完成了任务,它还将页面中出现的文案提取到了一个对象中:

const translations = {
  zh: {
    title: "熄灯游戏",
    instruction: "请把所有格子的灯熄灭。",
    clickCountLabel: "点击数次:",
    remainingLightsLabel: "剩余格子数:",
    winMessage: "🎉 恭喜!你赢了! 🎉",
    resetButton: "重置游戏",
  },
  en: {
    title: "Lights Out Game",
    instruction: "Turn off all the lights.",
    clickCountLabel: "Click count:",
    remainingLightsLabel: "Remaining lights:",
    winMessage: "🎉 Congratulations! You won! 🎉",
    resetButton: "Reset Game",
  },
};

虽然这个对象在后续的代码优化中又被 GPT-4 移除了,但这个操作还是让我觉得很惊艳。

此时的效果如下图所示:

lights-out_07.png

可以见到,GPT-4 在页面的最顶部添加了一个选择语言的下拉框,并且参考了之前的样式,将这个下拉框的样式设为了蓝色。

至此,这个游戏便基本完成了,后面我又将完整代码发给 GPT-4 让它进行优化,让它给鼠标 hover 和点击操作添加一些动画效果,它顺利地完成了任务,同时除了做一些代码上精简调整外,还将选择格子下拉框的显示文案从单个数字变成了 5x5 这样更直观的数字,这也让我很是惊讶。

当然,它也有一些不足,比如“点击次数”、“剩余格子数”后面它使用了半角的冒号,我让它替换为全角的冒号它却始终不明白,也许是我的描述有一些问题,最后我不得不手动修改了一下,这也是整个游戏代码中我唯一手动修改过的地方。

下面是这个游戏的最终效果图:

lights-out_08.png

你可以点击 https://oldj.net/static/lights-out/2.html 在线体验。

整个游戏的实现我一行代码也没有写,完全是通过与 GPT-4 的问答式交互生成的。

这个游戏还很简单,但 GPT-4 所表现出来的能力也已经非常令人惊讶,可以想象,如果应用得当,GPT-4 将会是多么犀利的效率神器。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK