Articles
04-January-2009 07:01 AM
Several months ago, several Coding the Wheel readers got an email from PokerStars.
We at PokerStars have noticed that recently you have tried out a program called "XPokerBot" by "Coding The Wheel". We would like you to know that among this program's features are automated robot playing that makes it against the rules of Poker Stars.
It's not the first time the PokerStars secret police have condemned a piece of software, nor will it be the last. The PokerStars Prohibited Software blacklist currently calls out some fifty (50) prohibited applications, of which nine (9) are prohibited while the PokerStars client is running, and forty-one (41) are prohibited at all times.

Let's be clear: according to the above document, you're not allowed to run prohibited software even if you shut PokerStars down first. Whether PokerStars is actually running doesn't matter! Once you install the PokerStars software, your machine, at least partially, belongs to PokerStars.
Continue reading >> 
01-January-2009 16:01 PM
Well, I'm back.

Hope you've all had a happy, safe, not-too-exhausting holiday season. I've been MIA for three months, here on Coding the Wheel, and for that I apologize. I haven't been abducted by PokerStars or clobbered by goons from the 2+2 forum, contrary to what you may have read in the comments. In fact, I briefly tried to go to work for PokerStars, on a lark; but for some reason, I never got a response—go figure. I'll tell that story, and say a few words about the recent harassment letter PokerStars sent to Coding the Wheel readers, in the next installment.
Continue reading >> 
20-October-2008 13:10 PM
This is your HTML markup:

This is your HTML markup on drugs ASP.NET:
Continue reading >> 
13-October-2008 23:10 PM
If I could take ten software development books to a desert island, The Elements of Style by William Strunk and E.B. White would be one of them.

Of course, "Strunk and White," as the book is commonly called, has nothing to do with software (it was written in 1935) and everything to do with writing: grammar, composition, and style for users of the English language. But in its 100 short pages this book has more to say about the craft of software than many books you'll find in the "Computing" section of your local bookstore. All you have to do is replace a few key words throughout the text and presto! Pearls of software development wisdom, delivered in near-perfect English.
Like this one, which discusses the importance of proper software design.
Continue reading >> 
03-October-2008 13:10 PM
Introduction
When I was nine years old, my uncle (who once caught a seven-foot hammerhead shark off a crowded Padre Island beach) taught me how to gut and clean a fish. It was a visual, hands-on introduction to the idea, pervasive in software development, that implementation details are messy. These days, I can hardly hear the word encapsulation without thinking about that fish. Anyone who's ever taken a biology class knows that one of the ways we learn how things (such as frogs) work is by dissecting them. Indeed, to analyze something is to take it apart; that's the root meaning of the word.
Anyway, today we're going to talk about how to gut (analyze) a different sort of fish.

I put the picture together in Photoshop, as a lark. Those of you who've read Exploiting Online Games: Cheating Massively Distributed Systems will recognize the four exploit vectors for modern client/server software: above, beneath, inside, and way outside. If you've been following the poker botting series, you've already played with some (basic, but hopefully illustrative) code that achieves a minor exploit along one vector or another. And of course, we use the word "exploit" but what we really mean is a reaffirmation of your basic electronic rights.
Continue reading >> 
03-October-2008 09:10 AM
People, for better or worse, have always been a little touchy about unique identifiers. Social security numbers. Barcodes. RFID. GUIDs. In this day and age of massive registration databases, of drive-by identity theft, a number can be a very powerful thing.

You may remember the sound and fury over the Pentium III processor's embedded serial number, a feature which could have been used (potentially) to track a user's computer without the user's knowledge or consent. This was back in 1999—ancient history—but it was taken quite seriously at the time. In the United States, the Federal Trade Commission was asked, repeatedly, to investigate the technology as an unfair and deceptive trade practice. Meanwhile, across the Atlantic, an advisory group to the European Parliament came very close to recommending a complete European ban of the chip.

Intel was and is one of the premiere technology companies in the world. And yet the message was clear, on both sides of the Atlantic: stay the f--k out of our lives. Intel was forced to first disable, and then discontinue entirely, the tracking feature. And you know what? In hindsight, the privacy concerns were probably exaggerated. Computer hardware is and has always been full of unique or semi-unique markers. That's how most licensing and registration software works, after all: by taking a look at a couple pieces of hardware and cobbling together a unique key.
Fast forward, ten years later.
Today I'd like to talk to you about an electronic privacy issue which is a hundred times more serious than the Pentium III, and a hundred times less publicized. This technology, which exists today, and which quite possibly is working its deceptive magic on your computer even as you read this, is exactly what the world was worried about when the Pentium III was introduced. Back then, the privacy concerns were unfounded.
Today, not so much. Read on.
Imagine, if you will, that your computer has been branded with a unique identifier, very similar to the one introduced with the Pentium III. Only this unique identifier isn't associated with a particular piece of hardware; it's associated with your entire machine—the one you're using to read this, and who knows, maybe the one your kid uses. You can change your CPU; doesn't matter. Reformat your hard drive; doesn't matter. The identifier persists.

And this is where it gets scary.
Let's imagine that this "computer barcode" was distributed across the Internet without your knowledge or consent, linked into a massive online database containing some 60,000,000 unique device identifiers, each one representing a personal computer somewhere in the world: yours, mine, your next door neighbor's, your cousin's in Tuscaloosa, your uncle's in Paris. And let's assume that this database was billed as "fraud prevention" technology, but that it was maintained by a private company selling their services—access to this database—for cold, hard cash. With zero oversight. Zero regulation. Zero anything.
Would it bother you?
Because, ladies and gentlemen, this technology already exists.
Exactly as described above.
And it's far more common than you think.
And if you're reading this article, there's a better than average chance that you've already been infected with it (and "infected," believe me, is the word).
Welcome to the wonderful world of ieSnare.
Sporting a name that smacks of destructive Internet script kiddie hubris, and backed by the resources of a dedicated company by the name of iovation, ieSnare is quietly one of the nastiest, most underhanded pieces of spyware/malware this author has encountered, in a long history of spyware-induced pain and anguish. It is quite simply a worldwide, online, profit-driven computer blacklist capable of uniquely identifying your machine (once submitted to the database) whenever you visit any site, or use any product, protected by the ieSnare system. In iovation's own words:
iovation ReputationManager utilizes proprietary methods to uniquely identify devices connected to the Internet, creating unique identification for them that remain constant across all subscribing online businesses. For example, a PC device connecting to one online gaming or e-commerce site protected by iovation ReputationManager is assigned a device identifier by the same method used to identify PCs connecting to other e-commerce sites/networks protected by the system.
Hello, Big Brother.
Tellingly, there is no publically available listing of companies who employ ieSnare technology although you can find various mentions and references on Google. I found out about ieSnare because I noticed that the Full Tilt, Ultimate Bet, and Bodog online poker clients were opening a curious file on my local hard drive:

STM.SOL is what's known as a Flash local shared object—which is basically a Flash "cookie". And unless you're a web developer, I'll bet you had no idea that there was even such a thing as a Flash cookie, or that Flash cookies are immune to typical "delete cookie" commands in your web browser. What's more, ieSnare sneaks under the radar of most antispy software because Flash cookies are either ignored, or viewed as low-risk items.
Like most successful spyware, ieSnare capitalizes on user ignorance. Whether or not ieSnare is an acceptable way to prevent fraud and/or increase operational efficiency is a discussion we can have once companies stop trying to slip this technology in through the electronic back door.
And by the way: guess who provides at least some of the funding for iovation?
Anybody?
The selfsame company which brought you the Pentium III and the unique identifier that caused such a stir ten years ago: Intel.

What a coincidence. No matter how things change, it would seem, the more they stay the same. 
25-September-2008 16:09 PM
Computer scientists have been doing their thing for over half a century now. (We don't know always know what that thing is, but whatever it is, they've been doing it.) And in that time, computers and software have come a long way. We've got the Internet, we've got artificial intelligence, we've got silky-smooth 3D graphics, we've even got Twitter.
Good job, programmers.
But now it's time for a reckoning, an Old West-style shootout. This article asks the question: what are the 10 most amazing pieces of software in the world today? In order to answer that question, we've used an ultra-rigorous benchmarking method: awesomeness. So without further ado, and in no particular order, the Top 10 Most Amazing Pieces of Software in the World.
#10: Google Maps
You've used Google Maps to get directions to your brother-in-law's house. But we think using Google Maps to get directions between point A and point B is like using the Imperial Death Star to make a pot of hot coffee. It's capable of so much more.

Think of it as an intricately detailed, zoomable photograph of every square inch of the Earth's surface*, complete with layers of information that can be transposed on that surface, presented in such a way that any person in the world can manipulate that surface interactively, including you. A sort of 2-dimensional electronic globe for the ages. And it's 100% free. And it's online. And it loads in about two seconds. And it lets you filter out whatever kinds of information you're not interested in. And did we mention it's free, for crying out loud?
And Google Maps can be used for anything.
No, we mean for any damn thing. You could, if you were so motivated, create a map pinpointing every geographic location from the T.V. series, Lost.

Now, not every use of Google Maps software has always been for the greater good...

...but all things considered, on a scale of coolness, with 0 being this guy:

And 10 being this guy:

Google Maps scores an 11, for being one of the most stunningly kick-ass pieces of software in the history of extreme software, built by a bunch of BAMFs up at the Google HQ, which by the way is located at 1600 Amphitheatre Parkway, Mountain View, California 94043, thank you very much.

Hello Google. Your shit amazes and scares us all.
#9 Microsoft WorldWide Telescope
Okay, we have to say, this is the only piece of software which has ever given us the FREAKING weird feeling of falling upward.
Feet first.

In outer space, of course, there is no upward, or downward, or any-ward, and after using this software for a few minutes you'll be counting yourself lucky to have been born on a habitable planet with gravity and a proper sense of up and down, not some zero-G cosmic maternity ward in which everything just...explodes. Stars and planets, doing weird things with gravity, collapsing in on themselves, having domestic disputes, and comporting themselves like, well...
Like assholes.

