|
|
Comments and Discussions
|
|
 |

|
Hello,
I'm having a good bit of fun experimenting with this code and was wondering how to extend it to run multiple decks as I rarely play in real life with a single deck.
Thanks,
--Brian
|
|
|
|

|
I'm getting an error when I try to run the source code, "Visual Studio cannot start debugging because the debug target "c:\program files\NUnit-Net 2.0 2.2.5\bin\nunit-gui.exe" is missing"
What am I doing wrong here?
Thanks!
|
|
|
|

|
HandEvaluator is the default startup project. Since this project does not compile to a .exe, there is nothing for the debugger to start. Change the default to the application you wish to run and try the debugger again.
|
|
|
|

|
Man ,you are the best ,congratulation for this formula .
|
|
|
|

|
Hi,
I downloaded the source which looks like it was made in VS 2005.
When VS 2010 converts the file everything seems ok except when trying to debug.
I always get the error message
Visual Studio cannot start debugging because the debug target 'C:Program Files\NUnit-Net-2.0.2.2.5\bin\nunit\nunit-gui.exe is missing.'
I checked the output path and build properties and there is no mention of nunit.
Has anybody else seen this problem ?
Any suggestions would be appreciated!
Thanks,
Ivan
|
|
|
|

|
I managed to get past this problem.
In the properties of the solution I checked the "build" option for the new project I created.
I am making a standalone project which will depend on the other project primarily to explore the Outs functions described in the article.
These functions don't seem to be present in the source that I downloaded.
modified 5 Jun '12 - 18:10.
|
|
|
|
|

|
Hello Keith and codeproject comunity,
first thank you a lot for this great codes.
I used this code below and find out that all boards with 3 suits in the first 3 boardcards
(and two player) analysed are not same to pokerstove...
but if there are not 3 suits in the first 3 boardcards the analyse is the same like pokerstove..
Can you help me ... in this case I dont know where I have to start...
Thank you a lot
Riki
and I tryed it with this 4 boards:
a) board = "9h 6h 4s" with result pokerstove for AsKs (28,3%) <> my code for AsKs(28,3%) o.k.
b) board = "9h 6h 4h" with result pokerstove for AsKs (24,7%) <> my code for AsKs(22,4%) !!!
c) board = "9h 6h 4h 5h" with result pokerstove for AsKs (19,3%) <> my code for AsKs(9,1%) !!!
c) board = "9h 6h 4s 5h" with result pokerstove for AsKs (13,6%) <> my code for AsKs(13,6%) o.k.
Here my used code
using System;
using HoldemHand;
// Iterate through all possible hands
// to see how these two hands compare
namespace HoldemHand
{
class Program2
{
static void Main(string[] args)
{
// Create hand masks
ulong player1Mask = Hand.ParseHand("as ks");
ulong player2Mask = Hand.ParseHand("jd jc");
ulong boardcards = Hand.ParseHand("9h 6h 4s 5h");
ulong deadcards = Hand.ParseHand("");
long player1Wins = 0, player2Wins = 0;
long count = 0;
// Iterate through all possible boards
foreach (ulong board in Hand.Hands(boardcards | 0UL,
deadcards | player1Mask | player2Mask, 5))
{
// Create a hand value for each player
uint player1HandValue = Hand.Evaluate(board | player1Mask, 7);
uint player2HandValue = Hand.Evaluate(board | player2Mask, 7);
// Calculate Winners
if (player1HandValue > player2HandValue)
{
player1Wins++;
}
else if (player1HandValue < player2HandValue)
{
player2Wins++;
}
count++;
}
// Print results
Console.WriteLine("Player1: {0 .0}%",
((double)player1Wins) / ((double)count) * 100.0);
Console.WriteLine("Player2: {0 .0}%",
((double)player2Wins) / ((double)count) * 100.0);
}
}
}
|
|
|
|

