Basic Computer Games 之 Hello 游戏非主流语言移植全解析:ANSI C / Go / MiniScript / Swift 端口的定位、实现与运行
2026/9/23 16:38:14 网站建设 项目流程
  • 示例工程

【免费下载链接】basic-computer-games

An updated version of the classic "Basic Computer Games" book, with well-written examples in a variety of common MEMORY SAFE, SCRIPTING programming languages. See https://coding-horror.github.io/basic-computer-games/

项目地址:https://gitcode.com/gh_mirrors/ba/basic-computer-games
点击查看免费下载

本文以 00_Alternate_Languages/45_Hello/README.md 为核心文档,围绕经典《Basic Computer Games》合集中 Hello 游戏的非主流语言移植展开:先阐明 "Alternate Languages" 目录的定位与遴选标准,再逐一解析 ANSI C、C、Go、MiniScript、Swift 五份移植实现的流程结构与关键代码,最后给出各端口的运行方式和新增移植的贡献指引。读完本文,你将理解该项目"10 大语言 + 任意附加语言"的组织策略,并能对照原始 BASIC 程序读懂任意一种端口的移植逻辑。

一、文档背景:Alternate Languages 目录是什么

Hello 游戏所在的 00_Alternate_Languages 目录存放的是各游戏在非约定 10 大语言下的实现。按 00_Alternate_Languages/README.md 的说明,主仓库约定的 10 种语言需要同时满足三项标准:

  1. 流行(Popular):以 TIOBE 指数衡量;
  2. 内存安全(Memory safe)
  3. 通常被视为脚本语言(Generally considered a 'scripting' language)

而 Alternate Languages 目录中的实现不受这三项标准约束——因此这里允许出现 C、Pascal 这类非脚本语言(本游戏的 hello.c 就是典型例子)。目录还给出了两条移植规范:

  • 忠实还原原貌:尽量保持与原版一致的"控制台应用"观感(console applications);
  • 保持可移植性:除非无法做到,否则尽量保持代码可移植,并在 README 和文件夹命名中明确说明任何平台限制。

需要特别强调的是,这些附加移植仅供教育目的(for educational purposes only),不计入项目最终的目标移植数量。这也是 00_Alternate_Languages/45_Hello/README.md 要求读者"参考父目录 README"的原因——单看子目录文档只有一段说明,其完整的组织规则都定义在父目录中。

二、游戏本体:Hello 的原始 BASIC 程序结构

Hello 是一个趣味交互程序(心理咨询师模拟),原始实现位于 00_Alternate_Languages/45_Hello/hello.bas。它虽然以"Hello"命名,但核心逻辑是一条完整的对话状态机,主要分为五个阶段:

阶段BASIC 行号行为
标题输出2–6TAB定位居中打印 "HELLO" 与 "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY"
询问姓名10–20自我介绍后INPUT "WHAT'S YOUR NAME";N$读取用户姓名
询问心情30–85问"是否玩得开心",非 YES/NO 会循环追问
四类咨询125–250按 SEX / HEALTH / MONEY / JOB 四类分发不同回复,并支持继续提问
收费结尾300–390索要 5 美元咨询费,校验是否付款后告别

程序的关键设计是三类输入校验循环:第 40–65 行的 YES/NO 校验、第 125–140 行的四分类校验(C$="SEX"等分支,否则输出IS GREEK TO ME并跳转到 250)、以及第 210–217 行的 TOO MUCH/TOO LITTLE 子问题校验。移植时这些循环是忠实度检验的试金石。

三、ANSI C 移植:经典结构化复刻

00_Alternate_Languages/45_Hello/ANSI_C/hello.c 是与 BASIC 结构一一对应的 C 实现,它用三个辅助函数清晰表达了移植思路:

  • tab(int):循环putchar(' ')复刻 BASIC 的TAB(33)/TAB(15)居中效果;
  • get_input(char*):用fgets读取并用strcspn剔除行尾换行,对应 BASIC 的INPUT
  • strings_match:基于strncasecmp大小写不敏感比较,把strings_match(reply, "YES")直接映射到 BASIC 的IF B$="YES"

主函数以donepaidmaybe_moresure四个状态变量驱动,while (!strings_match(reply, "YES") && !strings_match(reply, "NO"))正是 BASIC 第 40 行校验循环的翻译。值得注意的是,仓库根目录下的 hello.c 与之几乎一致,唯一实质差异是strings_match使用strncmp(大小写敏感)——同一游戏存在两份 C 实现,可对照观察移植者对输入容错的取舍。

四、Go 移植:类型化状态机的现代改写

