Beyond Stupid, Delphi 2009
If you're one of the few remaining Delphi developers out there, you're probably aware that Embarcadero recently bought Code Gear from Borland. Code gear, previously a subsidiary of Borland, is now a subsidiary of Embarcadero Technologies. Everyone heraled it as a great move that would somehow rescue the dead language from obscurity. (More)
Humor: An Embarrased Resume Spammer
Recruiters. When I was 20 I thought it made me special that when I posted my resume online, dozens of headhunters would soon follow. But now, the "resume spammer" is an all-too-commonplace nuisance.
A resume spammer, if you don't know, is a "recruiter" that picks candidates based on keywords in their resume and matches them with other jobs that match the same keywords. They then call you up claiming to have great "ins" with the company and ask that you let them exclusively represent them. If they land you a job, they take a big commission.
They generally are not knowledgible about technology so they wouldn't know PHP from Cobol. They simply match keywords.
The worst example of this called me up yesterday asking if I had "Web Focus" experience. No, I said, "I don't have Web Focus experience, but the words 'Web' and 'Focus' are both on my resume, having worked for a company with 'Focus' in its name. "
The only jobs I've ever taken have been the ones I found myself, and sometimes I have to call up these recruiters who list jobs and simply demand to know why they have not called me about an opportunity that is clearly a match.
The good news is, I think I've found a company that is for me, and in record time! I'll blog about it when it is more official.
The curse of having loved Delphi too much.
If you're a fellow Delphi developer, you feel it too. You're in a job interview and you make the mistake of mentioning that you have some history in working with Delphi... and you're immediately no longer so well received. The tone at the other end of the table transforms from one of "Wow. It looks like you've had some great experience here!" to one of: "oh... uh... i see... that's what's wrong with you" (More)
Spamtastic Spam Fighting - Part 2 - Integrating tightly with microsoft POP3 services.
After some searching and digging I found some COM interfaces that you can implement and register to implement your own SPAM filtering solution. I did this using Delphi 2007. My system is completely up and running now and catching at least 99% of all SPAM sent to my server. (More)
Brief Side-by-side comparison of Microsoft's Intellisense vs. CodeGear's Code insight
This is a quick summary of some of the differences between Code Gear's Code Insight (for Native Delphi) and Microsoft's Intellisense (for C#). It should be noted that Microsoft's intellisense is not nearly as feature rich for its own native languages (e.g. VC++), but it would sure be nice to have native Delphi catch up to C# in this department.
| Feature | Intellisense | Code Insight |
| Works with globals immediately as you type | YES | No, requires Ctrl+Space |
| Lists keywords | YES | No |
| Sorts items by ancestry | No | Yes |
| Option to remember frequently used items | YES | No |
| Auto lists enum constants when assigning to an enum type | YES | No |
| Easy overrides, lists virtual/abstract ancestors automatically | YES | No |
| Easy construction, complete constructor signature generated from declaration (handy especially when there are parameterized types) | YES (after typing NEW) | No |
Spam fighting basics
A DIY approach to elimiating 99.6% of spam without much code at all.
Congratuations! You're screwed!
An anecdotal account of the bursting housing bubble. (More)
Rock the Lake -- Guitar Hero III Tournament, a Brilliant sham
At first glance, the Rock the Lake tournament seemed like an exciting opportunity to play guitar hero in a more exciting environment, but after registering for the tournament and rereading the rules about 12 times, I began to notice how it was actually just a clever concoction designed to keep people in the Casino for absurd hours... and wasn't really any fun at all. (More)
Why lock(this) is good
Idiots abound. C# being such a popular language is bound to have a billion retards contributing forum posts, blogs, and and even magazine articles full of misinformation. The most irritating artcicles, in my opinion, are the ones that try to hold your hand, as if, you are a child, and tell you to "never" do something. Or say doing something "is bad". One thing that has been taking some heat is the use of lock(this). (More)
Understanding why SQL sucks in more detail than you would ever want to know.
I've never been a fan of SQL.
(More)Thinking about a career change? A Delphi study in BlackJack
The original putpose of this project was to create a program that would implement various card-counting techniques to see whether they could yield odds in the player's favor. The eventual goal was to find a way to play blackjack that would yield profits for players. There are people who play blackjack for a living. But I just had to wonder whether they're profiting off of sheer luck or whether they know something the rest of us don't... and decided to build a Delphi program that sought to determine exactly HOW to win.
BlackJack is an odd game in the casino. People say that the odds are in the favor of the house, which is clearly the case for slot machines and video games, but is it really true even for BlackJack?... Something just made BlackJack seem instinctively in the player's favor to me. Maybe I'm just more brilliant than everyone else, but I argued that the odds were in the player's favor if the player just plays an appropriate strategy. BlackJack odds are not entirely obvious. It isn't like roulette where you have 13 black numbers, 13 red numbers, and 2 GREEN numbers which are obviously there to tip the scales in the casino's favor against people betting on color. BlackJack is oddly imbalanced in that "Zerg vs. Protoss" sorta way:
- Dealer Advantage: Player must act after seeing only 1 dealer card.
- Dealer Advantage: Dealer hitting blackjack nulls all play unless player is dealt blackjack. (no chance to play for a 21-push)
- Dealer Advantage: If a player busts, he/she loses even if the dealer subsequently busts.
- Player Advantage: Dealer must play to hard 17 or soft 18, cannot stand on 16.
- Player Advantage: BlackJack pays bonus 1.5:1. Here you win $15 on a $10 bet, even though the odds of you geting a blackjack are the same as the dealer's odds.
- Player Advantage: Bets can be doubled in exchange for limiting the hand to just 1 more card. This means that in advantageous siturations, you can win more than you normally would.
- Player Advantage: Pairs that add up to values that would normally be bad, can be split into separate hands. The best example is 8s. Two 8s add up to 16, which is the worst hand in blackjack. But when split they have a good potential to become two 18s. Most casinos allow hands to be split then subsequently doubled. Playing this in favorable situations can really bring in the cash.
So according to this list, there are two key dealer advantages. The 1st is that the dealer gets to spook people into hitting hands into bust, or standing on weak hands by forcing the players to act FIRST, after seeing just one card. Players generally assume that the hidden card is a 10 (which is only true about 30% of the time) and build their hit/stand strategy around that assumption. The variance in possible outcomes after showing just one card is big enough that just about anything can really happen for the dealer. The chance of Win/Push against a dealer showing a "2" is about 50%Win/57%Push. For a 6 it is about 58%/60%. If the dealer shows "10" it is 38%/46%. This is according to my BlackJack Delphi app. Players play differently against a 6 vs a 2. But really the difference isn't that great and a dealer showing a "6" isn't as great of an event as it may seem to players at only a 60% chance of pushing. It should be noted that aforementions statistics come from strategic play, and not from card odds. It might be possible to improve the statistics by adjusting the AI strategy.
The second dealer advantage is that he wipes anyone out who doesn't have a BlackJack when the dealer gets a blackjack. You have no chance of playing to 21 for a push.
In poker, there's a term called the "pot-equity ratio", which a winning poker player must be very aware of if playing for long-term money-making. A poker player has to be very conscious of how much money is being spent on winning hands vs. losing hands. In the long run, if more money is spent overall on losing hands than winning hands, then the betting strategy needs to be adjusted. The P/E Ratio is generally calculated to determine whether a particular pot is worth what someone is betting for it, or what a good strategic bet would be if the goal is to force a fold or call.
Applying this kind of concept to BlackJack, items 3-6 on the above list are strategies that shift the Pot-Equity in the player's favor over the long term. Sure the chances of winning a single hand are about 49/51 if you play the same strategy the casino plays... ... but what about the chances of winning money in the long term if you use every advantage you have?
So I set out to white a Delphi program that could determine, whether playing BlackJack could guaranteee long-term income.
The first task was to build deck class and fill it with 7-decks of cards. Shuffle the deck.
Next I built functions for calculating the values of a hand by adding up the values cards with additional information as to whether the value is "soft" (contains and Ace) or "Hard".
Next I built the logic for playing the dealers hand. Casino's have very rigid rules for how the dealer must play the hand. They are quite simple. The dealer must HIT anything under a 17. If the 17 is soft (Ace 6), then the deeler must HIT the soft 17. This can be accomplished with a simple WHILE (dealer.value < 17) or (dealer.IsSoft and (deadler.value=17)) do dealer.Hit.
Next I built the payout system accounting for the fact that BlackJacks pay 1.5:1.
Finally I built the most difficult part: The player AI. But still, it was pretty simple, certainly easy compared to my poker =-bot code. I used a strategy card as a template for the AI like this one: http://pokeronamac.com/images/articles/online-blackjack-strategy/blackjack-strategy-card.gif
The AI also inincluded cluding different betting strategies. I implemented various shemes that some-people claim are "foolproof" to see if betting strategy would help or hurt me in the the long run. One popular strategy is to double the bet on any loss, thereby nulling out the previous loss on a win. But think about that one like a computer programmer. We're all pretty familiar with powers of 2, being computer programmers right? So lets say you start with a $2 bet. And the table maximum bet is $100. How long of a losing streak would you have to endure before you hit the table maximum? Well... just 8 rounds. A pretty typical losing streak. The bet goes from 2-4-6-8-16-32-64-128... What the hell do you do then? The casino's put a bet limit on the table for a very reason... they aren't dumb. But even if you were disciplined enough and rich enough to switch to a higherstakes table... think about it... you lose 16 games in a row, and the bet is now at $65536. If that doesn't scare you, then nothing must. No casino in my area lets you bet anywhere close to that.
Eventually I got the AI to play the strategy card exactly, including all splits and doubles. I then charted the chip wins or losses over many many many games.
What I found was, of you follow the strategy card to an absolute "T", the odds are in YOUR favor!
But you really have to follow it to a "T". My simulator didn't start winning until every little box in that strategy card was implemented and verified. If you decide to alter the strategy card's recommendations for doubling, even in just one square.... you WILL LOSE.
Some interesting things to note: Whereas you can win at a table that doesn't allow double's after splits, you don't win much, I tested this by adding compiler directives to my AI .. Pay attention to the card's advice regarding splitting 4s, 3s, and 2s. There's a good opportunity to win there.
After it was complete, I tested some various betting strategies, and found that no betting strategy really works better than straight betting with proper doubles and splits. Doubling your bet on losses only makes the game more volatile (which may be exciting to you if you're in it for quick money... or quick losses). But eventually.. the bet limit will catch up to you and it will hurt. For fun I tried different table limit, but even with a sky high table limit, you can get burned REALLY bad.
Quick Tips: Working with .net on SmartPhones
Just when you thought that no operating system could be more poorly thought out than the PocketPC platform.... enter SmartPhone... which is a broken version of the PocketPC platform... which was already broken to begin with. Read more. (More)
Named Indexers in C# with just 2 lines of Code.
Digging around for a hack that would let me add indexers with names to my C# classes, I found mostly cumbersome hacks requiring loads of tedious busywork. I tested out a few, but after some thought, I managed to create a generic that would create a named indexer with just two additional lines of code beyond the accessor implementation.