|
Srry my fault... of course
this code-part was wrong:
"foreach (ulong board in Hand.Hands(boardcards | 0UL, deadcards | player1Mask | player2Mask, 5))"
the right code ist:
"foreach (ulong board in Hand.Hands(boardcards, deadcards | player1Mask | player2Mask, 5))"
Bye Riki
|
|
|
|

|
Hi Keith, in the texas holdem hand evaluation how can obtain the best five card at showdown.
Example. board is "As 2d 3d Ah Kc" player has "4h 5c" -> the best five cards are :"As 2d 3d 4h 5c" ->Streight!
Thanks very much!
Alberto
|
|
|
|

|
I complete answer my question.
for all, to get the best five cards at showdown this is the code:
string GetBestFiveCard(string board, string winner_hand)
{
ulong totalmask = ParseHand(winner_hand+ " " + board);
string name= DescriptionFromMask(totalmask);
ulong bestfivemask= BestFiveCards(mask);
return Hand.MaskToString(bestfivemask);
}
private static ulong BestFiveCards(ulong hand)
{
#if DEBUG
if (Hand.BitCount(hand) < 5 || Hand.BitCount(hand) > 7) throw new ArgumentException();
#endif
uint hv = Hand.Evaluate(hand);
// Loop through possible 5 card hands
foreach (ulong hand5 in Hand.Hands(0UL, ~hand, 5))
{
if (Hand.Evaluate(hand5) == hv)
return hand5;
}
throw new Exception("Error");
}
|
|
|
|

