The Start
In the short span of time from June 13 to September 22, 2001, Reel Deal Poker Challenge went from a concept to a gold master. Some preliminary artwork, concept art and minimal documentation were available at the start. The game was desinged for Phantom EFX, a small publisher and developer whose strength is in their superb graphics and audio (they have an in-house sound studio).
The Concept
Phantom EFX's first title was Reel Deal Slots and Video Poker,
and they desired to continue in the gambling genre with a poker game.
Reel Deal Poker Challenge presents a variety of poker games inside
an elegant Poker Palace. There are three floors of play where the opponents
play better on each level and the stakes get higher. Each floor has a
poker room for regular play against four animated, talking players or
eight basic players (a standard poker view) and a tournament room where
four players play one variation for 20 hands and the player with the most
money is the winner. A cashier area to register players, get more cash
when your wallet is looking empty and see your statistics. There is a
slot room with a few slot machines to promote the previous title, and
an elevator allowing players access to the other floors when they have
earned enough " reputation points" by playing in tournaments. One of the
popular concepts used in the first title was a prize room where players
win valuable prizes when they do well. In Poker Challenge, when
a player wins certain tournaments, they win a valuable prize. The prizes
are unknown to the player and collecting all of them is a secondary goal
in the game.
The goal of the game is to earn enough "reputation points" and money to challenge to World's Best Poker player in a winner take all $2.5 Million game.
![]() |
![]() |
![]() |
![]() |
||
![]() |
Reel Deal Poker Challenge four player mode. |
The Plan
A good poker engine takes time to develop. From 1993 to 1995, I had been
director of development at Villa Crespo Software, then the premier gambling
entertainment software company with titles like Stanford Wong's Video
Poker, Amarillo Slim's Dealer's Choice, The Gold Sheet Football Analyzer
and Dr. Thorp's Blackjack. For Poker Challenge, we licensed
a poker engine from one of the developers I had worked with at VCS. The
next issue was using DirectX 8.0, which had recently been released. For
artwork, the easiest format to work with was BMP. I tried using the PNG
format, but the time needed to write and properly implement the routines
was not available. Sound was to initially be outputted via the "play"
function, with Direct Sound to be implemented later.
The Eye
Openers
The DirectX sample code for Direct Draw and Direct Input uses MFC and
Dialog Boxes which, when they compiled cleanly, didn't relate to what
I needed. MFC and window/dialog boxes were not used in this project. One
issue that came up was that in Direct Draw full screen, exclusive mode,
debugging became impossible except by using Message Boxes. To debug properly,
the following code was used frequently by commenting and uncommenting
the code below.
Note: include Ddutil.h and Ddutil.cpp (provided in DirectX8.0)
void
InitializeGraphics(HWND hWnd)
{
RECT
qrect={0,0,800,600};
if(!hWnd)
{
MessageBox(0,"Your
hWndNULL",TEXT("Poker2000"),MB_ICONERROR| MB_OK);
exit(0);
}
//************** USE THIS IN FINAL NON-WINDOW VERSION
if(FAILED(DXscreen->CreateFullScreenDisplay(hWnd,800,600,32)))
{
if(FAILED(DXscreen->CreateFullScreenDisplay(hWnd,800,600,24)))
{
if(FAILED(DXscreen->CreateFullScreenDisplay(hWnd,800,600,16)))
{
MessageBox(hWnd,"Unable
to find a compatible display mode.
The program will now exit.",
TEXT("Poker2000"),
MB_ICONERROR | MB_OK);
exit(0);
}
}
}
//************** USE THIS TO DEBUG (WINDOW VERSION)
// if
(FAILED(DXscreen->CreateWindowedDisplay(hWnd, 800, 600)))
// exit(0);
}-
The poker engine was written in MS Visual BASIC and played several poker variations (Draw Poker No Openers and Jacks or Better to Open, Five Card Stud, Seven Card Stud, Chicago Hi (Seven Card Stud with the High Spade in the Hole/ down cards the second winner), and Hold 'Em. The first issue was to convert the BASIC code to C++ code.
The poker AI was primarily in one VB module, but the variables were defined and used in numerous modules. After rewriting the original code several items had to be fixed. The engine did not account for equal poker hands, as when four players each have a Royal Flush. The engine designer's reaction was it would never happen. Well, what about a straight flush or a flush with the same ranked cards? This issue was fixed by allowing a suit order (Spades, Hearts, Diamonds then Clubs) and allowing multiple players to be the winner. The original AI also didn't look at other tie breaking issues. The new version resolved tiebreak by having two components of the "handresult" which comprised of Result Type and a Long Tie Factor. The Result Type is a number comprised of a best hand number (pair is 20, two pair is 40, to a straight flush as 160 and a royal flush as 180) plus the rank of the key card (2 through Ace or 14). The Long Tie Factor is a long (4 bytes) where each card's rank in Importance order is stored. A hand of three kings, two aces, a 3 and a 5 is stored as {13, 13, 13, 14, 14, 5, 3}. If two players have the same Result Type such as a pair of kings each (value 33) then the Long Tie Factor number is used to break the apparent tie. Reel Deal Poker Challenge poker added two variations, Chicago Low (the opposite of Chicago Hi where the lowest spade in the down cards shares as winner) and Omaha (a very popular poker variation). In games like Texas Hold 'Em and Omaha, the best possible hand must be determined. Texas Hold 'Em is a poker game where each player is dealt two cards down and five cards are dealt as community cards (used by all players). Omaha is similar to Hold 'Em except each player is dealt four cards down and five cards are dealt as community cards. In Omaha, the final hand is the best hand comprised of two of the four down cards and three of the five community cards. In Texas, the player uses their two down cards and three of the five community cards to make their best hand. The AI was programmed to analyze and determine a player's best hand.
![]() |
![]() |
![]() |
![]() |
||
![]() |
Reel Deal Poker Challenge eight player mode. |
Know
the Rules
As a programmer, we often give tasks to the computer rather than let events
happen naturally. In Draw Poker: Jacks or Better to Open variation, the
code was originally written to allow only a player having a hand of a
pair of Jacks or Better to open betting and continue the hand. If no player
had a pair of Jacks or better, the hand was redealt. The program decided
the course of play not the players. This method was incorrect. The final
version gives each player the choice to "check" (pass), "fold" or "bet."
If all players "check," the hand is redealt. If a player "bets" and they
do not have the required hand, the "check" option is substituted. In Five
Card Stud, Seven Card Stud and Chicago, the first bet is a forced bet
for the player with the lowest up card. In Hold 'Em and Omaha, the player
to the dealer's left must make a forced bet called the "blind bet. " The
ace is always the high card except the Ace of Spades in Chicago Lo where,
according to several websites on poker, the ace can be the lowest hole
(down) card. This information changed the Chicago Lo AI where the Two
of Spades was the lowest card.
Sound
and Animation
Direct Sound replaced the "Play" function so that multiple audio files could
be outputted simultaneously. In Poker Challenge, each room had background
(ambient) music playing and the poker rooms had three to four large background
music files. While the ambient music was playing, one or two sound effects
could be triggered. In the four player poker room, any of the three animated
characters will chat with the players, therefore a chat audio file had to
be in memory. The following code (using DSutil.cpp,
DSutil.h and DSound.h)
was used to initialize Direct Sound, the needed sound buffers (four background
sound buffers, two sound effect buffers and one character chat buffer) and
a sample of how the sounds were played.
///------ DirectSound Object and Buffers ------//
CSoundManager* g_pSoundManager = NULL;
CSound* g_pBackSound[4] = {NULL,NULL,NULL,NULL};
CSound* g_pSFX1Sound = NULL;
CSound* g_pSFX2Sound = NULL;
CSound* g_pChatSound = NULL;
void InitDSound(HWND hWnd)
{
HRESULT hr;
// Create a static IDirectSound in the CSound class.
// Set coop level to DSSCL_PRIORITY or DSSCL_NORMAL, and set primary buffer
// format to stereo, 22kHz and 16-bit output.
g_pSoundManager = new CSoundManager();
If( FAILED( hr = g_pSoundManager->Initialize( hWnd, DSSCL_NORMAL, 4, 22050, 16 ) ) ){
MessageBox( hWnd, "Error initializing DirectSound. Program will now exit.",
"DirectSound Init", MB_OK | MB_ICONERROR );
exit(1);
}
}
// CREATE THE SOUND EFFECTS #1 AUDIO BUFFER
// flag==1 to test if playing, else overwrite new SFX1 Sound
int NewSFX1Sound(TCHAR *strFileName,int flag) {
HRESULT hr;
if(g_pSFX1Sound){
// testing if sound is playing
if((flag==1) && g_pSFX1Sound->IsSoundPlaying())return(1); g_pSFX1Sound->Stop();
}
if(strlen(strFileName)>0){
SAFE_DELETE(g_pSFX1Sound);
// Sound if existed has stopped and has been deleted
hr = g_pSoundManager->Create( &g_pSFX1Sound, strFileName, 0, GUID_NULL, 1 );
}
return(0);
}
// PLAY THE SOUND EFFECTS #1 AUDIO BUFFER
void PlaySFX1()
{
HRESULT hr;
DWORD dwFlags = 0L; // set to DSBPLAY_LOOPING if looping needed g_pSFX1Sound ->Stop(); g_pSFX1Sound ->Reset(); Hr = g_pSFX1Sound->Play( 0, dwFlags );
}
In the four player poker room, the the opponents are highly animated characters designed to chat at 15 frames per second. Each character has seven different poses and each pose has five different eye frames and seven different mouth frames. The first time a player enters the four player poker room, all of the required graphics (poses, mouth and eye frames) are loaded into memory as surfaces. Using fast blitting from surface to screen and a 67 millisecond timer (1/15 of a second), the animations mimicked the chat audio files. Every chat line for each character was broken into a 1/15 of a second "pose, mouth, eye" setting which became the structure used to describe character animation. A zero for the eye or mouth position meant to use the pose's eye or mouth. The audio lines were then mapped to various response categories like "raise", "fold," and "call."
// ANIMATION: POSE, MOUTH, EYE FRAMES
char Pchar_buff[10][1000][3]={
//YVETTE: "Wow,good hand"
{{1, 3, 0},{1, 7, 0},{1, 7, 5},{1, 1, 5},{1, 1, 5},{1, 1, 5},{1, 1, 5},
{1, 1, 5},{1, 1, 5},{1, 6, 5},{1, 7, 5},{1, 7, 5},{1, 7, 0},
{1, 3, 0},{1, 3, 0},{1, 3, 0},{2,10, 0},{2, 6, 5},{2, 6, 5},{2,10, 5},
{2, 3, 5},{2,10, 5},{2, 1, 5},{2, 1, 5},{2, 1, 5},{2, 1, 5},
// CORRESPONDING AUDIO FILES
char CharAudio[10][30][30]={
{ // Yvette
{"\\Yvette\\GOODHAND.WAV"}, {"\\Yvette\\likethat2.WAV"},void LoadTalkerPic(int pl, int st) // pl is player, st is start line
{
int stoffset=0,i,xpose,xmouth,xeyes;
BOOL flag; DWORD startTime=0;
DWORD Msec7=67; // 67 ms (67/1000) is close to 1/15 of a second
RECT prc;
CurPose= 9; // force a change
CurMouth= 0;
CurEyes= 0;
// Locate the line to have character say
for(i=0;i st;i++)
Stoffset+= Pchar_offset[pl][i];
// Have character perform 1/15 second animation: pose, mouth and eyes
for(i=0;i>Pchar_offset[pl][st];i++){
// Get from the above chat structure the pose
xpose= (int)Pchar_buff[pl][stoffset+i][0];
Xmouth=0;
xeyes= 0;
// Get from the above chat structure the mouth frame if((int)Pchar_buff[pl][stoffset+i][1]>0)
xmouth= (int)Pchar_buff[pl][stoffset+i][1]+5;
// Get from the above chat structure the eye frame if((int)Pchar_buff[pl][stoffset+i][2]>0)
xeyes= (int)Pchar_buff[pl][stoffset+i][2];
// Make the character talk for 1/15 of a second MakeCharTalk(0,pl,xpose,xeyes,xmouth);
// Start the audio after the first frame is displayed
if(i==0){
if(strlen(CharAudio[pl][st])>0){
strcpy(WAVfname,".\\WAV"); strcat(WAVfname,CharAudio[pl][st]);
NewChatSound(WAVfname,0);
PlayChat();
}
} // i==0
} // i loop
}
Addictive
Gaming Techniques
Poker Challenge has several interesting gaming concepts that draw the
player deeper into the game play. Players start off with $2,500 and no
reputation points on the first level of the Poker Palace. They can enter
the tournament or non-tournament poker room, view the prize room (initially
it's empty), see the elevator (initially blocked by a bouncer), play slots
and view their statistics. Curiosity and fun game play will propel the
player to play in the non-tournament poker room to raise enough money
to enter the tournaments. Through winning at tournaments, player earns
reputation points, valuable prizes and money. As they increase their reputation
points, the other floors open up where the opponents play tougher and
high stake games are available. Eventually, through game play and word
of mouth, players will learn about a secret poker game for $2.5 million
and the World Championship which is only achievable through winning enough
reputation points from the third floor of the Poker Palace. As the players
win tournaments, the prize room will fill up. Until then, players will
wonder what valuable prizes go in the prize room slots. There are also
a few hidden "Easter eggs" for players to discover. The statistics tables
are also updated as the player enters each poker room. In the non-tournament
rooms the player can decide which poker variation to play. While in a
tournament room, only one variation of poker is played for the 20 hands.
The humorous and well-animated 4-player mode is very addictive and immerses
the player into the poker atmosphere. The slot room is an extra feature
that promotes Phantom EFX's first title. Hopefully this winter's holiday
season, many players will enjoy what I did this summer.
______________________________________________________