This software is the closest any of us will get to interstellar space travel in this lifetime. It doesn't just show you pictures of the universe taken from various telescopes and observatories. That would be pretty cool, but no. The WorldWide Telescope allows you to fly, at speeds well in excess of the speed of light, through a virtual 3D map of the galaxy, thereby allowing you to arrive at your destination before you leave...or something.

(Relativity is strange stuff.)
Best of all: this software is 100% free. A free virtual map of the galaxy, are you kidding? We have no choice but to give it the "One of the Most Kickass Software Programs of All Time" distinction award. Download it. Make your kids use it. Then kick them off the computer and use it yourself.
#8 Google Streets
Google, Inc. is like the kid in science class, you know the one we mean. Teacher asks a question, his hand goes up like a rocket. Teacher asks for a two-page report on the animal kingdom, kid gives him a genetic breakdown of the West African horn frog. Teacher gives a test on differential equations, kid aces it, screws up the grading curve for everybody else, and leaves early.
Yep.
Google is one curve-breaking little bastard of an alien child, who spends all his time doing weird, genius-type things like charting the position of his home planet in your solarium, somehow.
No seriously. He's a weird fucking kid. As if zoomable satellite imagery and street overlays for every square inch of the planet weren't enough. (Google already gives us, absolutely free of charge, the kind of layered overhead maps that ten or fifteen years ago would've had four-star generals drooling like a lechers at a porn convention.) But recently they had to go one better and show us pictures of what it looks like when we're actually in the street.
Uh, everywhere, basically.
This is quite possibly the most virtuoso exposition of software development technique I've ever wi-

Ah shit! That's my fucking house! Fuck!
Really?
With ZOOM??

We don't know whether to laugh or to cry.
And it makes us wonder: what's next?

Fuck you, Google. You little alien bastard child. Nobody loves you.
(Just kidding. We love you. We're just a little scared of you.)
#7 Microsoft Photosynth
You know those cool stereoscopic 3D photographs that let you rotate and zoom your way through a scene? We always thought you needed special cameras and assorted alienware hardware to put those together, and, until recently, you did.
Enter Photosynth, a project from Microsoft Live Labs, which allows anybody with a digital camera to take a bunch of pictures of a cool scene...

...and assemble them into an interactive, stereoscopic, 3-dimensional picture collage...

...using a normal digital camera.
When I say "interactive" I mean interactive. As you drag your mouse across the field of view, different areas are highlighted. See the yellow box in the above picture? Click on that, and you zoom into this:

Photosynth pieces together 2-dimensional photographs to create an explorable 3-dimensional scene, and it does it inside your web browser, and it does it for free.
And that's amazing.
Now if only we could get Photosynth to integrate with Flickr...and then take the combined images and attach them to Google Streets...and take a mugshot of every man, woman, and child on the planet...and link that in through a massive law enforcement database...and implant invisible RFID tattoos on every person, place, and thing in the world...then we might have something!
#7 Google Search
The ancient Greeks had the Oracle at Delphi:

Today, we've got Google Search:

We all know what it does: allows millions of people to search, simultaneously, for content across hundreds of millions of indexed sites. It's the de facto gateway to the web, the single most widely-used application in the history of forever, and probably the most insanely stable software contraption ever erected.
And it's all 100% free.
And it's about as difficult to use as one of these:

Countries may rise and fall, forest fires will burn, California may slip into the Pacific; but Google Search is here to stay. We think that the friendly Google search page will still be ready for action long after the sun has enveloped the Earth and extincted humanity.

In a very real sense, Google Search puts the combined wisdom and knowledge of humanity at the fingertips of anyone with a computer and an Internet connection, turning dumbasses into insufferable know-it-alls:

What's almost scary is that this technology is barely a decade old. Come back and see us in another 10 or 20 years, human.
#6 The Modartt Pianoteq
Most musical instrument "synthesizers" today are based on sampling: pre-recording the sounds of a particular instrument in a way that allows those sounds to be stored and played back. So when you strike the middle C of your digital piano, the sound you actually hear is the middle C of a Steinway Grand recorded two years ago and four thousand miles away.

But you know how in the Matrix, our hero discovers that the world is a software simulation inhabited by a) humans and b) various software intelligences with unknown powers?

Well, if you were to enter that world, walk into a concert hall, sit down at the piano, and begin to play, you'd cause, somewhere in the Matrix, a small piece of software to run. That software would be responsible for "simulating" the piano down to the smallest detail: the elasticity of its strings, the resonance of its soundboard, the subtle acoustics of overtones and case noise, all with unprecedented realism and fidelity.
Thing is, this software already exists. In today's world. Right now. On your home personal computer. The technology is called physical acoustic modelling and, in our opinion, the Modartt Pianoteq the most convincing demonstration of that technology yet seen.
But don't take our word for it...let's see what a real (physical) piano sounds like: (Can't hear the audio? Download a short MP3 here.)
Not bad. Now let's see what the Modartt Pianoteq software sounds like: (Can't hear the audio? Download a short MP3 here.)
We'd be willing to wager that 99% of you can't tell the difference. That's right: you, a distinguished professor of musicology at XYZ University, probably can't tell the difference between a physical grand piano, and one of these:

And if you think you can, you have a phenomenal ear. Because ah...okay...we lied. Both of the above recordings were generated with the Modartt Pianoteq.
Got it, Amadeus?
We empathize with those of you who decry software-generated instrumental sounds as a perversion of musical tradition. But what happens when synthesized instruments actually start to sound better—more authentic, more true—than their "authentic" counterparts? What then?
Well, as pianist Hugh Sung explains, good things happen.
Probably nothing will ever replace authentic physical instruments played by authentic human performers. But within a few short years, it will become absolutely impossible to tell them apart just by listening. Pianos, trumpets, or electric, feedback-laden guitars, it doesn't matter: this is the future of sound. So the next time you're considering purchasing a $50,000 grand piano, or a multi-gigabyte, thousand-dollar collection of sampled piano sounds, take a look at the Pianoteq, weighing in at around 15 megabytes (that's tiny) and just a few hundred dollars.
That's not just awesome, that's freaking awesomez. Recognize.
#5 Second Life
Dorothy, fasten your seatbelts, because Kansas? It's going bye-bye.
You've heard of Second Life by now. We hope. You know it's an immensely freaking huge, intricately detailed, 3-dimensional metaverse inside of which you can basically do anything. If you can do it in real life, you can probably do it in Second Life. Or hell. Even if you can't do it in real life, you can probably do it in Second Life.
Design and create your own 3-dimensional environment, be it a haunted house, a medieval castle, an ultramodern office park...and when you're done, invite other players to come visit your little piece of paradise. Here, for example, is Microsoft Island, a virtual Second Life location set up by the software giant:

Second Life doesn't just allow you to create virtual worlds. It allows you to create intricately detailed virtual objects: clothing. Musical instruments. Weapons. Parrots. And unless you're already a die-hard Second Lifer, we promise you: this is all WAY MORE INTRICATE THAN YOU THINK. Here's the crafting of an actual Second Life guitar created for a Suzanne Vega appearance.
And when it comes to avatars (that is, your digital representation in this world, your "character" if you will)...don't even get us started.

Second Life blurs the lines between reality and cyberspace in a way that no other online multiplayer "game" has done, not even World of Warcraft with its 11-million-plus subscriber base. Second Life is the closest thing we have to a fully-immersive virtual reality world. That's why Microsoft, Toyota, other major companies by the dozen have opened up shop in Second Life. That's why the Second Life economy has a real-world dollar basis. That's why Second Life is so much more than just another MMORPG where people with too much time on their hands can nerd out of control.
Second Life is real.
But if you ask us, the really cool thing about Second Life is the real estate.

That's an intricately detailed map of the Second Life "continent", made available at slurl and powered by, you guessed it, Google-freaking-Maps!! Let's zoom in on a couple pixels:

If you've never played Second Life: you can have no idea how crazy intricate it is, and growing more and more intricate with every passing day. Ultimately, the whole Second Life movement will probably result in the rise of generic A.I. and the subsequent extinction of the human race, somehow...

...but until then, it can be a lot of fun as well as quite profitable. And it's 100% free to get started. Do not under any circumstances start using Second Life if you care about your First Life. Because this is quite possibly the single most addictive substance in the history of addiction.
Consider yourself warned.
#4 NaturalMotion's Euphoria
3D video games are already pretty freaking amazing, but after reviewing NaturalMotion's Euphoria, and after seeing it in action, all we can say is that you ain't seen nothing yet. Say goodbye to the awkward, stick-figure-esque motions of yesterday's video games, and say hello to the future: dynamic motion synthesis.
Dynamic motion synthesis is what happens when you decide: to hell with all this motion-capture and animation-studio BS. Let's just code the human body from the skeleton up. Let's take its muscles, its joints, its nerves, its everything, and encode that as a reusable piece of software. Let's have it understand gravity, tension, weight, elasticity. Yeah. And then let's sell it to people who build 3D games so they can create stuff like this:
So say goodbye to clunky ragdoll physics and say hello to picture-perfect motion, coming soon to every 3D game on the planet, and already present in some obscure titles you've probably never heard of.
Like Grand Theft Auto IV.
#3 The Space Shuttle OS
Okay. Typically when we think of space shuttles, we think of hardware. Booster rockets. Nuts and bolts. O-rings. Flux capacitors.

But what about the software? You know, the programs that control all that hardware?
What are they, chopped liver?
We did some investigating and it turns out that the software which runs the U.S. Space Shuttle is, by some definitions, the most perfect software in the world, at least in the sense of "having the fewest errors". Can't have that manned mission to Mars flubbed because some junior programmer forget to truncate those last two digits. In They Write the Right Stuff, Charles Fischman explains:
But how much work the software does is not what makes it remarkable. What makes it remarkable is how well the software works. This software never crashes. It never needs to be re-booted. This software is bug-free. It is perfect, as perfect as human beings have achieved. Consider these stats : the last three versions of the program -- each 420,000 lines long -- had just one error each. The last 11 versions of this software had a total of 17 errors. Commercial programs of equivalent complexity would have 5,000 errors.
Now you may not know a thing about writing software, but come on. Half a million lines of code driving a violent conglomeration of hundreds of thousands of moving parts built by the lowest bidder, and you can count the number of errors using ten fingers and seven toes?
Respect.
#1 Google Earth
When you crack open Google Earth for the first time and see that familiar blue globe floating in the electronic darkness...

...you'll never be the same again.
If we were world dictator, and it's a good thing that we're not, but if we were: we'd issue a mandate that every man, woman, and child must download and use Google Earth at least once...or else. It is, in our opinion, the single most impressive (at least visually impressive) application in the history of history.
It might even be the single most impressive thing (software or otherwise) in the history of history.
Remember how amazing Google Maps was? Take that and multiply it by 10, then square the result, and multiply that by 74. That's how amazing Google Earth is. Because Google Earth does everything Google Maps does, and much, much more, and it does it in zooming 3D.
Mere screenshots don't really do it justice.
For example: when's the last time you darted into a telephone booth, switched into your Superman costume, and flew, at speeds well in excess of the fastest jetliner, from a location a thousand feet above New York City...

...to Paris, France?

Of course, not even Superman had access to Google Earth's layered network of superimpose-able meta-information:

So if you Lex Luthor types out there are thinking: I can use Google Earth to conquer the world, well...yeah. You're probably right.
Thanks again, Google. You little asshole.
(Just kidding. Don't hurt us.)
In Conclusion
That wraps up our list of the top 10 most amazing pieces of software in existence, rated by awesomeness. We hope you'll download and start using every one of these tools and, if you know of a piece of software which deserves to be on this list but isn't, leave us a comment. In fact, leave us a comment anyway! What do you think the most amazing software in the world is and why? 
08-September-2008 15:09 PM
Bringing Down the House by Ben Mezrich is, so far as I know, the only book which has ever succeeded in writing about the game of blackjack in an interesting way.

No offense to blackjack authors/players, but blackjack suffers from the same problem that afflicts poker: it can be a lot of fun to play, but often not much fun to read about playing. As an old blackjack-pro-turned-poker-player once wrote:
Blackjack is a game of pure numbers and rote, algorithmic strategy, and the life of a professional blackjack player (as professional blackjack players will agree) can be an exceedingly dull grind. Why should anybody contend with huge variance relative to a measly 1-2% gain, hostile casino staff, and hours of never-ending boredom? Masochism? For this reason, I believe that inside every casino blackjack player is a poker player, waiting to get out. In poker, the edge is a fat 10%, 15%, 20% by some estimates. In poker, there is no hostile casino staff, only people who are glad you showed up to play. In poker, you can make more money in a year than many people will make in a decade, and you can do this even if you're not a world-class player. Compared to blackjack, the game of poker is like a breath of fresh air.
For this reason, I think Bringing Down the House is a work of real genius. It does the impossible: injects life back into the game of blackjack. Even if the story is a fraud, as a recent article in the Boston Globe questions: who cares. The story is what sells. And this story sold so well that it was turned into a major motion picture: 21.
21 tried to do for blackjack what Rounders did for poker. And okay, it failed. But from this forgettable jumble of poorly written, poorly acted scenes, we can extract one gem. It's the scene in which Kevin Spacey presents our hero with a puzzle:
Suppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, "Do you want to pick door No. 2?" Is it to your advantage to switch your choice?
Welcome to the Monty Hall problem, which is admirably explained in layman's terms here, and demonstrated using Bayesian maths here.
Continue reading >> 
05-September-2008 21:09 PM
Introduction
This page is a listing of publically available poker hand evaluators, for Hold'em and other games, in C, C++, C#, Java, and other programming languages, with brief descriptions, sample usage, and complete source code, along with gratuitous pictures of scantily-clad ninjas. Downloading and building these hand evaluators piecemeal can be a pain in the you-know-what...

...so I've packaged the complete source code for every evaluator into a single, easy-to-build library: XPokerEval.
- Cactus Kev's 5-Card Evaluator
- Cactus Kev's 5-Card Evaluator with Perfect Hash
- Cactus Kev's 5-Card Evaluator with Perfect Hash in C#
- The Pokersource Poker-Eval Evaluator
- The Pokersource Poker-Eval Evaluator for .NET with P/Invoke
- The Pokersource Poker-Eval Java API
- Keith Rule's Pure C# Port of the Pokersource Evaluator
- Steve Brecher's HandEval Evaluator
- Moritz Hammer's DAG Evaluator
- Timmy's Poker Sim Library
- Paul Senzee's 7-Card Evaluator
- The Two Plus Two Evaluator
- Naive Hand Evaluators
If you're a poker hand evaluation guru, some of this will be old hat to you. On the other hand, if you're new to the subject of poker hand evaluation, it might come in handy. Enjoy.
The Pokersource Poker-Eval Evaluator
Description:
The Pokersource poker-eval library is probably the most widely-used poker hand evaluator in the galaxy. It's open-source, it's fast, it's over ten years old, and it can not only analyze your poker hands but make you a cup of coffee, interpolate the doomsday trajectory of near-Earth asteroids, and fix the grease-clot in your kitchen sink.
poker-eval is a C library to evaluate poker hands. The result of the evaluation for a given hand is a number. The general idea is that if the evaluation of your hand is lower than the evaluation of the hand of your opponent, you lose. Many poker variants are supported (draw, holdem, omaha, etc.) and more can be added. poker-eval is designed for speed so that it can be used within poker simulation software using either exhaustive exploration or Monte Carlo.
Poker-eval has a ton of functionality, including support for multiple poker variants (Hold'em, Omaha, Stud 7, etc.), non-standard decks, low and high-low games, enumerations, quarks, leptons, synchronicities, and strange attractors. It can be built on about a dozen different platforms, including Windows, *nix, and the alien mother ship OS first popularized in Independence Day and later legitimized by Jakob Nielsen.
23-August-2008 12:08 PM
Introduction
Today we're going to kill two birds—
- How to inject a .NET assembly (DLL) into a native process?
- How to inject a .NET assembly (DLL) into a managed process?
—with one stone: by using the CLR Hosting API.
But first, let's talk about monsters.
To many .NET developers, the .NET runtime is like the slobbering, snaggle-toothed monster sitting in your barcalounger, that everybody in the household politely ignores because hey. It's a frikkin' monster; don't make eye contact with it.

The monster occasionally grunts at you. It smells like a wet dog. And it clutters up half your living room with its bulk. But you tolerate it, because this is a useful monster. It vamooses those sticky kitchen leftovers; does the laundry; feeds the dog; vacuums the carpet; and makes sure the doors are locked at night. It takes care of you, even if your home doesn't quite feel like your home anymore.
Now, we're accustomed to thinking of Windows applications as being either:
Either our application has a big, smelly, snaggle-toothed monster sitting quietly on the barcalounger, or it doesn't.
Right?
Well, what if I said that the whole managed-vs.-native dichotomy is an illusion that's been pulled around your eyes to blind you to the truth?
Morpheus: The Matrix is everywhere. It is all around us. Even now, in this very room. You can see it when you look out your window or when you turn on your television. You can feel it when you go to work... when you go to church... when you pay your taxes. It is the world that has been pulled over your eyes to blind you from the truth.
Neo: What truth?
Morpheus: That you are a slave, Neo. Like everyone else you were born into bondage. Into a prison that you cannot taste or see or touch. A prison for your mind.
What truth? you ask.
That you are locked in a programmatic worldview designed to turn a human being into one of these:

Okay, scratch that.
Cut.
After having a friend review this article prior to posting, I'm told I'm way out on a limb here.
James bud—you're crazy. The .NET framework is nothing like the Matrix. Stop using the Matrix in your posts. For starters, .NET uses Unicode internally, whereas the Matrix uses [censored].
Ah. Right. The old what-programming-language-do-they-use-in-the-Matrix? debate.
I guess the point I was trying to make is this: there's no fundamental difference between a managed process and a native one on Windows. A managed process is simply a native process in which some special code which we call the ".NET runtime" happens to be running, and in which we have access to a special library known as the ".NET framework".
Now, this ".NET runtime" code is capable of doing some special things, to be sure. For example, it knows how to generate binary executable code on the fly in a process known as just-in-time compilation. It knows how to rig things properly such that "managed-ness" happens correctly, that our managed code runs by the rules we expect it to run by, and so forth.
But applications are not "managed" or "native". They're always native. Sometimes they eruct an infrastructure known as the managed runtime, and we can then start calling them "managed" but they never lose that core nativity. In fact, it's impossible to execute managed code without executing native code! The entire phrase is a misnomer!
There is no such thing as managed executable code. Only managed code which is later converted to executable code.
Like everything else in programming, the managed runtime is an illusion, albeit a useful one.
Loading the .NET Runtime Yourself
So if a managed process is simply a native process in which some special code is running, there must be a way to load the .NET infrastructure into a native, non-.NET process, right?
Right.
Surely this is a complex and messy process, requiring special knowledge of Windows and .NET framework internals?
Maybe, but all the complexity has been placed behind one of these:

I say this because starting the .NET runtime is (pretty much) a one-liner, by design:
HRESULT hr = pointerToTheDotNetRuntimeInterface->Start();
The only trick is getting the target process (the process into which you'd like to inject your managed assembly) to execute this code.
Let's explore.
Step 1: Create the Managed Assembly
So you have some managed code you'd like to run inside the target process. Package this code inside (for example) a typical .NET class library. Here's a simple C# class containing one method:
namespace MyNamespace { public class MyClass { // This method will be called by native code inside the target process... public static int MyMethod(String pwzArgument) { MessageBox.Show("Hello World"); return 0; } } }
This method should take a String and return an int (we'll see why below). This is your managed code entry point—the function that the native code is going to call.
Step 2: Create the Bootstrap DLL
Here's the thing. You don't really "inject" a managed assembly into another process. Instead, you inject a native DLL, and that DLL executes some code which invokes the .NET runtime, and the .NET runtime causes your managed assembly to be loaded.

This makes sense, as the .NET runtime understands what needs to happen in order to load and start executing code in a managed assembly.
So you'll need to create a (simple) C++ DLL containing code similar to the following:
#include "MSCorEE.h" void StartTheDotNetRuntime() { // Bind to the CLR runtime.. ICLRRuntimeHost *pClrHost = NULL; HRESULT hr = CorBindToRuntimeEx( NULL, L"wks", 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (PVOID*)&pClrHost); // Push the big START button shown above hr = pClrHost->Start(); // Okay, the CLR is up and running in this (previously native) process. // Now call a method on our managed C# class library. DWORD dwRet = 0; hr = pClrHost->ExecuteInDefaultAppDomain( L"c:\PathToYourManagedAssembly\MyManagedAssembly.dll", L"MyNamespace.MyClass", L"MyMethod", L"MyParameter", &dwRet); // Optionally stop the CLR runtime (we could also leave it running) hr = pClrHost->Stop(); // Don't forget to clean up. pClrHost->Release(); }
This code makes a few simple calls to the CLR Hosting API in order to bind to and start the .NET runtime inside the target process.
- Call CorBindToRuntimeEx in order to retrieve a pointer to the ICLRRuntimeHost interface.
- Call ICLRRuntimeHost::Start in order to launch the .NET runtime, or attach to the .NET runtime if it's already running.
- Call ICLRRuntimeHost::ExecuteInDefaultAppDomain to load your managed assembly and invoke the specified method—in this case, "MyClass.MyMethod", which we implemented above.
The ExecuteInDefaultAppDomain loads the specified assembly and executes the specified method on the specified class inside that assembly. This method must take a single parameter, of type string, and it must return an int. We defined such a method above, in our C# class.
ExecuteInDefaultAppDomain will work for the majority of applications. But if the target process is itself a .NET application, and if it features multiple application domains, you can use other methods on the ICLRRunTimeHost interface to execute a particular method on a particular domain, to enumerate application domains, and so forth.
The single toughest thing about getting the above code running is dealing with the fact that the CLR Hosting API is exposed, like many core Windows services, via COM, and working with raw COM interfaces isn't everybody's idea of fun.
Step 3: Inject the Bootstrap DLL into the Target Process
The last step is to inject the bootstrap DLL into the target process. Any DLL injection method will suffice, and as this topic is covered thoroughly elsewhere on the Internet and here on Coding the Wheel, I won't rehash it. Just get your bootstrap DLL into the target process by any means necessary.
Conclusion
That's it.
Of course, we've only scratched the surface of the CLR Hosting API and its powers. For a more in-depth description, consult Bart De Smet's CLR Hosting Series. If that's more detail than you need, Damian Mehers has an interesting post describing how he used .NET code injection to tweak Windows Media Center. Last but not least, if you're planning on hosting the CLR in production code, you might want to go all-out and pick up a copy of Customizing the Microsoft .NET Framework Common Language Runtime from Microsoft Press, though this shouldn't be necessary for everyday use.
And for those of you who are following the poker botting series, this technique allows you to have the best of both worlds: you can create AI or controller logic using a managed language like C#, while retaining most of the benefits of having code run inside the poker client process.
Good luck. 
22-August-2008 14:08 PM
Introduction
Thirty hands an hour.
When you're dealing a real-money game of No Limit Texas Hold'em, that's what you're shooting for. Thirty hands an hour, or roughly one hand every two minutes, like clockwork. Two minutes to wash, shuffle, cut the cards, deal them out in two concentric rings. Two minutes to gently coax a table of beer-drinking adults through four rounds of betting, keeping your sanity in the midst of two and three-way all-ins, split pots and side pots, pot bets and string bets, kills, half-kills, straddles, and other inventions of bored-out-of-their-mind poker players.
"Run it twice, dealer."
After a while, it becomes automatic. You get to where you can eyeball a stack of chips and tell it's one chip short of twenty. You get to where you can cut three, five, eight chips from a stack in one clean motion. Your dealing improves, as your hands learn the curt yet unhurried, almost lazy rhythm of high-throughput dealing. Wash, shuffle, shuffle, shuffle, cut, don't forget the deck guard, go. Two months before you were sending cards flying over the table rails in curlicues, now you're tossing them with pinpoint accuracy.
Like shuriken.
The rituals of the poker table are a kind of language, and as a fluent speaker of this language, you don't stop and think about what the individual words mean, or whether the grammar is correct. The words and the meaning they convey are one and the same. To hear the words is to understand them, but at the poker table, your "words" are bets, actions, the casual tossing of two useless cards into the muck, the spill of meaningful color we call the flop, the turn, the river, whatever. Symbols. Grammar. Inflection. Punctuation.
Language.
Think of a Texas Hold'em hand as a seven-letter word built from a 52-card alphabet. Consonants and vowels. In combination, they have meaning. One of your jobs as a poker dealer is to figure out when one person's "word" is better than another person's, and push the pot accordingly. As a poker player, you have to take things a step further. You have to understand the word. Not just its specific meaning, its denotation; but its connotations, associations, nuance, history. And you have to do all of this in the blink of an eye, automatically, without thinking.
It's almost robotic.

Speaking of robots, this is the kind of stuff at which poker robots excel:
- Hand Recognition
- Hand Comparison
- Hand Enumeration
- Hand Evaluation
These terms are often used interchangeably, but I like to give them specific meanings.
- Hand Recognition. Figuring out what a poker hand "is": what hand category it belongs to, the number of outs it has, it's equivalence class, and so forth.
- Hand Comparison. Taking two or more poker hands and determining the winner.
- Hand Enumeration. Enumerating all possibly combinations of cards, whether the cards in a player's hand, or the cards on the board, or both.
- Hand Evaluation. Computing the win/loss percentage or pot equity for two or more hands or hand ranges.
And of course, it goes without saying that robust hand evaluation is the stepping-stone to a mature poker A.I. If your poker bot can't do this...

...it's fighting with one arm tied behind its back.
That, by the way, is a screenshot of Andrew Prock's PokerStove, a poker calculator capable of performing hand vs. hand-range analysis across multiple opponents, using exhaustive exploration or Monte Carlo simulation. There are many such tools out there, but PokerStove is the most popular, and probably the most functional, of the lot. PokerStove is free, so if you haven't already done so, I suggest downloading it and getting familiar with how it works.
Because we're going to teach our poker bots and related tools how to do what PokerStove does.
Subjective All-In Equity (SAIE)
Notice I said hand vs. hand-range analysis. The "range" part is crucial, because in poker, rarely are we able to put our opponents on specific hands. Instead, we assign them a range of hands, and narrow that range as the hand progresses. In order to compute our equity, we have to figure out how well our known hand fares not against another known hand, but against the range of hands we believe our opponent has. This is what's referred to as subjective all-in equity or SAIE.
I like Michael Maurer's definition:
SAIE is a player's pot equity given particular beliefs about the possible hands of the opponent(s) and assuming no further betting.
Provided we follow it with Andrew Prock's note in the PokerStove FAQ:
This is not the chance that a hand will win the pot. Rather it is the fraction of the pot that a hand will win on average over many repeated trials, including split pots. The equity for a hand is calculated by dividing the number of "pots" that the hand won by the number outcomes considered. Because two players can split a pot, a player can win fractional pots. Thus, it is possible for a hand to have non-zero equity despite the fact that it cannot win.
For example, in the above screen shot of PokerStove, we can see that the equity of pocket Jacks versus two opponents is around 36%, if we assign each of those opponents a range of [any pair; any AQ or better]. If you took this situation and played it out a million times, you'd find that on average, you'd win 36% of the pot (assuming no further betting, and assuming nobody folds).
This is a useful number to have.
It takes into account the fact that, if one of your opponent has Aces, and the other has Kings, you're equity is lower—only 15%. It takes into account the fact that, if one opponent has AK (any AK) and the other has AQ (any AQ), your equity is higher—about 44%. SAIE provides a sort of weighted average of how your hand fares against each of the hands in your opponents' range, taking into account the likelihood of each specific opponent holding. You see, it's quite a bit easier for an opponent to have AK (12 combinations) than it is for him to have AA (only 6 combinations). And the mathematics need to allow for that.
Once again: this is not the same thing as your chance of winning the pot! Another example should make this clear.

Here, Player 0's chance of winning the pot is only 11%, but his equity is around 57%. This is because most of the time—whenever a 4 or higher falls on the river—the hand is going to be tied. But when a 3 or 2 falls on the river, Player 0 wins with Four Aces and a Four kicker, which beats Player 1's Four Aces and a Three Kicker.
And although Player 1's pot equity is 44%, he has zero chance of winning the pot outright.
That's a contrived situation, but an illustrative one. By thinking in terms of pot equity, rather than chance of winning the pot, we neatly fold all those messy tie-game situations into our mathematics.
The Need For Speed
Believe it or not, calculating SAIE is easy. Calculating it efficiently may not be.
It all hinges on hand comparison: the ability to compare two or more poker hands and determine the winner. If you can do that, all you have to do is programmatically deal out large numbers of hands and start tallying wins, losses, and ties. When it comes to dealing those hands out programmatically, you have two options:
- Exhaustive Exploration. Enumerate all possible outcomes: all the combinations of cards fitting your opponents' range times all the possibly combinations of board cards. Keep a tally of how many hands each player wins, loses, and draws. Afterwards, when you've enumerated every possibly combination, express these as a percentage.
- Monte Carlo Simulation. Randomly generate hands fitting your opponents' ranges and board cards, keeping a tally of wins, losses, and draws for each player. Over many trials (hands or games), your results will start to converge.
Typically in the game of Hold'em, we use Monte Carlo simulation for preflop matchups, and exhaustive exploration for matchups on the flop or later. You'll notice PokerStove has a radio button allowing you to specify which technique to use although, as Andrew Prock notes:
Monte Carlo simulations work very well for most practical problems, and enumeration driven software is only going to be of interest to the true poker geeks who must have all of their i's dotted and t's crossed. Of course, I'm one of those geeks :)
Whether you're a geek or not, you're going to need throughput: the ability to evaluate large numbers of hands quickly. If you're going to be randomly generating, or consecutively enumerating, millions of hands, you can't afford to do four bubble sorts, nine redundant array copies, a Google search, and send off 3 emails every time you evaluate one of those millions of hands.
You've got to optimize.
(Remember, this is something poker bots and other tools need to do in real time, at multiple tables, on various and sundry hardware.)
So it's got to be fast.
I don't mean 2,000 hands per second fast. That's not fast, that's slow. I mean fast like a bat out of hell. Fast like the wind. Fast like the Flash. Speedy Gonzales. Run Forest Run! fast. Or even—dare I say it—as fast as that paragon of speed and grace, the Roadrunner.

MEEP-MEEP!
And the best part?
This is not a wheel you have to reinvent. Highly-optimized hand evaluation code is already written, and is publically available in multiple languages (C, C++, C#, Java, and Python, among others) with support for multiple poker variants (Hold'em, Omaha, Stud) provided you know where to look.
A Small Army of Poker Hand Evaluators
Some people collect butterflies, leaves, flowers; others collect coins, marbles and shot-glasses.
Me? I collect open-source poker code.
If it's code, and if it's about the game of poker, and if it's freely available, I want a copy. Even if the code is written in a language I'll never use. Even if it's slower, messier, or buggier than my existing code. A lot of clever people have devoted a lot of time and energy to building robust poker hand evaluators, you see, and I want to leverage their hard work.
So every time I stumble across a new specimen, I collect it. I haul it out to the garage, open my toolbox, and start hammering away. I clean up the code, throw it into a Visual Studio project or who knows, I might even crack open my Eclipse IDE and do some Java work. Whatever.
There is no "one size fits all" poker hand evaluator, so I want a hand evaluation library which incorporates multiple evaluators within it, all of them written by other people.
Here are just a few (all of which we'll be covering in detail):
- The Pokersource Poker-Eval library
- The Java enumeration library built on top of Pokersource
- Keith Rule's C# port of the Poker-Eval library
- Cactus Kev's 5-Card Evaluator
- Paul Senzee's Improved 5-Card Evaluator
- Paul Senzee's 7-Card Evaluator
- Moritz Hammer's Directed Acyclic Graph-based 7-Card Evaluator
- Steve Brecher's HandEval routines
- The Two Plus Two 7-Card Evaluator
So instead of thinking of your poker hand evaluator as a single tool, think in terms of building a poker hand evaluation toolset; a collection of code which can be applied to the specific problems you're facing. Even within the relatively narrow context of an online poker bot, there's a lot of wiggle room. Are you building a multi-table online Texas Hold'em poker bot? If so, you need a fast 7-card evaluator. Are you building something which needs to support Hold'em as well as Omaha and 7-Card Stud. You need a good generic evaluator. And so forth.
If you think of poker hand evaluation as a smorgasbord, rather than a single component, you'll be doing yourself a favor.
Conclusion
Now, I know what you're thinking: where's the code? Where are the algorithms?
Well, it turns out that poker hand recognition, comparison, enumeration, and evaluation are such complex topics, it's impossible to fit them all into a single post, and at the same time, provide and explain the source code for a dozen different pre-existing evaluators. So I've broken these off into a set of background articles, to be published shortly:
- Poker Hand Analysis, Part 1: Theory
- Poker Hand Analysis, Part 2: 3rd-Party Evaluators and the XPokerEval library
- Poker Hand Analysis, Part 3: Hand Ranges and Multiple Opponents
Today, I just wanted to introduce the subject, and tell you how you can make some money by writing hand evaluation code.
Coding the Wheel, in conjunction with a site to be named shortly, will be presenting an award of X dollars (we're not quite sure what X will be yet, but it will be hundreds of dollars, rather than thousands or tens) to the person or persons who can produce a substantial improvement to the hand evaluation code we'll be presenting.
In addition, that person's solution will be highlighted, with full credit, or anonymously if preferred, in a dedicated post on Coding the Wheel and possibly some other sites as well.
There are only a few requirements:
- The solution must be unpublished
- The solution must evaluate 7-card poker hands
- The solution must be fast (noticeably faster than current evaluator implementations)
Full rules to follow. Stay tuned! 
18-August-2008 13:08 PM
Well, we can chalk up my month-long hiatus from posting to that blackest of software arts, time estimation. In the understatement of the century, Wikipedia notes:
The ability to accurately estimate the time/cost taken for a project to come in to its successful conclusion is a serious problem for software engineers.
In order to deal with this problem, I've tried everything from function point analysis to tasseography...

...and although this won't be a popular statement, let me tell you what I think: none of it really works.
Not really.
No matter how careful we are, and regardless of what statistical methods we apply, we'll find that software suffers from a sort of Heisenberg Uncertainty principle. It's almost impossible to observe a piece of software or to accurately predict how long it will take it to travel a certain distance on the development timeline. The best we can do is get a ballpark figure, and rely on the fact that our programmers will make a valiant effort to manhandle the project workload into the project schedule.
The problem here is one of loose wiring, a term I first came across reading Caro's Book of Poker Tells .
You see, your poker opponents are volatile beings. They can be impressionable, irritable, playful, capricious, and more. You don't know when they're going to short out, cross-circuit, or doing the silliest or the most brilliant things. This goes for all poker players, from the weakest beginners to the most seasoned pros. The deal is that even when opponents are playing a disciplined game of poker, so many of their decisions are borderlined that what they're going to do is anybody's guess
The idea is that given the exact same player, the exact same opponents, the exact same set of cards, the same amount of money, player actions will vary wildly just based on the current price of garbage in Moscow, or an increase in the butterfly population of Madrid. There's no telling what people will actually do, even if you present them with identical situations. Instead we have to contend with built-in unpredictability, a sort of inherent randomness to the world.

This is true not only in poker, but in life, and especially in programming.
The same programmer, given the same exact workload, given the same circumstances, will take anywhere between 50% to 150% as long to finish his work, based on nothing at all. Mood. Whim. Luck. The bad Chicken Marsala he ate last night. There's no way to predict this, no way to quantify it. The best you can do is resort to statistical methods to try to tame the beast. And even those don't work as well as we'd like, because the numbers we build are like houses of cards, prone to tumbling as soon as the assumptions that allowed us to generate those numbers are proven to be hopelessly naive, or on the other end of the spectrum, ridiculously conservative.
So for all these reasons and more, I've been hammered for the past three weeks playing catch-up on a side project, and unable to post. Cue the violins.
That project is finally concluded and for those of you who've asked whether the botting series will continue, the answer is absolutely. I hope you'll stay tuned as we continue discussing the mechanical aspects of poker botting, and as we start looking at the poker strategy and A.I. side of things more closely. We'll also touch on some other topics that I think you'll find quite interesting, if not shocking.
Expect the next post within 24 hours, give or take.
(But as I say that it occurs to me that estimating future publication dates is a bit of a black art, too, and even more difficult, in its own way, than estimating software completion times.)
Luckily this content is already written.
(But as I say that it occurs to me that content, like software, is never really complete. It can always be improved, honed, refactored.)
In the words of a poet:
What a tangled web of unrealistic schedules and intractable time-based dependencies we create, when first we start to estimate...
So, expect the next post within 12 to 36 hours, by the 50/150 rule stated above, and in the meantime: have you ever come across a software time-estimation method that actually works?
How good (or bad) are your software estimation skills?
Are they as bad as mine? As in need of constant oversight and refactoring? Or are you that rarest of creatures, the Bigfoot of Software Engineering...

A time estimation virtuoso? 
01-August-2008 12:08 PM
Here's a question for you. What does the following picture have to do with generating buzz for your website?

It's a typical conveyor belt such as you might find in any large donut shop or pastry factory. Krispy Kreme lovers, eat your heart(s) out.
And it also happens to be a near-perfect metaphor for how users find and browse content on the modern web.
Social networking sites, link repositories, news sites, discussion groups, even that great juggernaut of search engines, Google itself, all use the conveyor belt apparatus to deliver content to their users.
In other words, users are accustomed to seeing pages containing rotating lists of links to relevant content. New and/or more popular content appears towards the top of the page. Older, less popular content is reserved for the bottom of the page, or for some other page entirely.
Here's a picture of the Digg.com conveyor belt:

And the famous Google conveyor belt:

Depending on the nature of your site, conveyor belts will often be your primary method of attracting visitors. Unless users are typing your URL into their browser window, they'll usually find your content in some sort of conveyor belt listing, of which there are thousands all across the net:
- Google Search
- Google News
- Yahoo
- Yahoo Buzz
- Reddit
- Digg
- Sphinn
- Slashdot
Understanding how to make your content appear, even intermittently, on the major Internet conveyor belts, is worth its weight in gold. A properly conveyor-belted article can bring in thousands or hundreds of thousands of unique visits to your site. A single mention near the top of a major conveyor belt can take an obscure site and push it into the mainstream, at least for a time.
You must give your site a chance for exposure by placing it on the conveyor belts that are relevant to it.
It's important to remember that a given piece of content doesn't necessarily have to break the front page of Digg.com or appear as the #1 result for a generic search term in Google. Getting your content to the top of a conveyor belt is quite a feat, but what's really important is that your content appear somewhere on the conveyor belt, preferably not at the very end. That article you submitted to Digg, which only got 7 Diggs? Those 7 Diggs are valuable. That's 7 unique visitors who decided to independently "digg" your article. Those 7 visitors imply an unknown number of other visitors who did not choose to digg your article. Now every visitor who sees the page, sees a Digg count of 7 and knows that, while this might not be the most interesting content ever written, it was at least good enough that 7 independent people decided to express their opinion by Digging it.
In other words, getting your content on a conveyor belt has value beyond merely getting X additional users to visit your site. It also serves as a way to inform random visitors that your content has a degree of authenticity.
Putting it all together
So what does the conveyor belt metaphor mean in practice? Here are the broad strokes.
Titles are more important than you think. In a typical conveyor belt setting, the title is the only part of your content most users will ever see. The universal practice is to display hyperlinked titles which, when clicked, navigate to the full version of the content. So you have to structure your titles with this kind of mechanism in mind. A bad title can doom an excellent piece of content to the back pages, while a good title can vault even mediocre content into popularity. I can't overstress the importance of choosing good titles if you plan to compete. You must create titles that convince readers to click through.
Submission time is important. Each conveyor belt is different, and moves according to its own cyclic schedule of high activity, followed by low activity. By submitting your content at the wrong time, you can effectively hamstring it. The problem is that large conveyor belts have to deal with an almost continuous stream of submissions. New submissions generally get routed to a "New" or "Upcoming" set of pages, where all new content sits and stews, until it gets enough votes or Diggs to rescue it to a more prominent location. So if you submit a piece of content when all your readers are asleep, what happens is that a bunch of other people come in behind you and submit their content. Three or four hours later, when your users wake up, your content has been pushed down to the 3rd, 7th, 14th page of the "New" category - deep enough so that most users never see it, and never get a chance to click on it. In order to avoid this, submit your content when your likely readers will be awake and active, so that you can garner enough initial votes to prevent immediate obscurity.
Participation is important. In order to really know what kinds of content will do well on which conveyor belts, you really have to spend some time using those conveyor belts. Don't just submit to Reddit because you've seen other people submit their stuff to Reddit. Submit to Reddit because you read and participate in Reddit, and because you've got a solid feel for the kind of content that does well on Reddit. Another reason to participate is that many sites have some notion of "karma", which basically describes the authenticity of a particular user. If you create a Digg.com account for the express purpose of submitting and Digging your own stories, that's fine - but make sure to Digg some other good stories, too. There may or may not be a practical advantage to doing this, but one thing's for sure: it can't hurt. And ultimately, you'll get a lot more out of these sites if you're able to gradually build a solid network of friends and fans over time.
Voting widgets are important. Many conveyor belts, such as Digg and Reddit, feature a voting process in which users rank content and are ultimately responsible for determining the visibility of that content. This is typically done through a "voting widget" appearing next to the story, either on Digg itself, or on the original page where the content appeared. For example, in the top-right corner of this page, you'll see a typical, run-of-the-mill, Digg.com voting widget. If you don't mind a widget like this appearing on your pages, take advantage! And when you do, remember to not only display the voting widget at the top of your content. You also want the voting widget displayed at the bottom. You want the reader to see your (excellent) title on Digg, click through, read the content on your site, and then click the voting widget you've positioned at the bottom of your article. That's the user interaction you want, as it makes it as convenient as possible for readers to vote on your content
Hopefully this article has given you some food for thought when it comes to understanding the quasi-mechanical structure of sites like Digg and Reddit, as well as how to leverage that structure to promote your content. Of course, it goes without saying that for any of this to work, you've got to have content worth reading. But assuming you already have that base covered, exposing your content to popular conveyor belts can bring the lifeblood of any site - traffic - to your doorstep. 
01-August-2008 12:08 PM
If you've been programming in .NET for more than about 2 minutes you know that all .NET objects implicitly derive from System.Object.
But did you know that prior to .NET, in the world of native C++, the same convention existed (and still exists) in MFC? I mean the infamous CObject, the joy and bane of many an MFC programmer's existence. Every class in the MFC library (with very few exceptions) ultimately derives from CObject, which provides four basic services:
- Serialization
- Diagnostics
- Run-Time Class Information (RTCI, not to be confused with RTTI)
- Collections
Now, back in MFC's heyday, developers were encouraged to derive their domain classes from CObject, so as to leverage the benefits of the CObject boilerplate. So let's say you created a class Vehicle to use in your application. The idea was that, if you were building an MFC application, you'd go ahead and derive your Vehicle class from CObject, and be able to do things like serialization, if you wanted. For a while (a short while) this was even regarded as somewhat of a best practice, especially for developers who toed the Microsoft company line. The message was: build your application using the full power of the MFC library. The hidden subtext: abandon platform-independent solutions like the C++ standard library and do everything using MFC.
The problem, of course, was that CObject was a mess, and nobody really used it unless they had to. Now, I don't want to hear any geeks telling me that no, CObject was good, it was genius, it was brilliant. CObject was, is, and always will be crap, no offense to the team responsible for writing it, most of whom were brilliant.
But CObject failed - miserably - in its role as a universal base class. Because the services it provided just weren't that compelling:
- How often do you write a class that requires explicit serialization? And if you did, would you trust MFC's serialization, or use something else?
- How often do you really need cooked-in CObject diagnostics, when it's so easy to roll your own?
- How often do you write a class that requires the (dubious) powers of explicit run-time class information? (or RTCI, not to be confused with RTTI, run-time type information) If you're writing a lot of C++ code that has to explicitly check the type of an object at run-time, odds are you need to think about refactoring your code.
For all these reasons and more, CObject never really caught on as a "universal base class for developer-created classes". In practice, we worked with CObject because we were working with other classes, such as derived window or control classes, that themselves derived from CObject. To derive from virtually any MFC class is to ultimately derive from CObject, way up at the top of the inheritance hierarchy.
Now, around the time that MFC was gaining in popularity, developers were already realizing that deep inheritance hierarchies are evil. Herb Sutter explains in his excellent work, Exceptional C++:
Incidentally, programmers in the habit of making this mistake (using public inheritance for implementation) usually end up creating deep inheritance hierarchies. This greatly increases the maintenance burden by adding unnecessary complexity, forcing users to learn the interfaces of many classes even when all they want to do is use a specific derived class. It can also have an impact on memory use and program performance by adding unnecessary vtables and indirection to classes that do not really need them. If you find yourself frequently creating deep inheritance hierarchies, you should review your design style to see if you've picked up this bad habit. Deep hierarchies are rarely needed and almost never good. And if you don't believe that but think that "OO just isn't OO without lots of inheritance," then a good counter-example to consider is the [C++] standard library itself.
The MFC library is a classic example of the problems associated with deep inheritance hierarchies. In order to use a derived class such as a CListView, you have to know how each layer of the inheritance hierachy works:
- CListView
- CCtrlView
- CView
- CWnd
- CCmdTarget
- CObject
You end up with a sprawling in-memory layout of a particular object, with responsibilities divided (often unevenly) among the different layers of the hierachy. That sounds a little abstract, so let me tell you how it works in practice. In practice, you're sitting there working with your CListView, trying to do something like cause it to refresh, or handling print preview, or some aspect of message routing, and you can't remember where (at what level of the hierarchy) the particular service you're looking for lives. So it's another trip to MSDN, or fiddling around with Intellisense to figure out, aha, that particular feature lives in CWnd.
In other words, deep hierarchies are a big, confusing mess, and slapping a universal "I Am Object" base class on them doesn't fix the problem.
So why, if that's the case - if deep inheritance hiearchies are evil, and universal base classes along with them - why do I believe System.Object to be a brilliantly intuitive and effective universal base class? What did the .NET framework do right, that MFC got wrong?
For the answer to that, you'll have to wait, albeit with less than bated breath, for Part Two. 
01-August-2008 12:08 PM
Here's a rule you software developers out there can take to the bank:
Rambling, ultra-formal specification documents with headings, sub-headings, and dense tracts of text are one of the worst ways to communicate system features, requirements, architecture, design, implementation, or anything else.
Now, don't take offense just because you happen to have authored more than a few such documents in your lifetime. Don't take offense because your organization produces enough throwaway documentation each year to deforest the state of Vermont. We've all done it, and we'll continue to do it, because the next best thing to producing good software is producing a festering sinkhole of documentation just to establish that hey, we're doing important work here. But let's not fool ourselves into thinking that these documents really convey anything meaningful to our readers.
The likelihood of a specification document's actually being read varies inversely with its length.
The North Carolina Statewide Technical Architecture is a reference architecture with which state-funded IT projects are expected to comply. Your state or region probably has something similar, as does every major branch of government and the military. The NCSTA lays out, with impressive verbosity - around 50 separate Adobe PDFs - the best practices for software development in the sunny state of North Carolina.
It's littered with the language of the software development guru:
User process components coordinate the display of user interface elements. They are abstracted from the data rendering and acquisition functionality provided in the user interface components. Design them with globalization in mind, to allow for localization to be implemented in the user interface. For example, endeavor to use culture-neutral data formats and use Unicode string formats internally to make it easier to consume the user process components from a localized user interface.
And the Table of Contents (from the NCSTA Security Principles & Practices PDF) is downright intimidating:

Now, as a civic-minded taxpayer, and a software developer who reads and decrypts this kind of documentation for a living, I don't even know where to start.
- Why does North Carolina need its own proprietary version of a reference architecture? Aren't the IT needs of North Carolina very similar to those of Virginia, Kentucky, or Oregon? How many millions of dollars did it take to produce the NCSTA? And how many other states have produced something similar? Do we need to reinvent this particular wheel 50 times, one for each state in the union?
- PDF? That's my only format?
- Even assuming North Carolina needs its own proprietary architecture: why is the documentation so formalistic and difficult to read?
On this last point. Take the following paragraph from the NCSTA Microsoft .NET Enterprise Development Guidelines:
Using multiple panes for one activity. If multiple windows or panes are used in a particular user activity, it is important to keep them synchronized. In a Web application, a user interface usually displays a set of elements in a same page (which may include frames) for a given user activity. However, in rich client applications, several non-modal windows affecting just one particular process may be necessary. For example, a product category selector window floating in the application that to specify a particular category, the products in which will be displayed in another window. User process components help implement this kind of user interface by centralizing the state for all windows in a single location. Synchronization can be further simplified across multiple user interface elements by using data bindable formats for state data.
It's trying, admirably enough, to teach you how to synchronize the view of your data across multiple windows. The problem is that, if you can understand this documentation, you probably don't need it. So it's either irrelevant or hermetically confusing, depending on whether or not you know what things like non-modal windows are. (And just for the record: the word is modeless, not non-modal.)
So, how much of the information is really necessary? Assuming you're a fairly competent developer, qualified to read this documentation and implement it in practice? In other words, how much of this information is necessary and/or valuable to its sole intended audience? Well, let's take out our handy magic marker and make some corrections.
Using multiple panes for one activity. If multiple windows or panes are used in a particular user activity, it is important to keep them synchronized. In a Web application, a user interface usually displays a set of elements in a same page (which may include frames) for a given user activity. However, in rich client applications, several non-modal windows affecting just one particular process may be necessary. For example, a product category selector window floating in the application that to specify a particular category, the products in which will be displayed in another window. User process components help implement this kind of user interface by centralizing the state for all windows in a single location. Synchronization can be further simplified across multiple user interface elements by using data bindable formats for state data.
There you go. Simple.
Every last word can be discarded. These words add zero value or knowledge to the world that isn't either a) already known or b) explicitly stated fourteen other times in the labrynthine NCSTA documentation. In fact, the presence of these words provides a negative value. All your reader wanted to do was throw up a side window to display the person's name. Now you've got him off on a tangent, trying to figure out what the hell "synchronization can be further simplified across multiple user interface elements by using data bindable formats for state data" means.
Now the funny thing about all this, is that the NCSTA documentation is a virtuoso piece of technical specification writing if you compare it to the typical specification documents that governments tend to produce, usually under the auspices of "due diligence". So my complaints aren't so much geared toward the author(s) of the NCSTA as they are the entire genre of long-winded technical architecture documents in all their forms, and the institutional malaise that produces them.
In other words, you can't PDF your way to good software development. It's been tried and tried, without success. Consider, in your organization, using more fluent and expressive mechanisms to convey system structure or communicate best practices, and your users will thank you for it. 
01-August-2008 12:08 PM
Introduction
Several years ago, a client asked me to come up with a prototype for a real-money online poker bot. That's right: a piece of software you park on your computer while it goes out to a site like PokerStars or Full Tilt and plays no-limit Holdem for you, at 4 or 14 different tables, for real-money stakes.
If you're a poker player, and particularly if you're an online poker player, you've probably heard rumors about the rise of the poker bots. Unfortunately there's very little hard information out there (for obvious reasons) about how to build one of these bots. In fact, many so-called authorities still dismiss poker bots as a relic of the overactive poker player's imagination.
Well, I'm here to tell you that online poker bots are 100% real, and I know this because I've built one. And if I can build one, well. Anybody can build one. What's more, over the course of this multi-part article, I'll show you how. But first, a teaser (click on the image for a larger version):

That, ladies and gents, is a picture of a full-featured poker bot managing three play-money tables (note: this same bot also handles real-money tables) at an honest-to-goodness, real-money online poker site. Of course, it could be any site. The bot implementation I'm going to reveal will work at all major online poker sites, including Poker Stars, Full Tilt, Party Poker, Ultimate Bet, and most other major venues.
Why are you giving this information out?
I debated for a long time whether or not to make this information public, as I'm a poker player myself and have no desire to see the game ruined by an avalanche of poker bots. It's not that building a poker bot is some sort of black magic, known only to the privileged few. Any competent programmer can build one. But this information hasn't, so far as I know, been collected and presented in one place, certainly not as a "How To" complete with sample code. So the question I struggled with was this: is it irresponsible to publicize this information, such that every Internet script kiddie out there now has the ammunition he needs to actually build a bot?
After thinking about it, I've decided that keeping the technology of poker bot building secret is like declaring that only criminals can carry handguns. The fact is, there are people in the world right now who are doing this:

Poker bots, underground online poker boiler rooms, and collusion are a reality. That doesn't mean online poker's not worth playing, just that it pays to be educated about what's possible. Furthermore, there should be public discussion regarding what to do about it because one thing's certain: computers and programming languages aren't exactly going to be getting less powerful. The rise of the poker bots is a virtual certainty. I'd like to see the major online poker venues open up their famously vague "bot detection" and "anti-collusion" strategies to public scrutiny, as cryptography and security providers learned to do years ago. The best security algorithms and techniques all have the weight of public review behind them and I don't see how online poker's any different.
But even assuming all that weren't the case:
- Poker bots already exist on the open market. Do a little creative Internet searching.
- The poker community suffers from an irrational fear of bots. I'd gladly risk my money against most homegrown bots and trust me: you would too.
- I believe that bots are actually good for the game of poker. Mike Caro, "the Mad Genius of Poker," expressed a similar idea years ago.
- Any programmer worth his salt can build a bot with or without this document. They already have.
If you're visiting this page from 2 + 2 or another poker community, and you want to stay on top of this article (which will be in several parts), you can subscribe to the Coding the Wheel RSS feed or get it in your email inbox as I don't participate in these communities often. For easy digestibility, I'll be organizing these posts using a question and answer format, as there's a lot of highly technical material to cover.
Now, without further ado, let's talk about the basics. If you're not a programmer, fair warning: highly technical, possibly excruciatingly boring material ahead.
Basic poker bot responsibilities
At a very high level, the poker bot is best analyzed according to the classic model of information handling: Input, Processing, Output.

You'll find that your programming tasks decompose rather nicely into these three basic stages.
Input. The input to the system is the poker client software itself, including all its windows, log files, and hand histories, as well as internal (often private) state maintained by the running executable. The goal of the input stage is to interrogate the poker client and produce an accurate model of the table state - your hole cards, names and stack sizes of your opponents, current bets, and so forth.
Processing. The processing stage runs independently of the other two stages. It's job is to take the table model assembled during the Input phase, and figure out whether to fold, check, bet, raise, or call. That's it. The code that performs this analysis should (ideally) know nothing about screen scraping or interrogating other applications. All it knows is how to take an abstract model of a poker table (probably expressed as some sort of PokerTable class) and determine which betting action to make.
Output. Once the processing stage has made a decision, the Output stage takes over. It's tasked with clicking the correct buttons on the screen, or simulating whatever user input is necessary in order to actually make the action occur on a given poker site/client.
How does the bot figure out what its hole cards (and the board cards) are?
This is a broad question which it's better to break down into particulars. First of all, there's a very easy way to detect hole cards via a screen-scraping or "poor-man's OCR" approach. You don't have to be an image-recognition expert. All you have to know is how to get the color of a handful of different pixels on the screen. Or to put it another way, for any given card in the deck, there are a handful of pixels you can test which will uniquely identify that card.

That's fairly easy to implement, and requires zero knowledge of OCR, image recognition, graphics processing, etc. But depending on the specific poker site, pulling card rank and suit information might be even easier. On some sites, the hole cards will be emitted into the real-time game summary info:

Occasionally you'll find that hole cards are emitted into the log file. Poker Stars, for example, conveniently emits this information into its log file, and it does so in real time (meaning you can snoop on it in real time, and in the next installment, I'll show you how):
MSG_TABLE_SUBSCR_ACTION MSG_TABLE_SUBSCR_DEALPLAYERCARDS sit1 nCards=2 sit3 nCards=2 sit5 nCards=2 sit6 nCards=2 sit7 nCards=2 dealerPos=3 TableAnimation::dealPlayerCards MSG_TABLE_PLAYERCARDS 00260C82 ::: 8s <-- Hole Card 1, Cool! ::: 13c <-- Hole Card 2, Cool!
Last but not least, hole cards are always included in the hand history for a given game:
*** HOLE CARDS *** Dealt to CodingTheWheel [Qs 9h] MargeLeb: calls 10 ke4njd: calls 10 diamondlover2nite: calls 10 franklg454: folds WhoAmINot: calls 5 CodingTheWheel: checks *** FLOP *** [4h 7c Qd] WhoAmINot: checks CodingTheWheel: bets 10
The only problem is that, in many cases, the hand history file isn't emitted until the end of the hand.
How should the poker bot be structured, as a single EXE, a bunch of DLLs, what?
You will need:
- An executable file (.EXE) to display the bot's UI, and to contain the processing logic (the stuff that knows how to play poker).
- A dynamic link library (.DLL) to handle the Input (screen scraping) and Output (clicking buttons) processing. You'll inject this DLL into the poker client's process so that your code is effectively running as part of PokerStars, or FullTilt, or whatever site you're using. This will make your life a lot easier both when it comes to collecting data as well as doing things like simulating genuine user input.
Those two pieces are essential. Other than that, you're free to structure things however you want. I'll have more to say on this as we get into the nitty-gritty details of the implementation.
How do I inject my code into the poker client process?
There are a number of well-documented techniques for injecting your code - for example, a DLL you've written - into another application's address space. The method I used, and the method I'm going to recommend you use, is by installing what's known as a Windows Hook and specifically a CBT Hook. The relevant Windows API is SetWindowsHookEx, and here's the actual source code. If you're familiar with C++ and the Windows API, it should be straightforward:
/////////////////////////////////////////////////////////////////////////////// // This is the CBT hook procedure. The HCBT_CREATEWND notification generally // doesn't give us any useful information about the window because WM_CREATE // hasn't been called for the window yet. So instead we don't consider the // window as created until it's gotten it's first WM_ACTIVATE (note: this is // how it works on Poker Stars, the behavior may need to be changed for other sites) /////////////////////////////////////////////////////////////////////////////// LRESULT CALLBACK PokerBotCBTProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode < 0) { return CallNextHookEx(g_hHook, nCode, wParam, lParam); } else if (theInjector.getVenue() != Venue_Unknown) // ignore this bit of code for now.. { // Since we can't use DllMain, perform initialization the first time the hook is called. if (g_bFirstTime) { theInjector.inject(); bFirstTime = false; } // These are the only notifications we're interested in passing on. if (nCode == HCBT_ACTIVATE) return (LRESULT) theInjector.HandleIt(Hook_Activate, (HWND)wParam); else if (nCode == HCBT_CREATEWND) return (LRESULT) theInjector.HandleIt(Hook_Create, (HWND)wParam); else if (nCode == HCBT_DESTROYWND) return theInjector.HandleIt(Hook_Destroy, (HWND)wParam); } // Return 0 to allow window creation/destruction/activation to proceed as normal. return 0; } /////////////////////////////////////////////////////////////////////////////// // Publically exported hook installation function. The bot will call this on // startup in order to inject this DLL (the DLL that contains this function) // into the address space of every process, including every poker client process, // on the machine. /////////////////////////////////////////////////////////////////////////////// bool OPCHOOK_API InstallHooks() { // Actually install the hook... g_hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC) AutoCBTProc, hInstance, 0); return g_hHook != NULL; }
The above source code would live in a DLL: the DLL you plan on injecting into the poker client's address space. This DLL will also contain whatever code you write to handle the "input" (screen-scraping) and "output" (button-clicking) stages of the bot.
An even better way is to use a two-stage injection process. The problem with global CBT hooks (or any other kind of global hook for that matter) is that they cause the hook DLL to be loaded into the address space of every process on the machine. If your hook DLL is very fat (for example, if it contains a bunch of code to do screen scraping and so forth) this can impact system performance as your DLL will get mapped into processes you care nothing about, like Notepad.exe.
So to get around that, make the hook DLL - the DLL that gets loaded into every process - as lightweight as possible. Then, whenever the hook DLL detects that it's been loaded by a poker client process, such as POKERSTARS.EXE, have it explicitly load another DLL (again, written by you) containing the bulk of the bot I/O processing code. This in fact is the purpose of the theInjector object in the above code sample - it figures out if the DLL is being mapped into a poker client process and, if so, uses LoadLibrary to load the actual DLL that knows how to do things like screen-scraping and so forth.
A picture might help to clarify:

Here, INJECT.DLL would be a lightweight DLL, written by you, which contains the CBT Hook procedure and installation code I showed you above. POKERBOT.DLL is the fat, messy DLL, also written by you, that contains the poker bot's screen-scraping logic.
Do things this way, and the drag on the system shouldn't even be noticeable, other than a brief load period when you first install the hook. This method is a lot easier than most other methods of DLL injection, and more importantly, it's supported across all the major Windows operating systems.
How do I retrieve the game summary text from the poker table window?
Almost every online poker client displays a small window in which game summary text is displayed:

Now, depending on which poker client you're using, this window may or may not be a standard Windows edit box or rich text control.
If it is a standard Windows control, you can get the handle (HWND) to the window, and then get its text via the GetWindowText API. Furthermore, you can do this even if the window you're interrogating is owned by another process.
But what you'll find is that many poker clients don't use "normal" Windows controls. They may write their own custom display controls, or they may subclass a standard Windows control and cause WM_GETTEXT to return an empty string.
In that case you have at least three options, none of them trivial:
- You can investigate the control at the binary level. No matter how customized the control, somewhere in memory it's maintaining a string or a list of string which contains the game summary text. Since your code will be running inside the poker client's process, you're free to do whatever you want to do - investigate different areas of memory, subclass the control, etc.
- You can use API hooking to hook the core Windows APIs that every control uses to display text: DrawText, ExtTextOut, etc.
- You can use full-fledged OCR to analyze the text window and return the text. But this is probably overkill, especially since text tends to run through the summary window rapidly.
When building the bot, I went with the second approach: API Hooking. Once you know how to hook a particular Windows API, so that whenever POKERSTARS.EXE thinks it's calling DrawText, it's actually calling your custom version of DrawText, which snoops on the text before passing the call on to the original DrawText, it's a simple matter to examine the output coordinates to determine, aha: this text is being written to the summary window; this text is being written to the title bar; etc.
This is a deep enough topic that I'll roll it into its own installment along with specific code examples.
Hook a Windows API? Instrumentation? What does that mean?
Every Windows application in the world has to call into the Windows API to get things done: open files, create windows, display text, etc. Even language-specific libraries such as the C run time library or the C++ standard library internally will use the OS-provided facilities to work with things like files, memory, and so forth.
API hooking or "instrumentation" is the process of intercepting the function calls that an application (any application) makes, and redirecting them to a custom function defined by you. Specifically, you're going to intercept some of the calls that the poker application makes to the Windows API...
- DrawText
- ExtTextOut
- WriteFile
- etc
...and redirect these calls to a custom "interceptor" function, written by you. Your code thus gets a chance to examine the parameters of the call (which could be a string containing the player's name, for example) and do any other work you desire. When your "preprocessing" is done, you'll pass control back to the original API the poker application thought it was calling in the first place so that everything works transparently.
This technique can be used to extract all manner of useful internal information from any application, not just online poker clients. The best part is: you no longer have to write custom assembler code to achieve this. Instead you'll use a third-party library, and one of the best is a little-known Microsoft Research Project, Detours. Download it. Learn it. Love it. Learning how to accomplish API instrumentation means that ultimately, there's nothing the poker client can really hide from you - but that doesn't mean you'll be able to snoop around and figure out your opponent's hole cards. Don't even try. Unless the implementors have been sloppy, that information won't exist anywhere on your machine until your opponents have actually flipped their hole cards over.
And yes, if there's sufficient interest I'll put together a dedicated post with sample code showing exactly how to instrument a poker application.
Generally speaking, how do I go about harvesting data from an online poker game?
We've covered a few of the specifics so far, and we'll cover many, many more in future installments. But specific techniques aside, getting information from the poker client is an exercise in detective work. First of all, be aware of just how much information is available:
- Visual Table State. Everything a human player sees when playing online poker: his hole cards; the names, stack sizes, and betting actions of all players at the table; the position of the button; and so forth..
- Summary Text. Each table usually displays a text summary area which captures various betting actions, the beginning and end of new hands, etc.
- Action Buttons. These are the buttons the user clicks in order to Fold, Raise, Call, etc. Note that we can use the presence or absence of various action buttons to infer table state.
- Log File. Many poker clients output a log file which may contain helpful information.
- Hand Histories. Most poker clients output a formal "hand history file" which contains a complete description of a single hand of poker.
- Internal Stuff. Internally, most poker client makes standard calls to the C run-time library, the C++ standard library, and the Windows API. You can eavesdrop on these calls through a process known as API "hooking" or instrumentation. Additionally, poker clients, like all software, use memory to store things. Things like player names, cards, and betting actions.
- And more. Stuff I may not know about, or may have chosen not to mention.
The bot's job is simply to eavesdrop on that information, and analyze it to produce an accurate model of the table's state at any given point in time. So any technique now or in the future which allows you to do that is potentially a technique you'll want to leverage in the bot. Later, I'll suggest an architecture whereby a number of different interrogators can be used to query poker tables in a simple, extensible, and above all tweakable way.
How do I create a bot that's intelligent enough to play winning poker?
That's the million-dollar question. I could tell you that the folks over at the University of Alberta's Computer Poker Research Group have made impressive headway towards producing a winning poker bot. I could tell you that extensible rules-based systems like the one I implemented for my bot...

...are a lot more powerful than you think. I could tell you a lot of things, and we'll investigate how to leverage some of the poker bot frameworks that are already out there, and how to combine those with your own custom rulesets. But understand one thing: you don't have to create a winning poker bot in order to make money with a poker bot. All you have to do is create a bot that's capable of breaking even.
If you can create a bot that breaks even - neither wins nor loses money - rakeback deals and specific programs like the Poker Stars Supernove Elite will ensure that you get a fairly hefty payday per bot account. I mean many tens of thousands of dollars per year, per account. And nothing except the logistical nightmare of it all restricts you to a single bot account; why not have ten; or a hundred?
And indeed, unbeknownst to the rest of the world, somewhere, someone probably does. But not me, and not you; and that's a disparity in basic firepower I'd like to see remedied, since none of the online poker sites have really stepped up to the plate and either a) made bots legal (similar to the way that they're legal on Internet Chess Club) or b) put effective prevention measures in place.
What skills will I need to write a bot?
Well, you'll want to be well-versed in the nuances of C++ and the Windows API, at a minimum.
In addition to that, you'll either need to be familiar with, or get familiar with, an assortment of Windows development topics that reads like a chapter out of Richter (whose books I highly recommend purchasing and studying if you plan on implementing a bot yourself).
- Windowing & GDI
- Windows Hooks
- Kernel objects
- DLL Injection (in general: the injecting of code into other processes)
- API Instrumentation (via Detours or similar libraries)
- Inter-process Communication (IPC)
- Multithreading & synchronization
- Simulating user input
- Regular expressions (probably through Boost)
- Spy++
While it would probably be possible to build a bot using C#, VB.NET, or any other language, you'll find that some of the powers you'll need are only available through specific Windows APIs, and getting access to these APIs from a managed language is a little clunky. Another reason you'll want to use native C++ is that you'll need to sneek some of your code into the client poker process, and it's a lot cleaner to inject a small DLL than it is to inject all the machinery necessary to get managed code to run inside another (native) process.
Conclusion
This post has only scratched the surface of building a full-fledged poker bot. Hopefully it's given you food for thought and possibly whetted your appetite for the mountain of details left to be discussed. Assuming there's sufficient interest, I'll be posting a series of installments, each describing at a detailed level how to accomplish one specific poker bot task. If you found this document through a link on 2 + 2 or one of the other poker forums, you can subscribe to this site in a reader or get it in your email inbox, as I rarely post (or reply) on the poker forums these days. 
01-August-2008 12:08 PM
Introduction
Last week, I posted about how I built a working, real-money online poker bot. This week, we'll discuss how to get started building your own bot, address some specific bot-building techniques, talk about the woeful state of online poker user privacy, respond to a few reader questions and comments, and close out with some recommended reading.
This series is both a detailed manual on how to build and make money with an online poker bot, and a story of how two guys from the Dallas poker underground managed to realize such a bot in practice.
We'll be discussing everything necessary to build what's quickly becoming the de facto standard in online poker botting: a sophisticated parallel processing rig incorporating collusion AI, massive hand history databases, and real-time information flow to dominate the opposition. This is where the world is headed:
NOTE: While I believe building and running an online poker bot to be neither cheating nor unethical, building a ring of such bots is a different story. As a long time poker-player, I absolutely don't condone cheating people out of their money by colluding in online poker or any other game. We're going to discuss things like bot collusion not so we can (all |