|
There are issues with the current hand distance function in that it calculates the distance from the nuts without taking account of the distribution of the cards (if one player has a card then no other players can also have it). Eg: having the second nuts flushing hand: Ks, 2s with a board 7s, 3s, Qs gives a value of 17th best hand instead of 2nd. Having a hand of Ks, 9d with a board Kc, Kh, 9h gives a value of 2nd best hand instead of nuts.
I have been testing the following function for a while and seems to be correct for hands greater than two pair, once you get to hands lower than trips it is not easy to create an algorithm to take account of all possibilities without over counting / undercounting. Moreover, at this type of hand, depending on the board, there are many hands that can beat the hand held and the actual count is probably academic.
All feedback welcome. The code is given in the same spirit that keith has released the library.
/// <summary>
/// This method returns the mask distance from the best possible
/// mask given this board discounted to take account of the
/// distribution of cards (no draws are considered). The value 0 is the
/// best possible mask. The value 1 is the next best mask and so on.
///
/// Function provided by Matt Baker.
/// </summary>
/// <param name="pocket">The players pocket mask</param>
/// <param name="board">The board mask</param>
/// <returns>An integer representing the distance from the best possible mask</returns>
static public long HandDistanceDiscounted(ulong pocket, ulong board)
{
#if DEBUG
if (BitCount(pocket) != 2) throw new ArgumentException("player must have exactly 2 cards");
if (BitCount(board) != 3 && BitCount(board) != 4) throw new ArgumentException("board must contain 3 or 4 cards");
#endif
uint hv = 0U;
SortedDictionary<uint, string> dictHandVal = new SortedDictionary<uint, string>();
SortedDictionary<String, long> dictHandDesc = new SortedDictionary<String, long>();
// Current Hand (board and pocket)
uint pocketBoardVal = Hand.Evaluate(pocket | board);
uint pocketBoardType = Hand.HandType(pocketBoardVal);
// Board for special cases...
uint boardVal = Hand.Evaluate(board);
uint boardType = Hand.HandType(boardVal);
// Trips on the board (without using the pocket cards)...
bool tripsOnBoard = (boardType == (uint)HandTypes.Trips && pocketBoardType == (uint)HandTypes.Trips);
string desc = Hand.DescriptionFromMask(pocket | board);
// player has a flush, note the highest non-shared (board) card.
if (pocketBoardType == (uint)HandTypes.Flush)
{
uint topFlushCard = 0U;
// Seperate out by suit
uint sc = (uint)(((pocket | board) >> (CLUB_OFFSET)) & 0x1fffUL);
uint sd = (uint)(((pocket | board) >> (DIAMOND_OFFSET)) & 0x1fffUL);
uint sh = (uint)(((pocket | board) >> (HEART_OFFSET)) & 0x1fffUL);
uint ss = (uint)(((pocket | board) >> (SPADE_OFFSET)) & 0x1fffUL);
if (nBitsTable[sc] >= 5)
topFlushCard = topCardTable[(uint)((pocket >> (CLUB_OFFSET)) & 0x1fffUL)];
else if (nBitsTable[sd] >= 5)
topFlushCard = topCardTable[(uint)((pocket >> (DIAMOND_OFFSET)) & 0x1fffUL)];
else if (nBitsTable[sh] >= 5)
topFlushCard = topCardTable[(uint)((pocket >> (HEART_OFFSET)) & 0x1fffUL)];
else if (nBitsTable[ss] >= 5)
topFlushCard = topCardTable[(uint)((pocket >> (SPADE_OFFSET)) & 0x1fffUL)];
desc += " and top non board flush card " + (ranktbl[topFlushCard]);
}
// Special case trips on the board, we need to look at top pocket kicker.
else if (tripsOnBoard)
{
uint topKicker;
// Seperate out by suit
uint sc = (uint)((pocket >> (CLUB_OFFSET)) & 0x1fffUL);
uint sd = (uint)((pocket >> (DIAMOND_OFFSET)) & 0x1fffUL);
uint sh = (uint)((pocket >> (HEART_OFFSET)) & 0x1fffUL);
uint ss = (uint)((pocket >> (SPADE_OFFSET)) & 0x1fffUL);
uint ranks = sc | sd | sh | ss;
topKicker = topCardTable[ranks];
desc += " and " + (ranktbl[topKicker]) + " for a kicker";
}
// Always add the pocket hand to the sorted lists.
dictHandVal.Add(pocketBoardVal, desc);
dictHandDesc.Add(desc, 1);
// Build a List of unique hands, excluding the pocket cards. As the pocket cards may
// prevent some possible nut hands: Ks 9d - Kc Kh 9h - four of a kind impossible...
foreach (ulong p in Hand.Hands(0UL, board | pocket, 2))
{
hv = Hand.Evaluate(p | board);
if (!dictHandVal.ContainsKey(hv))
{
uint hvType = Hand.HandType(hv);
uint pv = Hand.Evaluate(p);
uint pvType = Hand.HandType(pv);
// Four of a kind but NOT four of a kind on the board (where best kicker counts).
bool hvFourOfAKind = (boardType != (uint)HandTypes.FourOfAKind && hvType == (uint)HandTypes.FourOfAKind);
// Trips using a pair on the board.
bool hvTrips = (hvType == (uint)HandTypes.Trips && pvType != (uint)HandTypes.Pair && boardType != (uint)HandTypes.Trips);
// Trips on the board.
bool hvTripsOnBoard = (boardType == (uint)HandTypes.Trips && hvType == (uint)HandTypes.Trips);
// Get a description of the hand, this will ensure best 5 cards are added only once.
desc = Hand.DescriptionFromMask(p | board);
if (hvFourOfAKind || hvType == (uint)HandTypes.Flush || (hvTrips && pocketBoardType != (uint)HandTypes.Trips) || hvTripsOnBoard)
{
// Flush on the board, note the highest non-shared (board) card and only add this once.
if (hvType == (uint)HandTypes.Flush)
{
uint topFlushCard = 0U;
// Seperate out by suit
uint sc = (uint)(((p | board) >> (CLUB_OFFSET)) & 0x1fffUL);
uint sd = (uint)(((p | board) >> (DIAMOND_OFFSET)) & 0x1fffUL);
uint sh = (uint)(((p | board) >> (HEART_OFFSET)) & 0x1fffUL);
uint ss = (uint)(((p | board) >> (SPADE_OFFSET)) & 0x1fffUL);
if (nBitsTable[sc] >= 5)
topFlushCard = topCardTable[(uint)((p >> (CLUB_OFFSET)) & 0x1fffUL)];
else if (nBitsTable[sd] >= 5)
topFlushCard = topCardTable[(uint)((p >> (DIAMOND_OFFSET)) & 0x1fffUL)];
else if (nBitsTable[sh] >= 5)
topFlushCard = topCardTable[(uint)((p >> (HEART_OFFSET)) & 0x1fffUL)];
else if (nBitsTable[ss] >= 5)
topFlushCard = topCardTable[(uint)((p >> (SPADE_OFFSET)) & 0x1fffUL)];
desc += " and top non board flush card " + (ranktbl[topFlushCard]);
}
// Special case trips on the board, we need to look at top non board kicker.
else if (hvTripsOnBoard)
{
uint topKicker;
// Seperate out by suit
uint sc = (uint)((p >> (CLUB_OFFSET)) & 0x1fffUL);
uint sd = (uint)((p >> (DIAMOND_OFFSET)) & 0x1fffUL);
uint sh = (uint)((p >> (HEART_OFFSET)) & 0x1fffUL);
uint ss = (uint)((p >> (SPADE_OFFSET)) & 0x1fffUL);
uint ranks = sc | sd | sh | ss;
topKicker = topCardTable[ranks];
desc += " and " + (ranktbl[topKicker]) + " for a kicker";
}
if (!dictHandDesc.ContainsKey(desc))
{
dictHandVal.Add(hv, desc);
dictHandDesc.Add(desc, 1);
}
}
// Add everything else...
else
{
dictHandVal.Add(hv, desc);
}
}
}
// Find current mask in the sorted list
long count = dictHandVal.Count - 1;
foreach (uint handval in dictHandVal.Keys)
{
if (handval == pocketBoardVal)
return count;
count--;
}
return -1;
}
|
|
|
|

