我正在用Ruby编写一个小程序来解析扑克网站的手历史日志。 日志分为几行,看起来有点像这样:
Table 123456 NL Hold'em $1/$2
5 Players
Seat 3 is the button
Seat 1: randomGuy112 $152.56
Seat 2: randomGirl99 $200
Seat 3: PokerPro $357.12
Seat 4: FishCake556 $57.19
Seat 6: MooMoo $188.98
Dealt to MooMoo [Ah, Ks]
randomGuy112 folds
randomGirl99 raises to $7
etc.. etc..
我想在一个对象中总结这些信息,然后可能会,例如, 以不同方式呈现它或将其保存到数据库。 当我最初想到这个问题时,我想我只有一个具有许多正则表达式和几个if / else语句的反向直接类。然后我意识到这可能变成一个非常大的方法,可能是调试/维护的噩梦。请记住,它需要在游戏的每个阶段(翻牌前,翻牌等)循环以收集玩家的行为。
我也想用TDD方法解决这个问题,但是“一长方法”的方式意味着检查以后输入的测试将依赖于早期的测试。
我对Ruby很陌生,还没有点击'Ruby方式'来做事。我正在写自己编写C#代码 用不同的语言。
你能否给我一些关于如何设计解析器的指示,以便它不是if / else语句的一大堆,而且更可测试?
答案 0 :(得分:2)
看起来你正处于ad hoc字符串匹配和RE的优势之间的边界,以及需要实际解析器的内容。
手写解析器没有任何问题,只要你保持你的方法简短,在任何给定的方法中没有很多复杂性,就可以在解析器需要的时候总共有if
个语句。
我不确定10行具有难以理解的正则表达式是否优于30行漂亮的代码。
现在,Ruby确实拥有一个先进的PEG解析器生成器。我认为在这种情况下,我不会担心这是否过度,我只会go ahead and use Treetop.
答案 1 :(得分:1)
您可以查看此open source poker game hand parser
看起来他们创建了正则表达式的哈希,然后他们可能迭代正则表达式数据结构。它是一个比解析器更简单的机器,可能是一个更轻量级的方法。
答案 2 :(得分:1)
在扑克牌的任何一点上,都有明确定义的下一组动作。我认为你可以将它们封装成state machine。有几个,其中(没有建议,我担心 - 没有足够的经验)
答案 3 :(得分:1)
我为PokerStars日志文件https://github.com/malikbakt/pokerstars
编写了手历史解析器答案 4 :(得分:0)
您可能需要查看:StringScanner。
答案 5 :(得分:0)
我有两个不同的指针,它们将指向解决方案,如何以红宝石方式编写代码。
答案 6 :(得分:0)
我推荐Martin Fowler出版的 Refactoring 一书(以死树和电子格式提供,IIRC)。他涵盖面向对象的补救措施,以确切地解决您所询问的设计问题,所有这些都在测试驱动的环境中进行。这是专业人士应该阅读的那本书之一。