ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深入解析 Basic Computer Games 之 Poker:规则、AI 下注策略与移植注意事项

深入解析 Basic Computer Games 之 Poker:规则、AI 下注策略与移植注意事项 示例工程【免费下载链接】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点击查看免费下载导读Poker 是 1978 年经典书籍《Basic Computer Games》中的第 71 号游戏由 Trinity College哈特福德康涅狄格州的 A. Christopher Hall 编写。在这款双人五张换牌扑克draw poker中你与计算机各持 $200 资金展开对局直到一方输光为止。本文以 71_Poker/README.md 为骨架完整还原游戏规则、下注约定与作者信息并结合本仓库中的原始 BASIC 源码poker.bas与 C# 移植实现71_Poker/csharp深入解析计算机的下注策略、牌型评估算法、资金耗尽时的卖手表机制以及官方文档记录的已知缺陷——帮助你既会玩、又懂移植、更能规避历史遗留问题。游戏概览一场人与计算机的换牌扑克根据 71_Poker/README.md 的描述这是一场人与计算机互为对手的 draw poker换牌扑克开局资金游戏开始时双方各持有 $200。结束条件当任意一方资金耗尽时游戏结束如果你人类玩家输光计算机会好心地提议回购你的手表或钻石领带夹tie tack换取继续游戏的机会。下注节奏换牌前由计算机开注opens the betting before the draw换牌后由你开注you open the betting after the draw。弃牌与过牌约定如果你觉得手里的牌毫无价值想弃牌下注0换牌前想跟注过牌check可以下注0.5。跟注与加注当然如果计算机已经下注你必须匹配match其注额才能换牌如果手牌够好你随时可以加注raise。游戏开场时BASIC 原版会在终端打出标题与规则提示见 poker.basWELCOME TO THE CASINO. WE EACH HAVE $200. I WILL OPEN THE BETTING BEFORE THE DRAW; YOU OPEN AFTER. TO FOLD BET 0; TO CHECK BET .5. ENOUGH TALK -- LETS GET DOWN TO BUSINESS.C# 移植版将这些文案抽取到了资源文件 Instructions.txt 中并在 Game.cs 的Play()方法里先输出标题与规则再创建Deck、Human、Computer与Table对象进入对局循环。原始出处与移植背景71_Poker/README.md 明确给出了游戏的历史来源游戏作者为A. Christopher Hall来自Trinity College, Hartford, Connecticut原版程序发表于Basic Computer Games (1978)一书本仓库的 BASIC 源文件poker.bas下载自 Vintage Basic 网站http://www.vintage-basic.net/games.html。在本仓库中该游戏拥有完整的跨语言移植生态各语言目录下均有对应的 README.md 与实现语言目录说明C#71_Poker/csharp结构最完整的面向对象移植包含 Cards / Players / Strategies / Resources 四个子命名空间Java71_Poker/java/Poker.java单文件 Java 移植代码注释中说明了基于 OCR 版 BASIC 源码移植JavaScript71_Poker/javascript/poker.js 与 poker.html浏览器可运行的 HTML JS 版本Python71_Poker/python对应 README 记录了移植说明Ruby / Perl / Lua / Kotlin / VB.NET各对应目录各语言目录下均有独立实现各语言目录下的 README 基本遵循统一的格式注明原始来源Vintage Basic、翻译目标语言、以及可选的移植注意事项。核心玩法拆解从发牌到比牌要理解这款游戏的移植难点首先需要吃透其核心回合流程。以 Table.cs 的PlayHand()方法为主线一局完整的流程如下资金检查与底注Ante每局开始前先检查计算机资金Computer.CheckFunds()余额 ≤ 底注即视为破产随后输出 The ante is $5. I will deal:底注固定为$5Table.cs 中Ante { get; } 5。若人类玩家余额不足以支付底注会触发Human.RaiseFunds()卖手表筹资。发牌Deal洗牌后双方各缴 $5 底注入池Pot各发 5 张牌并打印你的手牌Table.cs。换牌前下注Pre-draw betting计算机先行表态——开注Ill open with $X或过牌I check.随后轮到你下注Table.cs。换牌Draw询问你换几张牌上限 3 张输入超出会提示 You cant draw more than three cards.并输入要换掉的牌号计算机根据策略保留/替换自己的牌Table.cs。换牌后下注Post-draw betting这轮由你开注若你跟注/过牌后计算机仍有行动空间它可能跟注或加注。比牌Showdown打印双方手牌并比较牌型胜者拿走整个底池平局则 The hand is drawn.底池保留到下一局Table.cs。继续或结束打印双方余额询问 Do you wish to continue任一方破产则游戏结束Table.cs。下注输入约定在 BASIC 原版中下注与换牌输入直接通过INPUT完成规则校验集中在 3050–3470 行poker.bas。C# 移植版将这一逻辑封装在 IReadWriteExtensions.cs 的ReadHumanStrategy()中规则如下输入0→ 弃牌Fold当前无任何注额且输入0.5→ 过牌Check否则提示 No small change, please.输入其它非负整数 → 视为下注/加注Bet若你的跟注总额仍低于计算机的当前注额会提示 If you cant see my bet, then fold.要求重新输入若余额不足会提示 You cant bet with what you havent got.并尝试卖手表筹资见下文。计算机 AI基于牌型的下注策略计算机并非随机下注而是根据手牌强弱与牌型等级动态选择策略。C# 移植版把策略建模为 Strategies 目录下的抽象类Strategy及其子类Bet(amount)直接下注指定金额Bet.csRaise加注默认基础值为 2Raise.csFold弃牌Value -1Fold.csCheck过牌Value 0Check.csBluff(amount, keepMask)虚张声势下注同时可指定换牌时保留哪些牌Bluff.cs。换牌前的决策NewHand计算机在拿到新牌后会立即依据(IsWeak, Rank Three, Rank FullHouse)三个条件做模式匹配决策Computer.cs条件概率分支策略手牌很弱IsWeak随机数 2/10Bluff(23, 0b11100)或Bluff(23, 0b11110)手牌很弱随机数 1/10Bluff(23, 0b11111)全保留假装强牌手牌很弱其余情况Fold弃牌不弱、但不到三条随机数 2/10Bluff(23)不弱、但不到三条其余情况Check达到三条、不到葫芦—Bet(35)葫芦及以上随机数 1/10Bet(35)否则Raise换牌后的决策DrawCards换牌完成后计算机根据新的牌型再次调整策略Computer.cs原本就在虚张声势Bluff→ 继续保持Bluff(28)换牌后手牌变弱 →Fold达到三条 → 10% 概率Bet(19)否则Raise达到葫芦 → 10% 概率Bet(11)否则Bet(19)强牌葫芦以上→ 直接Raise。保留牌掩码KeepMask由 Hand.cs 的Analyze()计算同花保留全部 5 张0b11111对子/三条/葫芦按对子位置生成掩码无对子时若存在顺子可能则保留 4 张0b1111或0b11110否则只保留最大牌0b11000。计算机按掩码中为 0 的位换掉对应位置的牌Computer.cs。跟注与加注的博弈逻辑当人类玩家下注后计算机的响应逻辑集中在 Table.cs若人类下注刚好等于计算机注额 → 收注进底池本轮下注结束若人类下注超过 5 且计算机策略为Fold→ 计算机直接弃牌I fold.若人类下注超过计算机策略值的 3 倍 → 计算机选择看你Ill see you.跟注除非它本身就是Raise策略其余情况 → 计算机计算加注额Human.Bet - Computer.Bet 随机 0~9输出 Ill see you, and raise you $X并更新注额后再次轮到你。C# 中实际下注额由GetWager(int wager)生成基础注额加上一个 0–9 的随机抖动wager _random.Next(10)这是原版 BASIC 中VZFNA(0)模式poker.bas的忠实还原当计算机余额不足以跟注时会尝试通过RaiseFunds()买回手表自救详见下文资金耗尽机制。牌型评估HandRank 体系与已知局限C# 移植版把牌型定义在 HandRank.cs 中共 9 个等级按数值从弱到强牌型数值显示文案Schmaltz高牌1schmaltz, X highPartialStraight部分顺子2无显示串内部用Pair一对3a pair of XsTwoPair两对4two pair, XsThree三条5three XsStraight顺子6straight, X highFlush同花7a flush in [suit]FullHouse葫芦8full house, XsFour四条9four Xs牌型比较通过重载/运算符实现HandRank.cs同级牌型再比较HighCard最大牌这与 BASIC 原版中先比U值再比FNB(D)/FNB(M)的比较逻辑一致poker.bas。需要注意的牌型局限源码中明确注释原版不检测同花顺straight flush与皇家同花顺royal flush——HandRank.cs 注释 The original code does not detect a straight flush or royal flush即同花顺会被按同花处理。顺子的识别是残缺的Analyze()只检查排序后第 1–4 张与第 2–5 张的跨度是否为 3Hand.cs本质上只能识别中间 4 张连续的部分顺子若首尾同时跨 3 才判定为完整顺子。A-2-3-4-5 最小顺子等边界形态由于 Rank 从 2数值 2到 Ace数值 14Analyze()用差值等于 3 判定顺子无法识别 A 作为 1 的环绕顺子。这些牌型局限属于原版游戏的历史行为各语言移植版均以忠实还原为首要目标而非修正算法。资金耗尽与卖手表/领带夹机制README 提到The game ends when either player runs out of money, although if you go broke the computer will offer to buy back your wristwatch or diamond tie tack.这套变卖家产续命机制是这款游戏最具特色的部分也是已知缺陷最集中的地方。人类玩家的筹资流程当人类玩家余额不足以支付下注或底注时Human.RaiseFunds()被触发Human.cs提示 You cant bet with what you havent got.询问 Would you like to sell your watch计算机随机出价70% 概率出 $75Ill give you $75 for it.30% 概率只出 $25Thats a pretty crummy watch - Ill give you $25.对应 BASIC 原版 poker.bas 中的FNA(0)7分支卖掉手表后获得相应现金HasWatch置为 false可继续下注若拒绝卖表且已无其它筹资手段则IsBroke true游戏结束并输出 Your wad is shot. So long, sucker!。计算机的买回手表自救计算机在 Computer.cs 的RaiseFunds()中拥有类似机制当它余额不足以跟注且人类已无手表可卖时会询问 Would you like to buy back your watch for $50若你同意计算机直接 $50并拿回手表注意源码注释明确说明原版代码并没有从玩家那里扣掉这 $50。若拒绝计算机破产输出 Im busted. Congratulations!。原版中的领带夹tie tack分支BASIC 原版在 3970–4080 行poker.bas还有一段卖钻石领带夹的代码随机给 $100 或 $25但因O/3INT(O/3)等整除条件的逻辑缺陷而永远不可达。C# 移植版在 Human.cs 中明确注释了这一决定The original program had some code about selling a tie tack, but due to a fault in the logic the code was unreachable. Ive omitted it in this port.官方记录的已知缺陷Known Bugs71_Poker/README.md 以 Known Bugs 小节明确列出了四个历史缺陷阅读源码后可以逐一印证其成因与影响过度下注导致负余额If you bet more than the computer has, it will still see you, resulting in a negative balance.—— 当人类下注额超过计算机剩余资金时计算机仍会看你跟注导致自身余额变负。在 Table.cs 中可见只要满足Human.Bet 3 * Computer.Strategy.Value且策略不是Raise计算机就会无条件 Ill see you. 并跟注缺少全下all in上限控制。正确做法应像 README 建议的那样让计算机 all in 并把你的下注额缩减到它可匹配的范围或者直接判负——而这正是人类玩家在同样情况下会遭遇的结局。卖表后小额下注仍被判输光If you are low on cash and sell your watch, then make a bet much smaller than the amount you just gained from the watch, it sometimes nonetheless tells you you blew your wad and ends the game.—— 卖表获得资金后若下注额远小于刚得到的金额程序有时仍会误报 Your wad is shot 并结束游戏。这与Human.SetWager()中Balance - Bet - strategy.Value 0的余额检查以及后续RaiseFunds()的触发时序有关Human.cs。买卖手表不产生真实资金转移When the watch is sold (in either direction), the buyer does not actually lose any money.—— 无论是你卖表给计算机还是计算机买回手表对方账户都不会实际扣除对应金额属于凭空印钞。这一点在 Computer.cs 与 Human.cs 的注释中均有确认The original code does not have the computer part with any money。领带夹代码不可达The code in the program about selling your tie tack is unreachable due to a logic bug.—— 即上文所述 BASIC 原版 3970 行起的分支因整除逻辑缺陷永远无法执行C# 移植版已直接省略该功能Human.cs。面向移植者的 Porting NotesREADME 末尾保留了 Porting Notes 小节邀请各语言移植者记录移植中遇到的难点。基于本仓库现有的多语言实现移植这款游戏时建议重点留意以下问题0.5过牌与整数输入的冲突BASIC 的数值输入天然支持小数而多数强类型语言如 C#、Java的整型读取需要特殊处理。C# 在 IReadWriteExtensions.cs 中用float读取后判断bet ! (int)bet且bet .5才视为过牌其它小数一律报 No small change, please.。牌型比较的优先级必须先比牌型等级、同等级再比高牌且不能引入原版不存在的牌型如同花顺否则会破坏与原版一致的对局体验。随机数抖动的复刻计算机下注额 策略基础值 0–9 随机数移植时应保持这一确定性 随机性的混合模式Computer.cs。换牌上限人类玩家最多换 3 张超出必须提示并重新输入Human.cs 与 poker.bas。历史缺陷的处理策略多数移植版选择忠实复现如 C# 保留负余额缺陷并注释说明少数选择省略不可达代码如领带夹建议在移植文档中明确记录你的取舍正如 README 的 Known Bugs 小节所做的那样。如何运行BASIC 原版直接使用 Vintage BASIC 或兼容 BASIC 解释器加载运行 poker.bas。C# 移植版在 71_Poker/csharp 目录下使用dotnet run运行项目文件为 Poker.csproj入口为 Program.cs程序启动时依次输出 Title.txt 标题与 Instructions.txt 规则。JavaScript 移植版直接打开 poker.html 即可在浏览器中游玩。其它语言Python、Java、Ruby、Perl、Lua、Kotlin、VB.NET 等目录下均提供对应实现可查阅各目录 README 获取运行说明。小结Poker 是《Basic Computer Games》中少有的、同时包含双向下注博弈、AI 决策与变卖家产续命机制的策略游戏。通过对比 71_Poker/README.md 与仓库源码我们可以看到C# 移植版用Strategy策略模式精确还原了计算机基于牌型的虚张声势、跟注与加注逻辑用HandRank等级体系忠实保留了原版不识别同花顺的牌型局限同时对四个已知缺陷负余额、卖表误判、买卖不扣款、领带夹不可达做出了明确的注释性处理。无论是想体验 1978 年的经典人机对战还是研究老游戏如何优雅移植到现代语言这份文档与源码都是极佳的参考样本。赞分享示例工程【免费下载链接】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 之 Bullseye飞镖计分概率游戏的规则、策略与多语言移植解析Basic Computer Games 之 Bullseye飞镖计分概率游戏的规则、策略与多语言移植解析 导读 Bullseye靶心是《Basic Co示例工程Basic Computer Games 之 Bagels 猜数字推理游戏规则、策略与多语言移植源码解析Basic Computer Games 之 Bagels 猜数字推理游戏规则、策略与多语言移植源码解析 导读 Bagels贝果谜题是经典《Basic C示例工程Basic Computer Games 之 Hi-Lo猜数赌金的规则、BASIC 源码与多语言移植实现解析Basic Computer Games 之 Hi Lo猜数赌金的规则、BASIC 源码与多语言移植实现解析 导读 Hi Lo 是经典《Basic Compu示例工程上一篇SOES EoE功能深度探索EtherCAT over Ethernet的完整实现方案下一篇Stagehand AI 浏览器自动化实战一个脚本跑通网页数据采集全流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表