|
Here are a the test cases that I have used to check the functinality, they are in VB:
Private Sub TestHandDistance()
'# These tests come from Lee Jones Preliminary Chapter Quiz
'# Question 8a
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qs Jc"), Hand.ParseHand("Ad Kh 6s 4h Tc")) = 0, "8a nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("As Ac"), Hand.ParseHand("Ad Kh 6s 4h Tc")) = 1, "8a second best hand error")
'# Question 8b
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ts 8c"), Hand.ParseHand("7h 4s 3d 9h Js")) = 0, "8b nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("5s 6c"), Hand.ParseHand("7h 4s 3d 9h Js")) = 1, "8b second best hand error")
'# Question 8c
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("3s 4c"), Hand.ParseHand("Ac 5s Th 2c 9s")) = 0, "8c nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("As Ah"), Hand.ParseHand("Ac 5s Th 2c 9s")) = 1, "8c second best hand error")
'# Question 8d
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("3h 3s"), Hand.ParseHand("3c Jc Qh 6c 3d")) = 0, "8d nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qs Qd"), Hand.ParseHand("3c Jc Qh 6c 3d")) = 1, "8d second best hand error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Js Jd"), Hand.ParseHand("3c Jc Qh 6c 3d")) = 2, "8d third best hand error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("6s 6d"), Hand.ParseHand("3c Jc Qh 6c 3d")) = 3, "8d fourth best hand error")
'# Question 8e
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("8d 7d"), Hand.ParseHand("6d 9d 9h Kh 5d")) = 0, "8e nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("9s 9c"), Hand.ParseHand("6d 9d 9h Kh 5d")) = 1, "8d second best hand error")
'# Question 8f
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ad 7d"), Hand.ParseHand("Tc 5h Jd Qs Kc")) = 0, "8f nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("9s 9c"), Hand.ParseHand("Tc 5h Jd Qs Kc")) = 1, "8f second best hand error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ks Kd"), Hand.ParseHand("Tc 5h Jd Qs Kc")) = 2, "8f third best hand error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qd Qc"), Hand.ParseHand("Tc 5h Jd Qs Kc")) = 3, "8f fourth best hand error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Js Jc"), Hand.ParseHand("Tc 5h Jd Qs Kc")) = 4, "8f fifth best hand error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ts Td"), Hand.ParseHand("Tc 5h Jd Qs Kc")) = 5, "8f sixth best hand error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("5s 5d"), Hand.ParseHand("Tc 5h Jd Qs Kc")) = 6, "8f seventh best hand error")
'# Question 8g
'# Note 3 queens is the lowest possible hand that can be the nuts when 5 board cards are dealt.
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qh Qc"), Hand.ParseHand("Js 2c Qd 4h 7c")) = 0, "8g nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Jh Jc"), Hand.ParseHand("Js 2c Qd 4h 7c")) = 1, "8g second best hand error")
'# Question 8h
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ah 2h"), Hand.ParseHand("4h 6s 8h Jd 9h")) = 0, "8h nuts error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Kh 2h"), Hand.ParseHand("4h 6s 8h Jd 9h")) = 1, "8h second best hand error")
'# These tests come from the Hendon Mobs Nut test and will test a full board
'http://www.thehendonmob.com/guide/index.php?p=2.3.1
'# Q1
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ks Qs"), Hand.ParseHand("4d 8s 6s Jh 3s")) = 1, "1a hendon hand a error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("As 2s"), Hand.ParseHand("4d 8s 6s Jh 3s")) = 0, "1a hendon hand b error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qs Ts"), Hand.ParseHand("As 2d Js Ac Ks")) = 0, "1b hendon hand a error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ad Ah"), Hand.ParseHand("As 2d Js Ac Ks")) = 1, "1b hendon hand b error")
'# Q2
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qd Qh"), Hand.ParseHand("Qc 6s 4c Jh 3h")) = 2, "2a hendon hand a error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("7c 5c"), Hand.ParseHand("Qc 6s 4c Jh 3h")) = 0, "2a hendon hand b error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qd Jd"), Hand.ParseHand("9d 4c 8s Ts 7h")) = 0, "2b hendon hand a error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Jh Tc"), Hand.ParseHand("9d 4c 8s Ts 7h")) = 1, "2b hendon hand b error")
'# Q3
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ad 2d"), Hand.ParseHand("4c 9s 5d 3s 8h")) = 2, "3a hendon hand a error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("7c 6c"), Hand.ParseHand("4c 9s 5d 3s 8h")) = 0, "3a hendon hand b error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("8c Ad"), Hand.ParseHand("8s 2c 6d Ac 8d")) = 1, "3b hendon hand a error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("As Ah"), Hand.ParseHand("8s 2c 6d Ac 8d")) = 1, "3b hendon hand b error")
'# Special Cases
'# four of a kind on the board.
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ah 2h"), Hand.ParseHand("5h 5s 5d 5c 9h")) = 0, "four of a kind with best kicker as pocket card error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("2c 2h"), Hand.ParseHand("5h 5s 5d 5c Ah")) = 0, "four of a kind with best kicker as board card error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Kh 2h"), Hand.ParseHand("5h 5s 5d 5c 9h")) = 1, "four of a kind with second best kicker as pocket card error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("2c 2h"), Hand.ParseHand("5h 5s 5d 5c 2s")) = 11, "four of a kind with worst (11th) kicker as pocket card error")
'# trips on the board.
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ac Kc"), Hand.ParseHand("7h 7s 7d")) = 13, "trips on board best kickers (without a full house or 4 of a kind) error")
'# Note can't have a 2 high kicker.
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("2c 3c"), Hand.ParseHand("7h 7s 7d")) = 23, "trips on board worst kickers (without a full house or 4 of a kind) error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Kc Tc"), Hand.ParseHand("7h 7s 7d")) = 14, "trips on board kickers K T (without a full house or 4 of a kind) error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("8c 2c"), Hand.ParseHand("7h 7s 7d")) = 19, "trips on board kickers 8 2 (without a full house or 4 of a kind) error")
'# flush on the board.
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ac 2c"), Hand.ParseHand("9c 8c 3c")) = 0, "nut flush error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Kd 2d"), Hand.ParseHand("9d 8d 3d")) = 1, "second best flush error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("9h 2h"), Hand.ParseHand("7h 8h 3h, 4h, Td")) = 5, "fifth best flush error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ks 2s"), Hand.ParseHand("As 8s 3s")) = 0, "nut flush top card on board error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Qs Js"), Hand.ParseHand("As 8s 3s")) = 1, "second best flush top card on board error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("2h 3h"), Hand.ParseHand("Ah Kh 4h")) = 7, "seventh best flush top card on board error")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("8d 7d"), Hand.ParseHand("Qd 3d 2d")) = 5, "fifth best flush top card on board error")
'# 2 pair
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Ac Ks"), Hand.ParseHand("Ad Kc Ts")) = 4, "2 pair error 1")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Js Th"), Hand.ParseHand("Jc Td 2s")) = 3, "2 pair error 2")
Debug.Assert(Hand.HandDistanceDiscounted(Hand.ParseHand("Js 7c"), Hand.ParseHand("7s 3d 3h")) = 14, "2 pair error 2")
End Sub
|
|
|
|

