The Poker Copilot Blog

Tracking the development of Poker Copilot, Mac OS X software for poker analysis and statistics.

Saturday, 31 May 2008

Poker Stats: Auto-detecting Full Tilt Poker Hand History

Here's a gory report of some technical internals of my app. If Java or concurrent programming bores you, avert your eyes.

Yesterday I completed the mechanism to detect the user's Full Tilt Poker hand history. I'm pleased with the result. It gave me a chance to give the java.util.concurrency API a good work out. I have the interesting challenge of keeping the GUI responsive while performing some processor intensive parsing. I got to write a simple implementation of Google's MapReduce algorithm too.

Here's what happens: my Poker stats app scans for hand history files in the ~/Documents/HandHistory folder, which is where Full Tilt Poker writes its hand history, unless instructed otherwise. This folder can be changed in the preferences.

A background thread is launched to monitor this folder. Any file that has either not been parsed yet, or has changed in file size since last parsed is added to a list of files to be parsed. This process is repeated every 10 seconds. To be precise, it is repeated 10 seconds after the end of the previous scan. Through careful monitoring I've proven that this regular scanning causes no discernible ongoing load on the system.

The list of files needing scanning is then sent to the parser. I've used every trick I know to make the parser fast. On my dual core 2.4 Ghz Mac Book Pro, it currently rips through the hand history files at the rate of about 2500 hands per second, although it sometimes peaks at 4000 hands per second. On a multi-CPU or multi-core processor, my MapReduce implementation creates multiple parsing threads, so this rate could feasibly be much higher. I'll have to find a way to test this on a machine with more than 2 cores.

As soon as all the hands in a file are parsed, the GUI is notified to update, via the Observer pattern. Newest files are parsed first, so that upon start-up the most recent statistics appear immediately, whereas the older stats may take a few seconds to appear.

Friday, 30 May 2008

Poker Stats: What's in a Name?

I watched a video recently of Tim Ferriss giving a presentation to Google London. Tim Ferriss is the author of "The 4-Hour Workweek", a title I think is poxy. It turns out he does too. In this video he revealed how he came up with the name.

His original title was "Dealing Drugs for Fun and Profit". His publisher said that such a Wal-Mart unfriendly title would be terrible for his sales and he needed a new name. So he came up with about 10 different titles. For each he registered the domain and set up a simple "coming soon" page. He then spent about $150 in total on Google Adwords campaigns to see which attracted the most clicks. Apparently "The 4-Hour Workweek" was an order of magnitude more popular than any other candidate.

Oh, and Tim has made a massive heap of money, I guess, from this book.

I'm taking the same approach for my Poker Stats app. I'm gathering 10 candidate names of which, thanks to help from Scott Kane and Rob Meredith, I already have 5. Then I'll let the market speak, courtesy of Google Adwords.

I'm still keen to hear suggestions for names, especially if the domain for the name is available.

Poker Stats: Banished the Calculating Bugs

I played about 100 hands of poker yesterday, carefully tracking the results of each hand manually. Comparing to the results of my app, I discovered my calculation problems. They were due to the subtle differences between "raising $1" and "raising to $1". The linguistic difference is subtle, the mathemathical difference any but.

Thursday, 29 May 2008

Poker Stats: Side-by-Side Screenshot

Here's a screenshot showing how you can use my as-yet-unamed Poker Stats app to monitor your play with Full Tilt Poker in real-time. After I complete each hand, within a few seconds the chart and stats are updated. Click for larger image.


The screenshot also shows a bug that I'll have to track down: why the big dip towards the end of the graph? My guess is that in certain hands the calculations are getting confused.

Wednesday, 28 May 2008

Poker App: Finished the parser

I knuckled down today and completed the parser for Full Tilt Poker hand history. This is the second parser I wrote, the first being for Party Poker, another online poker site. The second one was definitely much easier to write than the first one, because for the first one I had to relearn how to write a parser, something I hadn't needed to do since my university days. It's more than 15 years since I finished university, which is adequate time to forget most everything I learnt.

Now I've got the less enjoyable part to do: manually reading through various hand history files, calculating with pen and paper the expected results, which I can then compare to the results my Poker statistics app gives. After all, I don't want my app to be telling people they are poker gods, if they are only poker mortals.

I spent a little time on the name dilemma. Damn, it's hard finding a pithy but appropriate name whose domain is free.