00_Alternate_Languages/45_Hello/go/main.go 是五份移植中结构化程度最高的一份,它不再逐行镜像 BASIC,而是用现代语言特性重构:

  • type PROBLEM_TYPE int8iota定义SEX/HEALTH/MONEY/JOB/UKNOWN枚举,替代 BASIC 中 130–136 行的四次IF C$="..."串行比较;
  • promptForProblems内用switch strings.ToUpper(scanner.Text())做分类分发,default分支返回UKNOWN,对应 BASIC 第 138 行的 "IS GREEK TO ME";
  • 每个咨询分支(solveSexProblemsolveHealthProblemsolveMoneyProblemsolveJobProblem)被拆成独立函数,askQuestionLoop承担外层"ANY MORE PROBLEMS"循环;
  • 收费阶段用time.Sleep(4 * time.Second)模拟原版 BASIC 第 307 行的空转延时循环FOR I=1 TO 2000: NEXT I

这份实现展示了从"行号 GOTO 结构"到"函数 + 枚举 + 循环"的迁移路径,是学习移植方法论的最佳范本。

五、MiniScript 移植:最贴近原版的脚本化直译

MiniScript/hello.ms 采用字符串拼接式直译,ns = input("What's your name? ")与 BASIC 的INPUT一一对应,print " "*33 + "Hello"用字符串乘法替代TAB。其输入处理值得注意:bs = input.lower直接在读取时统一转小写,随后与"yes"/"no"比较,等效于 ANSI C 版的大小写不敏感策略。

该目录还附有 MiniScript/README.md,明确给出了两种运行方式:

  1. 命令行版 MiniScript:从 miniscript.org/cmdline 下载安装后执行miniscript hello.ms
  2. Mini Micro 环境:下载 Mini Micro,挂载该目录为磁盘文件夹,在命令行输入load "hello"run

这是五份移植中唯一附带运行文档的端口,体现了"保持可移植性并明确说明限制"的目录规范。

六、Swift 移植:默认值兜底与函数式输出

Swift/hello.swift 的移植亮点在于健壮性处理:var name = "STRANGER"为姓名提供默认值,读取输入后判断if (input != nil && input != "")才覆盖默认名,对应 BASIC 中未显式处理的空输入边界情况。tab用字符串拼接spaces += " "配合print(spaces, terminator:"")实现不换行的空格输出;get_Input()readLine()的 nil 结果返回空串并统一uppercased(),与 ANSI C 的大小写不敏感策略一致。

七、五份移植的实现对照

端口文件输入比较策略结构风格状态控制
ANSI CANSI_C/hello.cstrncasecmp大小写不敏感函数辅助 + 循环4 个布尔标志
C(根目录)hello.cstrncmp大小写敏感函数辅助 + 循环4 个布尔标志
Gogo/main.gostrings.ToUpper后比较枚举 + 独立求解函数函数返回 / 循环
MiniScriptMiniScript/hello.msinput.lower统一小写直译脚本while true+break
SwiftSwift/hello.swiftuppercased()统一大写函数辅助 + 循环4 个布尔标志

从源码结构看,一个共同的移植模式是:把 BASIC 的 GOTO 跳转(如IF B$="YES" THEN 70)转换为循环内的break/状态位,把行号标签(如 145/160/180/200)转换为独立函数或分支。这正是把 1970 年代 BASIC 结构迁移到现代语言的通用方法论。

八、如何贡献新的移植

依据两份 README 的约定,向 Alternate Languages 目录新增端口需要遵守以下规则:

  1. 任何语言均可:不限于约定的 10 种语言,C、Pascal、MiniScript 等"非内存安全或非脚本"语言同样欢迎;
  2. 忠实原貌:保持控制台应用观感与原文案(原文案本身是复古风格的一部分);
  3. 声明平台限制:代码若依赖特定平台,必须在 README 与文件夹命名中明确说明;
  4. 教育用途定位:附加端口仅供学习,不计入项目移植数量目标,也不参与项目末尾的捐赠统计。

建议新移植以 00_Alternate_Languages/45_Hello/hello.bas 为唯一行为基准,先保证姓名输入、YES/NO 校验、四分类咨询、收费结尾五个阶段完整,再参考 go/main.go 的函数化拆分思路组织代码结构。

九、总结

Hello 游戏的五份附加语言移植,是理解《Basic Computer Games》项目"多语言移植方法论"的绝佳入口:它体量小但状态机完整,从直译(MiniScript)到重构(Go)展示了不同抽象层次的移植风格,而 00_Alternate_Languages/README.md 则从项目层面定义了"10 大语言三标准 + 附加端口教育用途"的组织策略。无论你想学习如何忠实复刻复古终端交互,还是想研究 GOTO 结构如何映射到现代控制流,这份 8KB 的 BASIC 程序及其五个端口都值得精读。

  • 示例工程

【免费下载链接】basic-computer-games

An updated version of the classic "Basic Computer Games" book, with well-written examples in a variety of common MEMORY SAFE, SCRIPTING programming languages. See https://coding-horror.github.io/basic-computer-games/

项目地址:https://gitcode.com/gh_mirrors/ba/basic-computer-games
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询