|
Hello CodeProject community.
Because I can't find out how to contact Keith Rule directly I now choose this way to either get in contact with him or maybe get some help by people who are willing to help me out.
I am interested in Keith Rules software tool called "MultiOddsApp".
I would like to practise my Pokergame with it.
In the first moment I thought, that Keith tools are Windows executable programs.
I am wrong, am I?
I need to run some sort of Coding program, maybe Visual Basic?
I already downloaded it and tried to open Keith Poker tool in it.
But I got a few error messages and I didn't bring it to work at all.
So maybe one here is willing to explain to me how I can run "MultiOddsApp" though I have never got contact with Visual Basic before?
I would be really happy about your help.
Thank you very much.
Sorry, english is not my original language.
Many greetings
|
|
|
|

|
Timo Michaelis wrote: I would like to practise my Pokergame with it.
In the first moment I thought, that Keith tools are Windows executable programs.
I am wrong, am I?
I'm not a poker expert nor am I trying to produce a general tool for poker enthusiast. I'm a programmer that found Poker analysis to be an interesting programming challenge.
Codeproject is primarily a site for programmers. The download associated with this article is the source for the project rather than the binaries for that reason. The MultiOddsApp is intended to be an example of how to use the underlying library.
The easiest way to get a binary would be to download Visual C# 2008 Express Edition (http://www.microsoft.com/exPress/download/[^])
You should be able to load, compile and then execute the application your interested in.
Good Luck,
Keith Rule
|
|
|
|