Tuesday, 27 May 2008

Poker App: Some Progress

I finally got around to importing my project source into Subversion source control. I know, I know, I should have done it long ago. :-)

I added a red dot to the end of the Sparkline, to make it clearer that the number beside the Sparkline is the value of the last data point. If this means nothing to you, be patient, I intend to explain what Sparklines are, why I'm using them, and I how I implemented them in Java sometime soon.

I got cracking with a hand history parser for Full Tilt Poker. I needed to test against a wide range of hand history files, which meant I had to play for a while. Nice when I can play online poker and consider it work. If all goes well tomorrow, I should have the parser finished.

I experimented with building a DMG file, which is how OS X apps are typically distributed. It was a bit cumbersome, I'm definitely going to have to create a one-step process to build the distributables.

If anyone reading this plays Full Tilt Poker on the Mac, and would like to help me out by trying out the DMG file and running the app on your own system, let me know. It would be good to know if I've accidentally included any dependencies on my own environment.

Making Dialogs in Java Close When Escape is Pressed

In Windows and in OS X, if you press the escape key, dialogs close. It is equivalent to clicking on Cancel.

By default JDialogs in Java do not have this behaviour. If you want to add it to your JDialogs, you can use this subclass of JDialog. Instead of extending JDialog, extend EscapeKeyAwareDialog instead:

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.*;

