示例工程【免费下载链接】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点击查看免费下载导读本文聚焦经典《Basic Computer Games》丛书中的冰球模拟游戏Hockey深入剖析其在当前开源仓库中的MiniScript 移植实现hockey.ms。文章将完整覆盖该移植版的两种官方运行方式命令行 MiniScript 与 Mini Micro 虚拟机、全部游戏玩法参数与输入规则并对照原始 BASIC 源码hockey.bas逐段解读其数据结构、随机判定模型与移植修复点帮助你既能立刻把游戏跑起来也能读懂这套 70 年代游戏逻辑在现代脚本语言中的组织方式。一、Hockey 游戏与 MiniScript 移植的背景1.1 游戏来源Hockey 是 1978 年出版的《Basic Computer Games》第 49 号程序原作者为Robert Puopolo由 Creative Computing 的Steve North修改润色。原始 BASIC 文件头部注释清晰地保留了这段历史见 hockey.bas 第 1-4 行ROBERT PUOPOLO ALG. 1 140 MCCOWAN 6/7/73 HOCKEY游戏定义见 49_Hockey/README.md说明这是一场由计算机充当裁判的双人对抗冰球模拟两名人类对手也可以一人同时操控两队轮流进攻。程序会询问队名、六名场上球员的名字、甚至裁判姓名随后围绕传球pass、射门shot与射门区域area三个核心输入展开完整的回合制比赛包含争球face-off、控球、传球配合、扑救、篮板球、4 打 2 等大量对抗细节原作没有罚球penalty机制。1.2 MiniScript 移植版在仓库中的位置按照仓库的整体组织规则见根目录 README.mdMiniScript 并不属于项目约定的 10 种官方移植语言C#、Java、JavaScript、Kotlin、Lua、Perl、Python、Ruby、Rust、VB.NET因此该移植被收录在00_Alternate_Languages备用语言目录下定位为教学与参考用途。MiniScript 移植版的目录结构如下00_Alternate_Languages/49_Hockey/ ├── MiniScript/ │ ├── README.md # 本文所述的关联文档来源、运行方式 │ └── hockey.ms # MiniScript 完整源码396 行 ├── README.md # 游戏说明与移植注意点 └── hockey.bas # 原始 BASIC 源码其中 MiniScript/README.md 声明源码源自 Vintage Basic 网站下载的原始程序随后转换为 MiniScript该文档同时给出了两种运行路径是使用本移植版的第一手指南。二、运行环境准备与两种启动方式运行 MiniScript 移植版需要先获取 MiniScript 运行时。根据 MiniScript/README.md 的说明共有两种主流玩法另可参考同目录下其它 MiniScript 移植如 Rock Scissors Paper 的做法其还额外提供了在线 Try-It 方式。2.1 方式一命令行 MiniScriptCommand-Line MiniScript这是最轻量的运行方式适合日常调试与脚本化运行从 MiniScript 官网的Command-Line MiniScript页面下载对应你操作系统Windows / macOS / Linux的命令行解释器并安装在终端中以hockey.ms文件为参数直接运行miniscript hockey.ms启动后即可在终端内看到游戏标题与开场画面并进入交互输入流程。2.2 方式二Mini Micro 虚拟机Mini Micro 是 MiniScript 官方的复古风格图形虚拟机适合获得更接近原版电脑终端的体验下载并启动 Mini Micro点击界面顶部的磁盘槽位选择Mount Folder...挂载文件夹选中包含hockey.ms与本 README 文件的那个文件夹即00_Alternate_Languages/49_Hockey/MiniScript/在 Mini Micro 的命令提示符中输入load hockey runMini Micro 会加载挂载目录中的hockey.ms并执行游戏输出显示在其终端屏幕中。提示两种方式下游戏行为完全一致均为纯文本交互选择哪种取决于你希望使用轻量命令行还是带虚拟终端界面的环境。三、游戏玩法详解输入规则与操作含义运行后游戏会先询问是否需要查看操作说明Would you like the instructions输入y/n即可。说明内容直接来自源码中的帮助文本见 hockey.ms 第 46-70 行其核心规则如下3.1 三类核心输入提问取值含义Pass0 - 3本次进攻的传球次数0 为直接射门1/2/3 次传球会触发不同的进攻配合描述Shot1 - 4射门方式1 Slapshot大力击射、2 Wristshot腕射、3 Backhand反手射门、4 Snap shot快射Area1 - 4瞄准区域1 左上角、2 右上角、3 左下角、4 右下角所有数字输入都有范围校验。源码中的getNumber(prompt, minVal, maxVal)辅助函数第 26-31 行实现了这一约束——它会循环读取输入直到minVal num maxVal才返回例如传球数被限定在1..3、射门与区域被限定在1..4、比赛分钟数被限定为不小于 1getNumber function(prompt, minVal 1, maxVal 999) while true num input(prompt ? ).val if minVal num maxVal then return num end while end function注意这里使用了 MiniScript 的链式比较语法minVal num maxVal这是该语言区别于 C 系语言的特色之一。3.2 球队与球员设置流程每局比赛开始前setup函数第 72-105 行需要依次完成输入两队队名使用getTwoStrings第 15-24 行读取两个队名可以用英文逗号分隔一次输入如Maple Leafs, Canadiens也可以分两次输入输入比赛时长分钟数getNumber(Enter the number of minutes in a game)最小值为 1A 队教练输入 6 名球员随后B 队教练同样输入 6 名球员输入裁判姓名程序打印双方starting lineup首发阵容然后宣布开场争球opening face-off——由裁判在双方中锋第二位球员之间掷球。球员顺序有严格约定帮助文本第 65-69 行左边锋、中锋、右边锋、左后卫、右后卫、守门员left wing, center, right wing, left defense, right defense, goalkeeper。在源码中这 6 名球员被存放在aNames[1..6]/bNames[1..6]队名存放在下标 7见第 42-43 行。3.3 单回合face-off流程主循环第 358-364 行按设定的分钟数逐轮调用doOneRoundfor l in range(1, roundsInGame) while not doOneRound; end while // (repeat until it returns true) if l roundsInGame then print And were ready for the face-off end fordoOneRound第 215-355 行完整实现了一轮攻防随机决定控球方control floor(2 * rnd) 1打印 XX has control of the puck询问传球数0-3并按p 2个随机数生成一条传球链每条链会强制相邻球员编号不重复第 226-231 行的 while 循环避免出现自己传给自己的荒谬局面若p 0直接询问射门类型否则先打印对应传球配合的解说文案1 次传球、2 次传球的3 on 2、3 次传球的4 on 2情境再询问射门类型询问瞄准区域同时计算机随机生成守门员的薄弱区域a1第 342 行判定结果若所选区域恰好命中薄弱区域a a1进入shootAndScore判定进球否则进入shootBlocked打印扑救描述第 349-353 行。3.4 进球判定与扑救机制进球判定shootAndScore第 107-165 行的核心是一个基于射门权重 z的模运算模型ha[20] floor(100 * rnd) 1 if ha[20] % z ! 0 then break即在 1-100 的随机数中若不能被z整除则判定进球。z由射门类型决定而传球次数会显著降低进球难度z1加成这正是游戏策略性的来源场景z 基准z1传球加成直接射门 Slapshot10—直接射门 Wristshot2移植版修复值—直接射门 Backhand25—直接射门 Snap shot17—传球后射门2/3/4 依射门类型31 次传球、22 次传球、13 次传球可见传球次数越多射门越接近守门员、z1越小从而更容易进球而直接 Backhand 射门z25最难命中。进球后程序会打印Goal/Score提示、用char(7) * 25连续响铃模拟赛场汽笛、打印当前比分按落后方在前的方式排版、输出进球球员与助攻球员未助攻略去、并更新ta/t1/t2/t3统计数组。若随机判定未进球会进入扑救回弹循环a2 % 4 0时打印Save ... rebound/follow up并重新判定。扑救描述shootBlocked第 167-213 行基于 6 面随机骰子floor(6 * rnd) 1产生 6 种不同的守门员动作文案例如1Kick save and a beauty by [GK]踢挡扑救→ 直接结束本轮2spectacular glove save手套扑救→ 继续下一轮3skate save冰刀扑救→ 结束本轮4pad save ... covers up垫挡扑救并压住球5whistles one over the head射偏6face save!! and he is hurt面部挡球受伤后卫掩护攻守双方各有独立的 6 条文案分支第 169-212 行全部引用守门员与后卫的名字营造沉浸感。四、比赛结束与数据统计当所有分钟数回合执行完毕后主循环结束第 368-396 行程序以 30 声铃响char(7)*30与 Thats the Siren 宣告终场并打印三部分数据Final Score最终比分同样按落后方在前的格式输出两队得分Scoring Summary得分总结表分别列出两队前 5 名场上球员不含守门员的Goals进球与Assists助攻统计使用printWithTab辅助函数第 33-35 行把源码中的\t转义符转换为真实制表符char(9)以实现对齐Shots on net射正数两队各自累计的射正次数teamAShotsOnNet/teamBShotsOnNet在每次射门时于 hockey.ms 第 344-348 行累计。五、从 BASIC 到 MiniScript移植的修复与重构亮点对照原始 BASIChockey.bas与 MiniScript 版本可以看到移植者对经典代码的现代改造这既是本移植的核心价值也回应了项目 README 中保持行为一致但采用结构化编程、修复缺陷的移植准则。5.1 修复了原始代码的坠落缺陷游戏说明文档49_Hockey/README.md明确记载了一个已知 Bug原始 BASIC 缺失第 430 行导致FLIPS A WRISTSHOT分支直接落到BACKHANDS ONE分支执行。对照源码可以看到BASIC 中第 420 行打印完 wristshot 文案后第 430 行空缺导致执行流直接进入第 440 行 backhand 的分支。MiniScript 移植版明确修复了该缺陷并在 hockey.ms 第 251-253 行留下了注释说明将 wristshot 的 z 权重独立设为 2else if s 2 then print flips a wristshot down the ice // BUG: missing line 430 in the original caused it to fall through // to the s 3 case. Well instead just do: z 25.2 以函数替代 GOTO 跳转原始 BASIC 通篇依赖ON C GOTO、GOTO行号跳转如GOTO 940、GOTO 260控制流难以跟踪。MiniScript 版本将其彻底重构为模块化函数setup—— 比赛初始化队名、球员、裁判、首发doOneRound—— 单回合攻防主流程shootAndScore—— 进球判定与统计更新shootBlocked—— 扑救文案生成getYesNo/getTwoStrings/getNumber/printWithTab—— 通用输入输出辅助配合命名规范如aNames/bNames代替 BASIC 的A$(7)/B$(7)可读性显著提升。5.3 输入容错与大小写支持项目要求移植版支持大小写输入并改进错误处理。getYesNo使用.lower统一小写后仅取首字符判断第 6-13 行因此Y、y、YES、yes均可接受getNumber通过while true循环反复校验范围getTwoStrings则会处理用户只输入一个队名的情况自动二次追问第 18-22 行。5.4 数据结构的现代化BASIC 版本使用多个独立数组H(20)、T(5)、T1(5)等并通过G1/G2变量在行号间传递球员编号。MiniScript 移植版保留数组语义但做了现代化整理数组大小用途ha21回合临时随机数缓冲传球链、射门判定与比分ha[8]/ha[9]ta/t26两队各球员进球数t1/t36两队各球员助攻数aNames/bNames8两队球员1-6 队名7传球链的生成逻辑第 226-231 行用while true 提前 break 取代了 BASIC 中三个连续IF...GOTO条件对应 hockey.bas 第 330-340 行语义完全等价但结构更清晰。六、延伸阅读与相关资源游戏完整说明与历史出处49_Hockey/README.md含原书页扫描链接与已记录 Bug 清单原始 BASIC 源码便于对比移植差异hockey.bas其他游戏的 MiniScript 移植参考Rock Scissors Paper、Hammurabi其中前者额外记载了在线 Try-It 的第三种玩法项目整体结构与移植语言约定根目录 README.md含全部 96 个游戏按语言完成的进度总表如果你希望在浏览器中先体验原版游戏的交互手感也可以在项目中查看各游戏的 JavaScript 版本实现Hockey 的 JavaScript 移植位于 49_Hockey/javascript 目录可作为 MiniScript 版之外的对照实现。赞分享示例工程【免费下载链接】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点击查看免费下载相关推荐Basic Computer Games 之 Bullfight 的 MiniScript 移植版安装与运行指南Basic Computer Games 之 Bullfight 的 MiniScript 移植版安装与运行指南 本指南面向希望以 MiniScript 语言示例工程gVisor Sentry VFS 深度解析引用计数与 Inheritance 模式的设计内幕gVisor Sentry VFS 深度解析引用计数与 Inheritance 模式的设计内幕 本文基于 gVisor 仓库中的 pkg/sentry/vfs示例工程《Basic Computer Games》Bombs Away 的 MiniScript 移植运行指南与源码解析《Basic Computer Games》Bombs Away 的 MiniScript 移植运行指南与源码解析 本篇技术指南围绕经典 BASIC 游戏《B示例工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
