拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Alternate Languages 语言选型标准与移植实践:以 basic-computer-games 的 Dice 多语言实现为例

Alternate Languages 语言选型标准与移植实践以 basic-computer-games 的 Dice 多语言实现为例【免费下载链接】basic-computer-gamesAn 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/33_Dice/README.md 展开解析该文档定义的 Alternate Languages非约定十种语言的补充移植选型标准、目录组织方式与移植政策并以经典游戏 Dice模拟掷一对骰子并统计点数出现频率在 C、Go、Nim、Julia、MiniScript 中的真实移植为样本逐行对比各语言如何还原原始 BASIC 程序的逻辑与原汁原味的控制台外观。读完本文你将理解该项目区分标准语言与Alternate Languages的判定依据TIOBE 流行度、内存安全、脚本语言三大标准并掌握如何读懂、运行与复刻这批教育性质的补充移植。一、关联文档说了什么Alternate Languages 的定位00_Alternate_Languages/33_Dice/README.md 全文虽短但明确传达了四层信息它们是整个00_Alternate_Languages目录的宪法导航指向本目录的说明以父目录 00_Alternate_Languages/README.md 为准原文Please refer to thereadme.mdin the parent folder.。目录语义每个子文件夹代表该程序到某种非约定十种语言的移植。三条选型标准这些补充语言不满足以下三条标准中的至少一条——按 TIOBE 指数流行Popular by TIOBE index、内存安全Memory safe、通常被认为是脚本语言Generally considered a scripting language。移植政策欢迎添加额外移植但这些移植仅用于教育目的for educational purposes only。父目录 00_Alternate_Languages/README.md 进一步补充了细则该目录中的实现不受上述三条标准约束例如 C 或 Pascal 在这里是被允许的so for example, (here only) C or PASCAL are allowed。移植应忠实还原原始程序的观感Please still remain faithful to original look-and-feel (console applications)。尽量保持代码可移植若无法移植则必须在 README 和文件夹命名中明确说明限制。补充移植不计入项目捐赠总数donation total。二、三大选型标准与标准十种语言清单要理解Alternate意味着什么必须先看项目根 README.md 中定义的标准十种语言。项目基于 2022 年 TIOBE 指数筛出同时满足内存安全与通用脚本语言两条标准的语言作为目标移植语言#语言说明1C#2Java3JavaScript4Kotlin5Lua6Perl7Python8Ruby9Rust10VB.NET值得注意的是根 README 记录了两次标准清单的演进这些是项目官方陈述的事实2022 年 3 月移除 Pascal / Object Pascal替换为 Rust原因在于项目无法确认 Pascal 是否真正内存安全原有的 Pascal 移植被移入00_Alternate_Languages目录。同时加入 LuaLua 在 2022 年进入 TIOBE 前 20且既内存安全又是脚本语言。由此可以推导出Alternate Languages目录的判定逻辑凡是 10 种约定语言之外的语言无论它是否满足三条标准都归入00_Alternate_Languages。例如本项目中的 Julia 与 MiniScript 实际上兼具内存安全与脚本语言属性只是不在约定清单中而 C 则因非内存安全、非脚本语言而属于典型的 alternate 语言。这一点正是Alternate Languages文档所强调的该目录按是否为约定十种语言划分而非按三条标准是否满足划分。根 README 还给出项目整体指南适用于所有移植包括 alternate 移植忠实于原始程序、支持大小写输入、使用结构化编程与子程序、注释充分、不过度追求花哨技巧、不提交 IDE 或构建系统专属文件。三、以 Dice 为例原始 BASIC 程序的逻辑骨架一切移植的原型是 00_Alternate_Languages/33_Dice/dice.bas原作者 Danny Freidus出自 1978 年《BASIC Computer Games》。整段逻辑只有约 30 行却覆盖了后续所有移植必须还原的四个要素10 DIM F(12) 30 PRINT THIS PROGRAM SIMULATES THE ROLLING OF A 40 PRINT PAIR OF DICE. ... 80 FOR Q1 TO 12 90 F(Q)0 100 NEXT Q 110 PRINT:PRINT HOW MANY ROLLS; 120 INPUT X 130 FOR S1 TO X 140 AINT(6*RND(1)1) 150 BINT(6*RND(1)1) 160 RAB 170 F(R)F(R)1 180 NEXT S 190 PRINT TOTAL SPOTS,NUMBER OF TIMES 200 FOR V2 TO 12 210 PRINT V,F(V) 220 NEXT V 223 INPUT Z$ 224 IF Z$YES THEN 80分解其核心要素频率数组DIM F(12)声明 13 个元素索引 0–12实际只用 2–12两个骰子和的最小值为 2。每次游戏开始前第 80–100 行清零。骰子模拟INT(6*RND(1)1)用取整把RND的[0,1)均匀分布映射到 1–6 的整数两个骰子相加得到和R。统计累加F(R)F(R)1是整段程序的题眼——用结果值直接作为数组下标省去了一次查找。输出与重玩打印TOTAL SPOTS/NUMBER OF TIMES两列表格若用户输入YES则跳回第 80 行重新清零并再来一轮。原文还在开场提示中警告非常大的数字会耗时很久尤其超过 5000 的输入IN PARTICULAR, NUMBERS OVER 5000这是因为 BASIC 的RND生成是解释执行、逐次循环复杂度为 O(n)。四、六个 Alternate 移植的源码级对比00_Alternate_Languages/33_Dice 目录下共有 5 种补充语言的实现C、Go、Nim、Julia、MiniScript外加原始dice.bas作为对照。逐一分析它们如何还原上述四个要素是理解同一程序在不同语言中的移植艺术的最佳途径。4.1 C最贴近硬件的移植dice.c00_Alternate_Languages/33_Dice/C/dice.c 用rand() % 6 1模拟单颗骰子用rolls[13]数组保存 2–12 的频数并额外用percent()函数输出每个点数出现的百分比float percent(int number, int total){ float percent; percent (float)number / (float)total * 100; return percent; }C 版本与原始 BASIC 有两个明显差异一是一次性运行没有实现TRY AGAIN重玩循环输入times后直接统计并退出二是输出增强在每行追加了百分比列。这恰好印证了 alternate 移植教育目的的定位——它不是逐字节复刻而是演示同一算法在目标语言中的惯用写法。注意srand(time(NULL))初始化随机种子这是 C 语言中让rand()每次运行结果不同的必要步骤对应 BASIC 中RND的隐式播种。4.2 Go带错误处理的现代移植main.go00_Alternate_Languages/33_Dice/go/main.go 是六个移植中结构最完整的一个它用printWelcome()函数承载开场白对应 BASIC 的 30–70 行PRINT用bufio.NewScanner(os.Stdin)逐行读取输入并实现了原始 BASIC 不具备的输入校验numRolls, err : strconv.Atoi(scanner.Text()) if err ! nil { fmt.Println(Invalid input, try again...) continue }这直接呼应根 README 中improved error handling for bad or erroneous input改进错误输入处理的项目目标。统计逻辑用注释明确说明了 13 元素数组的设计意图The first two indices (0 1) are ignored, leaving just the indices that match the roll values (2 through 12). 重玩判断把输入转为大写后仅接受Y相比原始 BASIC 的Z$YES更宽松。4.3 Nim类型化数组的优雅表达dice.nim00_Alternate_Languages/33_Dice/nim/dice.nim 展示了 Nim 的静态类型能力直接用自定义下标的数组类型表达 2–12 的合法结果域var f: array[2..12, int]这个array[2..12, int]声明让数组下标天然限定在 2–12 之间把 BASIC 中声明 0–12、只用 2–12的隐式约定提升为编译期强制约束是移植中对原程序巧妙技巧F(R)F(R)1的数组下标映射的最忠实且最安全的翻译。随机数使用rand(1..6)调用前randomize()播种重玩判断接受normalize()后的yes或y。4.4 Julia惯用法与边界处理Dice.jl00_Alternate_Languages/33_Dice/Julia/Dice.jl 的头部注释明确记录了它对原程序的唯一改动——any string starting with y or Y will be accepted, instead of only YES接受任何以 y/Y 开头的字符串而非仅 YES这是遵循现代编码规范、兼容大小写输入的典型做法。实现上值得注意两点索引偏移技巧Julia 数组默认从 1 开始而骰子和最小为 2因此代码用counts[dice_sum-1] 1把和映射到 11 元素数组sum of 1 is impossible, the array will only have 11 values。入口惯用法if abspath(PROGRAM_FILE) __FILE__; main(); end让脚本既可被include复用又可在作为主程序直接运行时自动执行main()是 Julia 社区标准的模块化入口写法。4.5 MiniScript最忠实的逐行翻译dice.ms00_Alternate_Languages/33_Dice/MiniScript/dice.ms 由 Joe Strout 移植是所有版本中在结构上最接近原始 BASIC 的一个runOnce函数对应 BASIC 的 80–220 行主循环对应TRY AGAIN逻辑。三个细节值得学习骰子模拟用ceil(6 * rnd)等价于 BASIC 的INT(6*RND(1)1)且刻意保留了die1/die2两个变量名。输出右对齐用字符串切片技巧( v)[-6:]注释明确说明the [-6:] trick below right-aligns the number——这是 MiniScript 字符串下标风格的体现。askYesNo函数把重玩提问封装成只接受y/n单字符的输入循环比原始 BASIC 更严谨。4.6 重玩输入策略的横向对比原始 BASIC 只接受严格等于YES的输入而各移植遵循根 README 允许大小写输入 改进错误处理的指导各自演进这一演进本身就是一篇微型输入校验设计教材版本判定逻辑文件BASIC 原始版Z$YES严格相等大小写敏感dice.basGo转大写后等于Ymain.goNim归一化后为yes或ydice.nimJulia首字符为y/Y任意长度前缀Dice.jlMiniScript只接受单字符y/n否则循环重问dice.msC未实现重玩循环一次性运行dice.c五、标准语言版本与 alternate 版本的分工从项目根 README.md 的进度表toggle for game by language table可以看到33_Dice 这一游戏在标准十种语言中除 Kotlin 外均已实现C#、Java、JavaScript、Lua、Perl、Python、Ruby、Rust、VB.NET 九个目录位于主目录 33_Dice 下。这些标准版本面向捐赠目标每完成一个约定语言移植作者向 Girls Who Code 捐赠 5 美元而 00_Alternate_Languages/33_Dice 下的 C、Go、Nim、Julia、MiniScript 则明确不计入捐赠总数纯粹以教育为目的。理解这一分工就理解了为什么同一个游戏在仓库中会同时存在两套独立的移植树。六、如何查看与运行这些移植仓库是只读的以下运行方式仅供本地查看验证需要先安装对应语言工具链BASIC 原版使用 Vintage BASIC 运行 dice.bas原始游戏行为验证可参考主目录 33_Dice 下的 README。Cgcc dice.c -o dice ./dice需要 GCC 编译器。Gogo run main.go需要 Go 工具链。Nimnim c -r dice.nim需要 Nim 编译器。Juliajulia Dice.jl需要 Julia文件头注释说明了与原程序的差异。MiniScript需要 MiniScript 解释器环境加载执行 dice.ms各语言子目录内的 README如 Julia/README.md、MiniScript/README.md通常附有更具体的运行说明。七、总结Alternate Languages 文档教会我们的三件事回到 00_Alternate_Languages/33_Dice/README.md 本身这篇简短的导航文档浓缩了项目移植生态的完整规则边界清晰00_Alternate_Languages是约定十种语言之外的自由区三条选型标准TIOBE 流行度、内存安全、脚本语言在此不强制但所有移植仍需保持控制台观感与可移植性。教育优先补充移植不计入捐赠其价值在于向学习者展示同一算法在不同语言中的惯用表达——正如 Dice 的 13 元素频数数组在 BASIC 里是DIM F(12)在 Nim 里是array[2..12, int]在 Julia 里是索引偏移的 11 元素数组。忠实与改进的平衡忠实于原程序逻辑与外观同时允许按现代规范改进大小写输入、错误处理、输入宽容度这一原则贯穿所有 alternate 移植也正是这个持续更新的经典项目能够作为编程教学素材长期存在的根本原因。【免费下载链接】basic-computer-gamesAn 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),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门