public class EscapeKeyAwareDialog extends JDialog {

public EscapeKeyAwareDialog() throws HeadlessException {
super();
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Dialog owner) throws HeadlessException {
super(owner);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Dialog owner, boolean modal) throws HeadlessException {
super(owner, modal);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Dialog owner, String title) throws HeadlessException {
super(owner, title);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Dialog owner, String title, boolean modal) throws HeadlessException {
super(owner, title, modal);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Dialog owner, String title, boolean modal, GraphicsConfiguration gc) throws HeadlessException {
super(owner, title, modal, gc);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Frame owner) throws HeadlessException {
super(owner);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Frame owner, boolean modal) throws HeadlessException {
super(owner, modal);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Frame owner, String title, boolean modal) throws HeadlessException {
super(owner, title, modal);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(Frame owner, String title, boolean modal, GraphicsConfiguration gc) {
super(owner, title, modal, gc);
addCloseOnEscape(this);
}

public EscapeKeyAwareDialog(java.awt.Frame owner, String title) throws java.awt.HeadlessException {
super(owner, title);
addCloseOnEscape(this);
}

private void addCloseOnEscape(final JDialog dialog) {
ActionListener cancelListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
};

KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
JRootPane rootPane = dialog.getRootPane();
rootPane.registerKeyboardAction(cancelListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
}
}

How can I Format Java Code with Blogger?

Does anyone know of a good tool that will help me with this?

When I paste Java code into this blog, I'd love for it to be nicely formattly with syntax highlighting and indenting. Unfortunately simply copying and pasting into the Compose window eats my indenting. And I really don't want to have to do all the formatting manually in the "Edit HTML" window.

Any suggestions?

Poker Stats: Getting the Mac Feel Right

I can always tell when a Mac app is a quick port from Windows done by people who haven't taken the time to grok the OS X environment. Things just aren't quite right. For example, in OS X, the keystroke Command+, always brings up Preferences. Additionally they are always available from a standard location on the menu bar. Always? Did I say always? I meant always except for those who just dump a Windows app onto the Mac with the bare minimum work required to get in running.

I'm trying very hard to get the Mac feel right. I'm grateful to Apple for providing ample quality documentation in this area. For example, the Apple guidelines specify the preferred size and location of new windows. Horizontally centred, vertically with a gap between the top of the window and the screen equal to half the gap below the window.

I've created a helper method in my SwingUtils class to take care of locating new windows for me. Here's the source:

/**
* Aligns the position of an object (dialog, window, frame) so that it is located
* according to the Apple UI guidelines.
*
* @param window object to locate
*/
public static void alignObject(final Window window) {
final Dimension size = window.getSize();
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int x = ((int) screenSize.getWidth() - (int) size.getWidth()) / 2;
int y = ((int) screenSize.getHeight() - (int) size.getHeight()) / 3;
window.setLocation(new Point(x, y));
}

Poker Stats: More Decisions Made

There are many online poker apps, all of which have their own way of writing hand history files. These hand history files are the input for my app.

I've been playing Party Poker exclusively until a few days ago, and my app currently only parses hand history files from Party Poker. However Party Poker creates two problems for me. First, the Mac version doesn't write hand history files, and I've decided only to release a Mac version initially. Secondly, the hand history files it writes are messy and interlaced with chat messages, causing some parsing reliability problems.

Over the last couple of days I've been trying Full Tilt Poker. This has a good Mac version, writes hand history files on Macs, and the hand history files are better structured. A friend told me that it has much more users than Party Poker too, although I've been unable to verify this.

So the decision: the first version will only support Full Tilt Poker hand history files.

Poker Stats: The Accidental Genesis of my Poker Stats App

It is a bit of an accident that I am developing an app I can feasibly sell. Here's the story.

A few weeks ago I read Apple's "Java Development Guide for Mac OS X". It gives good information on how to make Java apps "feel right" on Macs. Being a Java programmer and since late last year a Mac owner, I was interested to write a quick test app to try the advice from the article.

I soon had a Mac app that integrated well with the OS X environment. Preferences and the About dialog were in the right place. In Finder the app looked and behaved just like any other Mac app. The only problem was, it didn't actually do anything.

About a week later I restumbled upon Edward Tufte's Sparklines, an excellent way to show certain types of data. As I had some time on my hands and the weather had turned a bit nasty, I wrote a Java implementation of Sparklines, which I then plugged into that empty Java app I had written. I was pleased with the result, but I wasn't graphing any real data. While out walking (despite the cold) I asked myself, what data do I have that I could meaningfully graph to properly test out my Sparkline code?

Lately I've been getting into online poker. The online poker software I've been using writes a history of all my hands to the local hard drive. This seemed the perfect thing to graph with sparklines.

I put the three together -the empty Java app, the poker data, and the sparklines. I mentioned what I had done to a couple of friends who also play online poker. I was surprised by their high level of interest in what I done. It turns out they had been discussing how one might go about parsing the hand history. Before I knew it they were suggesting features for me to add - live update of graphs while playing, showing win/loss not in terms of dollars but in terms of "big bets" to get a better reflection of what was going on, showing the most successful combination of cards one has played.

I did these things they suggested and suddenly found I had an app that was useful to me. I started using it to monitor my own progress at poker. Naturally, as soon as I reached that phase I discovered things could be better and features that should be added. Oh, and things that didn't work properly and needed fixing.

As of a couple of days ago, this project has morphed from a personal toy to try out some new stuff, into something I aim to have available for purchase on the web by the end of June.

Monday, 26 May 2008

Poker Stats: Mac, Windows, or both?

My Poker Stats app is written in Java. I've successfully built and run both Mac and Windows versions. However I want to keep the launch by the end of June as simple as possible. I don't have the resources to thoroughly test against two different operating systems. So which will it be?

My primary computer is a Mac. As I am "eating my own dog food" (using my own product) already, I figure it is wiser to launch with a Mac-only version. The only thing that could change my mind is an avalanche of feedback requesting the Windows version already.

And now a screenshot

I mentioned that I've already been working on this app for some weeks. Here's a screenshot of my progress to date. It shows the approach I am taking with the GUI:

The App is called...

...actually I don't know. The first 10 or so options I came up with are not available as domain names.

The product keeps track of your progress with online poker. It tables statistics and makes graphs showing how fast you are losing (or rarely, winning) money and how well you are playing according to a bunch of metrics. It helps you find weaknesses in your playing style.

So the name would ideally be poker[something], where the domain poker[something].com is available, and is an appropriate word.

Amusing sign-up policy

I just signed up as a user on Java Ranch, and encountered a gem of a "Rules, Policies, and Disclaimers" screen:



Not bad.

30 Days to Launch a New Software Application

Patrick McKenzie suggested forming a peer group of people interested in launching a new app by the end of June. I'm dead keen to join in. This site is for tracking my progress.

I'm cheating a bit, because contrary to Patrick's idea of starting on June 1st, I've already been working for 3 weeks.

 

Poker Copilot

Free 30 Day Trial

Only $69

Order risk free with our 30-day money back guarantee.

  • Poker software for Mac OS X
  • Supports Full Tilt Poker and PokerStars
  • Analyses your opponents while you play
  • On-table HUD for Mac
  • Easy to use, easy to understand

Watch a demo of the major features of Poker Copilot