views:

385

answers:

6

I'm writing a small program in Ruby to parse a hand history log from a poker site. The log is split over several lines and looks a bit like this:

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..

I want to summarise this information in an object which then might, for example, render it differently or save it to database. When I originally thought of this problem I thought I'd just have one realativly straight forward class with a number of regexes and several if/else statements. I then realised this could turn into quite a large method and potentially be a nightmare to debug/maintain. Keep in mind it needs to loop at each stage of the game (preflop,flop etc) to collect player's actions.

I also want to tackle this with a TDD approach, but the 'one long method' way means that the tests for with checking later input will kind of rely on earlier tests.

I'm quite new to Ruby and havn't yet clicked on the 'Ruby way' to do things. I'm catching myself writing C# code in a different language.

Can you give me some pointers on how to design the parser so it isn't one huge mess of if/else statements and more testable?

A: 

You may want to look at: StringScanner.

rkj
+1  A: 

You can checkout this open source poker game hand parser

It looks like they created a hash of regular expressions and then they probably iterate over the regex data structures. It is a more simple machine than a parser and probably a more light weight approach.

jrhicks
+2  A: 

Use Treetop

It does look like you are on the borderline between what ad hoc string matching and RE's are good for, and what requires an actual parser.

There is nothing wrong with handwritten parsers, and as long as you keep your methods short, without a lot of complexity in any given one, it's OK to have as many if statements in total as the parser requires.

I'm not sure 10 lines with incomprehensible regular expressions is any better than 30 lines of nice looking code.

Now, Ruby does have an advanced PEG parser generator. I think in this case I wouldn't worry about whether it was overkill, I would just go ahead and use Treetop.

DigitalRoss
+1  A: 

State Machine, anyone?

At any point in the play of a poker hand there is a clearly-defined set of possible next actions. I'd think you could encapsulate them into a state machine. There are a few around, amongst which (no recommendations, I'm afraid - not enough experience with any) are

Mike Woodhouse
For an assignment a few months ago, I found that a state machine for poker is very straight-forward. Here it seems there is only texas Hold-em so that makes it even more easy.
NomeN
A: 

I have two different pointers for you, which will point you to the solution, on how to write code in the ruby way.

  • Get a ruby book. The ruby book will have a lot of examples on how to write code in the ruby way. From my personal expirience I can recommend you the pixake(is this spelled right?) book: http://www.ruby-doc.org/docs/ProgrammingRuby/html/index.html
  • Read existing ruby code. You seem to know enough ruby to write code? Then you should certainly be able to read existing code. I assume you already have installed ruby on your system. If so, you will find plenty of sourcecode on your harddrive. If not just use the internet.
johannes
A: 

I'd recommend the book Refactoring by Martin Fowler (available in both dead-tree and electronic formats, IIRC). He covers object-oriented remedies for exactly the design problems you're asking about, all in a test-driven context. This is one of those books that everyone in the profession should read.

bradheintz