|
pleas help me....
I want fill color between two curves and between one curve to Xaxis in the chart on the zedgraph control.what I do? thanks ....
modified on Sunday, July 12, 2009 8:07 AM
|
|
|
|

|
In some contexts, especially when an opponent's hand can be guessed at, it's possible for an improved kicker to be an "out" (yielding a tie on a hand which would otherwise be a loss). For example, player holds A2, opponent is believed to hold Ax (based upon pre-flop betting), and the flop comes AKK rainbow.
If the opponent's other card is a three through queen, you have a 2 as an out to win, and any card higher than the opponent's card as an out to tie (e.g. if the opponent holds A6, then after the flop your AAKK2 would lose to AAKK6, but if a seven comes up both you and the opponent would hold AAKK7; an ace would leave you both holding AAAKK, and a king would leave you both holding KKKAA).
Obviously one will seldom know perfectly what cards an opponent has (unless cards are being shown all-in, in which case you can't do anything with the information) but one can frequently make an educated guess. While one must be careful to consider implied as well as actual pot odds in situations where one is likely to at best tie, I would still consider it very useful to know what outs exist that would give the player a tie (in one on-line game, I held a crummy hand in the Big Blind, everything was checked through to the river, and the board came down with a four of a kind and an ace kicker; my hand was no better than the board, but I'd still say the board's s four-of-a-kind counted as an out).
Incidentally, it's possible for a board card to "improve" one's hand and yet make it far worse. For example, holding 22 with a flop of 233, having another 3 come up on the turn would likely make one's hand somewhat worse (it would lose to any other pocket pair); if a fourth 3 comes up on the river, the pocket deuces would go from very good (only beaten by three exact holdings) to completely worthless (losing to any other possible hand). The third or fourth 3 in that situation should not be considered an "out" for the person with the pocket deuces. Instead, they would transform the winning 22233 into a dubious 33322 or a losing 33332.
BTW, I haven't seen a lot of poker games, the ones I've played give bulky but incomplete textual descriptions of hands (e.g. "three of a kind sixes with a nine kicker", or "flush, jack high"), when it would be more concise and more informative to say "three of a kind 66694" or "flush J9742s". I wonder why they don't give something more like the latter?
|
|
|
|

|
Is there support for "weights" in your classes (as described by davidson master thesis)?
|
|
|
|

|
Hi Keith,
Thank you for posting these invaluable tools for all to use, it certainly looks like you have spent a large amount of time writing and perfecting these libraries.
I am an avid online player (a poor one unfortunately), and what you might diplomatically call an "enthusiastic" C# developer. The reason I came across your page on code project is I have recently started writing a poker-related program, albeit not in the traditional sense - i.e. neither an odds calculator nor a bot. What I have in mind involves the analysis of played hands, as my background is primarily in database development and business intelligence. I would be very interested to hear your feedback on some of my ideas, if you have the time of course. Is it possible to email you directly?
Many thanks,
Leo
|
|
|
|

|
Dear Keith,
your code is definitely brilliant and very useful. Many thanks for that.
I work with it quite a lot and I found an issue about the query language and the parser:
ulong[] List = PocketHands.Query("AK") returns a list of 12 hands, all of them being offsuit.
So, this line of code produces the same result as ulong[] List = PocketHands.Query("AKo").
It should return a list of 16 hands (offsuit and suited), no?
Since I have absolutely no knowledge of Lex and Yacc, I really have no idea to fix this issue.
Thank you in advance for your help
And again many many thanks for providing this code
|
|
|
|

|
You could just use (AKs | AKo) for the desired hands.
|
|
|
|

|
This behavior is intended.
AK should only select AKo and not to AKo + AKs.
|
|
|
|

|
I've been doing some range calculations feeding ulong[]-arrays into RandomHand, and it seems that the last element of the array is never chosen. I think this is because rand.Next(int maxValue) uses an exclusive upper bound. Hmm, poor explanation, I'll show the code (from HandItorator.cs):
static public ulong RandomHand(Random rand, ulong[] list, ulong dead, int ncards)
{
ulong mask = 0UL;
do
{
mask = list[rand.Next(list.Length - 1)]; } while ((mask & dead) != 0);
return RandomHand(rand, mask, dead, ncards);
}
If I replace "list.Length -1" with just "list.Length" it seems to work as intended.
|
|
|
|

|
I did this change and performed a lot of tests & comparisons with other odds calculators and you are right.
Thank you for the fix
Any idea about my query issue?
|
|
|
|

|
Anybody knows if this bug is fixed in the current version? If not: Is it only in RandomHand with the specified arguments or is it in all RandomHand-methods?
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Using C# to do sophisticated analysis of Texas Holdem
| Type | Article |
| Licence | GPL3 |
| First Posted | 7 Jun 2007 |
| Views | 122,817 |
| Downloads | 1,738 |
| Bookmarked | 110 times |
|
|