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.
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
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]
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 Translation Project
About This Blog
This blog tracks the ongoing development of Poker Copilot. Who would find this blog interesting? People interested in 1-person software development, in Poker, or in both.
Contact me via email at steve at pokercopilot dot com.
Blog Archive
-
►
2012
(31)
-
►
January
(29)
- Coming in the Next Update: Ignore Old Hand History...
- Coming in the Next Update: Poker Copilot can forma...
- From the "It's About Time, Too" Department
- Poker Copilot Business Cards
- Playing on Entraction Network?
- Unofficial Update for Ongame Players
- One Person with Two Accounts Playing on Ongame?
- Small Tweaks in Poker Copilot Preferences
- Ongame Network and Poker Copilot
- Buy Poker Copilot via Bank Transfer
- Improvement to Appearance of HUD Popup
- Improvement for Poker Copilot Translators
- Coming in the Next Update: HUD Layout has an extra...
- Unofficial Poker Copilot Update for Ongame Network...
- Poker Copilot Demo Video in French
- Reason I Like My Mac #17,823
- Updated Poker Copilot Demo Video
- Poker Copilot 3 Coming...
- News for Poker Copilot Translators
- Updated Poker Copilot Translations
- New Poker Copilot Screenshots Reveal How Version 2...
- Poker Copilot Translation Project: Update
- PokerStars now has built-in Auto-Hotkeys
- Reflection on the PokerStars Update that Broke Pok...
- Poker Copilot 2.101 Now Available
- Poker Copilot Website in French
- Spanish Website Translation
- Poker Copilot Website in Spanish
- Update for PokerStars Denmark Users (PokerStarsDK)...
-
►
January
(29)
-
►
2011
(154)
-
►
December
(10)
- New Unofficial Update
- Poker Copilot Discussion Forum in French
- Coming in the next update: multiple HUD layouts
- Poker Copilot Fact of the Day
- Unofficial Poker Copilot Update for the Brave
- Coming in the next update: All-in Equity in $ or B...
- Who uses BarrierePoker.fr?
- Coming in the next update: Filter tournaments by t...
- Help Wanted: BlazingStars or AHK for Merge Network...
- Coming in the next update: choose a language for P...
-
►
November
(13)
- MacKeeper's "Real-time protection" breaks Poker Co...
- PokerStars Playing History Audit CSV Problems with...
- Poker Copilot 2.99 Now Available
- HUD not working on PokerStars in update 2.98?
- PartyPoker support in Poker Copilot
- End of a Troublesome Week
- Poker Copilot 2.97 Problem Fixed?
- Desperately Seeking Help to Solve the Crashing Pro...
- Is Poker Copilot 2.97 Crashing For You?
-
►
December
(10)
-
▼
2008
(184)
-
▼
May
(16)
- Poker Stats: Auto-detecting Full Tilt Poker Hand H...
- Poker Stats: What's in a Name?
- Poker Stats: Banished the Calculating Bugs
- Poker Stats: Side-by-Side Screenshot
- Poker App: Finished the parser
- Poker App: Some Progress
- Making Dialogs in Java Close When Escape is Presse...
- How can I Format Java Code with Blogger?
- Poker Stats: Getting the Mac Feel Right
- Poker Stats: More Decisions Made
- Poker Stats: The Accidental Genesis of my Poker St...
- Poker Stats: Mac, Windows, or both?
- And now a screenshot
- The App is called...
- Amusing sign-up policy
- 30 Days to Launch a New Software Application
-
▼
May
(16)

