深入解析 Hi-Lo 游戏:从 1978 年 BASIC 到多种内存安全脚本语言的移植实践
示例工程【免费下载链接】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点击查看免费下载导读本文围绕 classic BASIC 游戏 Hi-Lo00_Alternate_Languages/47_Hi-Lo/README.md 中收录的移植作品展开完整还原其游戏规则与作者设定并以仓库内 hi-lo.bas 原始 BASIC 源码为主线逐语言剖析 Python、C#、Java、Rust、Ruby、JavaScript 等移植版的实现思路。读完本文你将掌握该游戏的核心算法随机奖金生成、六次机会的高低提示、累计赢钱与重玩循环并了解本仓库中忠实还原 70 年代控制台观感、同时保持代码可移植性的移植规范。一、游戏背景与定位Hi-Lo 是经典电子游戏合集Basic Computer Games1978 年中的猜数字游戏作者为美国德克萨斯州沃斯堡Fort Worth, Texas的 Dean Altman。它本质上是同一合集中 GUESS 游戏的变体不再只是猜测 1 到 100 之间的数字而是猜中金额即可赢得美元奖金。在仓库结构上Hi-Lo 有两条实现分支标准目录 47_Hi-Lo包含 10 种约定语言Python、C#、Java、JavaScript、Ruby、Rust、VB.NET、Kotlin、Perl、Lua 等的移植遵循主仓库对受欢迎TIOBE 指数、内存安全、一般被视为脚本语言的三大语言选择标准备用语言目录 00_Alternate_Languages/47_Hi-Lo/收录了不在约定 10 种之内的其他语言版本如 Pascal、D、Elm、Nim、Go 等按 00_Alternate_Languages/README.md 的说明这些实现不受三大标准约束例如允许 C 或 PASCAL仅用于教学目的不参与项目捐赠统计但同样要求保持忠实于原始控制台观感并尽量可移植。二、核心游戏规则作者原始设定根据 47_Hi-Lo/README.md 记录的作者规则说明游戏共 7 条规则所有移植版都必须忠实还原HI-LO 奖池jackpot中的金额在 1 到 100 美元之间。玩家有6 次机会猜测奖池金额。每次猜测后计算机会提示猜测过高TOO HIGH还是过低TOO LOW。若 6 次机会用完仍未猜中计算机公布奖池金额。若在 6 次机会内猜中计算机登记该次赢得的金额。每轮猜测结束后玩家可选择继续游戏或结束程序开始新一局时奖池会生成一个新的随机金额。若玩家多次获胜赢得的金额会累计相加。一个关键行为细节出现在各移植版中如果某一轮 6 次机会内未猜中累计赢钱会清零重置R0而不是保留之前的奖金。这正是该游戏与普通猜数字游戏的最大差异——高风险、高回报的连赢机制。三、原始 BASIC 源码逐行剖析hi-lo.bas 全程序仅 29 行是典型的小型 1970 年代 BASIC 程序逻辑结构非常清晰10 PRINT TAB(34);HI LO 20 PRINT TAB(15);CREATIVE COMPUTING MORRISTOWN, NEW JERSEY 30 PRINT:PRINT:PRINT 100 PRINT THIS IS THE GAME OF HI LO.:PRINT ... 160 R0 累计赢钱清零 170 B0:PRINT 180 YINT(100*RND(1)) 生成 0~99 随机数作为奖池金额 200 PRINT YOUR GUESS; 210 INPUT A 220 BB1 猜测次数加一 230 IF AY THEN 300 猜中跳转到获奖输出 240 IF AY THEN 270 250 PRINT YOUR GUESS IS TOO LOW.:GOTO 280 270 PRINT YOUR GUESS IS TOO HIGH. 280 PRINT:IF B6 THEN 200 未满 6 次继续猜 290 PRINT YOU BLEW IT...TOO BAD...THE NUMBER WAS;Y 295 R0:GOTO 350 300 PRINT GOT IT!!!!!!!!!! YOU WIN;Y;DOLLARS. 310 RRY 320 PRINT YOUR TOTAL WINNINGS ARE NOW;R;DOLLARS. 350 PRINT:PRINT PLAY AGAIN (YES OR NO); 360 INPUT A$:IF A$YES THEN 170 380 PRINT:PRINT SO LONG. HOPE YOU ENJOYED YOURSELF!!! 390 END从源码结构可以看出核心算法骨架随机金额YINT(100*RND(1))生成 0~99 的整数即 1~100 的等效表示因为比较逻辑只依赖大小关系对实际游玩无影响猜测循环INPUT A读取猜测BB1计数通过与Y的比较输出 TOO HIGH / TOO LOW 提示IF B6 THEN 200控制最多 6 次猜中分支跳转到行 300输出GOT IT!!!!!!!!!! YOU WIN Y DOLLARS.累计RRY失败分支6 次未中则输出YOU BLEW IT...TOO BAD...THE NUMBER WAS Y并把累计奖金清零R0重玩判断INPUT A$读取字符串只有输入YES精确匹配、未做大小写归一化才回到行 170 开始新一局否则输出结束语SO LONG. HOPE YOU ENJOYED YOURSELF!!!。值得注意的是BASIC 版本对输入大小写敏感必须输入YES且没有对非数字输入做防护——这是现代移植版普遍改进的两个点。四、现代语言移植的忠实还原与工程化改进仓库为每种语言提供了完整可运行的移植。以下结合源码分析各实现的异同。4.1 Python 版最贴近 BASIC 的直译47_Hi-Lo/python/hilo.py 是最能体现原始逻辑的版本。它用常量MAX_ATTEMPTS 6与QUESTION_PROMPT ? 抽象出关键参数主循环结构与 BASIC 完全对应secret random.randint(1, 100)生成 1~100 的奖池金额for _attempt in range(MAX_ATTEMPTS)实现六次机会命中时total_winnings secret累计奖金并打印当前总额未命中则打印YOU BLEW IT...TOO BAD...THE NUMBER WAS {secret}重玩判定通过input().upper()做大小写归一化只有YES才继续。Python 版还保留了原版的横幅输出CREATIVE COMPUTING MORRISTOWN, NEW JERSEY和完全一致的提示语体现了忠实于原始 look-and-feel的移植要求。4.2 C# 版Top-level Statements 与健壮输入47_Hi-Lo/csharp/Program.cs 使用现代 C# 的 top-level statements 编写在还原逻辑的同时加入了输入校验int jackpot rnd.Next(100) 1; // [0..99] 1 - [1..100]关键工程化细节用Random rnd new()作为统一随机源rnd.Next(100) 1明确注释了[0..99] 1 - [1..100]的区间换算自定义ReadInt辅助函数int.TryParse解析失败时输出!Invalid Number Entered.并循环重试这是对 BASIC 版无输入防护的改进Tab(n)辅助函数生成 n 个空格用于还原TAB(34)的居中排版重玩判定Console.ReadLine().ToUpper().StartsWith(Y)比 BASIC 的精确匹配更宽容YES/Y均可失败时累计奖金归零的语义在guess 6分支中体现。4.3 Java 版状态机驱动的面向对象实现47_Hi-Lo/java/src/HiLo.java 是仓库中结构最工程化的移植作者在注释中明确说明不引入新特性、不加多余文本与错误检查忠实还原 70 年代 BASIC。它用GAME_STATE枚举实现了一个有限状态机private enum GAME_STATE { STARTING, START_GAME, GUESSING, PLAY_AGAIN, GAME_OVER }STARTING首次进入打印介绍文本START_GAME调用init()重置猜测计数并生成随机数打印O.K. I HAVE A NUMBER IN MIND.GUESSING读取猜测validateGuess()比较大小并输出提示猜中则累计奖金并跳转PLAY_AGAIN6 次未中则打印奖金金额、清零奖金并跳转PLAY_AGAINPLAY_AGAIN通过yesEntered()接受Y/YES不区分大小写决定回到START_GAME还是进入GAME_OVER。同时47_Hi-Lo/java/src/HiLoGame.java 作为独立入口类调用hiLo.play()将启动逻辑与游戏逻辑分离。Java 版还用常量LOW_NUMBER_RANGE 1、HIGH_NUMBER_RANGE 100、MAX_GUESSES 6显式声明了游戏参数随机数通过Math.random()换算到[1, 100]闭区间。4.4 Rust 版类型安全与输入重试47_Hi-Lo/rust/src/main.rs 体现了 Rust 的强类型风格let jackpot_amount rand::thread_rng().gen_range(1..101);使用randcrate 的gen_range(1..101)生成 1~100 随机数猜测输入经guess.trim().parse::u32()解析Err(_)时打印PLEASE ENTER A NUMBER VALUE.并continue实现非数字则重新提示的重试逻辑且重试不消耗猜测次数因为continue前没有递增计数——这是 Rust 版的一个细节行为与 Python 版的int(input())直接抛异常不同累计奖金类型为u32第 6 次i 5仍未猜中时清零奖金重玩判定用tocontinue.trim().to_ascii_uppercase()与YES比较。4.5 Ruby 版面向对象的直白表达47_Hi-Lo/ruby/hi_lo.rb 将逻辑拆分为intro、make_guess、check_guess、blew_it、outro五个具名方法可读性极强常量MAX_TRIES 6与RANGE (1..100)集中声明游戏参数介绍文本通过RANGE.min/RANGE.max动态插值避免硬编码check_guess用三元表达式guess number ? HIGH : LOW合并两条分支失败判定blew_it unless guessed_correctly语义清晰重玩判定break if gets.start_with?(/n/i)与 BASIC 相反——以 N 开头即退出其余输入一律继续是各版本中对重玩输入最宽松的实现不要求精确输入 YES。4.6 JavaScript 版浏览器化的异步交互47_Hi-Lo/javascript/hi-lo.js 由著名开发者 Oscar Toledo G.nanochess从 BASIC 转换运行于浏览器环境通过document.getElementById(output)追加文本节点模拟控制台输出input()返回Promise动态创建INPUT元素、监听回车键event.keyCode 13后移除输入框并resolve输入值配合async function main()的await实现顺序交互随机数用Math.floor(100 * Math.random())还原 BASIC 的INT(100*RND(1))写法连原始版本0~99的语义都保持一致配套的 47_Hi-Lo/javascript/hi-lo.html 提供页面容器打开即玩无需命令行环境。五、各版本行为差异对照行为点BASIC 原版PythonC#JavaRustRubyJavaScript随机金额范围0~99INT(100*RND(1))1~1001~1001~1001~1001~1000~99忠实还原猜测上限6666666非数字输入处理无防护抛异常循环重试无parseInt循环重试gets.to_i静默转 0parseInt得 NaN重玩判定精确YESYES大写归一以 Y 开头Y/YES忽略大小写YES大写归一以 N 开头即退出精确YES大写归一失败后奖金清零清零清零清零清零清零清零这张对照表说明各移植版在忠实还原原始规则六次机会、过高/过低提示、猜中累计、失败清零上高度一致差异集中在输入健壮性与重玩判定的宽容度上——这正是忠实原版观感与现代工程实践之间最常见的平衡点。六、如何运行与体验各版本均可在本地直接运行仓库只读仅需查看与运行Python在 47_Hi-Lo/python/ 目录执行python3 hilo.pyC#进入 47_Hi-Lo/csharp/使用dotnet run项目文件为HiLo.csprojJava编译并运行 47_Hi-Lo/java/src/HiLoGame.java入口类内部委托给HiLoRust在 47_Hi-Lo/rust/ 执行cargo run依赖randcrate见Cargo.tomlRuby在 47_Hi-Lo/ruby/ 执行ruby hi_lo.rbJavaScript直接用浏览器打开 47_Hi-Lo/javascript/hi-lo.htmlVB.NET / Kotlin / Perl / Lua分别见 47_Hi-Lo/vbnet/、47_Hi-Lo/kotlin/HiLo.kt、47_Hi-Lo/perl/hi-lo.pl、47_Hi-Lo/lua/hilo.lua。七、移植要点总结结合 47_Hi-Lo/README.md 的Porting Notes留白与各实现的实际代码移植 Hi-Lo 时有四点值得注意随机数的区间语义BASIC 的INT(100*RND(1))产生 0~99而多数现代版本选择 1~100 的直觉区间。无论采用哪种必须保持与提示逻辑的自洽比较只依赖大小关系两种区间对玩法无影响。累计奖金的生命周期猜中累加RRY6 次失败清零R0——这一惩罚性清零是游戏张力所在任何移植都不可遗漏。输入与重玩判定的宽容度BASIC 精确匹配YES且大小写敏感现代版本普遍归一化大小写甚至允许YC#、Java或以 N 退出Ruby。若需严格还原历史体验请参照 BASIC 原版。排版还原TAB(34)居中标题等格式细节在 C#Tab函数、JavaScripttab函数、Rust{: 39}格式化中均有对应实现体现了 00_Alternate_Languages/README.md 强调的忠实于原始 look-and-feel控制台应用原则。结语Hi-Lo 是一个体量虽小、但移植价值极高的经典案例它同时涉及随机数生成、循环控制、输入解析、累计状态与游戏循环状态机五种基础编程要素。通过对比 hi-lo.bas 与仓库中 Python、C#、Java、Rust、Ruby、JavaScript 等版本的实现开发者可以清晰看到忠实还原与工程改进之间的权衡艺术——这正是本仓库作为教学资源的核心价值所在。赞分享示例工程【免费下载链接】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点击查看免费下载相关推荐Appium 共享 Oxlint/Oxfmt 配置包 appium/oxc-config从版本日志看集中式代码规范体系的落地Appium 共享 Oxlint/Oxfmt 配置包 appium/oxc config从版本日志看集中式代码规范体系的落地 本文基于 Appium mon示例工程basic-computer-games 的 Bombardment 替代语言移植从 1978 年 BASIC 到 Go 与 MiniScript 的实战剖析basic computer games 的 Bombardment 替代语言移植从 1978 年 BASIC 到 Go 与 MiniScript 的实战剖析示例工程如何快速上手PilotGo-plugin-redis5分钟搭建Redis集群监控系统如何快速上手PilotGo plugin redis5分钟搭建Redis集群监控系统 前往项目官网免费下载 https://ar.openeuler.org示例工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考