title: BlackJack Algorithm
body: <p>What is the general alogirthm for a BlackJack game ?
  I'm writing one in c++ and end up having WAY too many if statements which ruin the whole thing.</p>
  
  <p>The project is a win32 GUI application, and Im posting the message loop as well as the part of the program that checks the game's status
  Posting the complete code will make it humongous, so here are the links to all the files:
  <a href="http://dl.dropbox.com/u/35856163/Code.zip" rel="nofollow">Full Source Code</a></p>
  
  <h2>Message Loop</h2>
  
  <pre><code>LRESULT CALLBACK WndProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ){
    switch(Msg)
    {
    case WM_PAINT:
    {
        PAINTSTRUCT PS;
        HDC hDC = BeginPaint(hWnd, &amp;PS);
        You.Draw(hDC);
        Dealer.Draw(hDC);
        EndPaint(hWnd, &amp;PS);
        if(Bet.Enabled){
            Bet.GetFocus();
            Bet.Select(0,Bet.Length());
        }
    }
    return 0;
    case WM_CTLCOLORSTATIC:
    {
        SetBkMode((HDC)wParam, TRANSPARENT);
    }
    return (INT_PTR)(HBRUSH)GetStockObject(NULL_BRUSH);
    case WM_CREATE:
    {
        //Create edit control
        Bet.Create(hWnd, 10, 550, 100, 25, "0");
        //Create labels
        char Buffer[30];
        sprintf(Buffer, "%d", You.HandValue());
        BetLabel.Create(hWnd, 10, 500, 100, 40, "Enter Bet Amount");
        GameControls.Create(hWnd, 10, 375, 100, 40, "Game Controls");
        PlayerLabels.Create(hWnd, 10, 10, 100, 20, "You:");
        PlayerLabels.Create(hWnd, 10, 150, 100, 20, "Dealer:");
        HandValueLabel.Create(hWnd, (int)You.x[You.cards] + 85, (int)You.y[You.cards] + 25, 100, 20, Buffer);
        YourMoney.Create(hWnd, 125, 500, 100, 40, "Your money: ");
        sprintf(Buffer, "%d", You.money);
        MoneyValue.Create(hWnd, 125, 525, 100, 40, Buffer);
        //Create buttons
        Ok.Create(hWnd, 10, 600, 100, 50, "Ok");
        Hit.Create(hWnd, 10, 425, 100, 50, "Hit");
        Stand.Create(hWnd, 120, 425, 100, 50, "Stand");
        //Select Text
        Bet.Select(0,3);
    }
    return 0;
    case WM_CLOSE:
      exit(0);
      break;
    case WM_COMMAND:
    {
        switch(HIWORD(wParam))
        {
        case BN_CLICKED:
        {
            switch(LOWORD(wParam))
            {
            case ID_OK:
            {
                //Place bet
                int bet = 0;
                bet = StringToNumber(Bet.Text());
                You.money -= bet;
                char Buffer[30];
                sprintf(Buffer, "%d", You.money);
                MoneyValue.SetText(Buffer);
                //Update the window
                InvalidateRect(hWnd, 0, TRUE);
                You.Bet = YES;
                Ok.Disable();
                Bet.Disable();
                You.DealCard();
                You.DealCard();
                Dealer.DealCard();
                Dealer.DealCard();
                You.win = false;
                You.bust = false;
                You.playing = YES;
                Dealer.win = NO;
                Dealer.bust = NO;
                Dealer.playing = YES;
            }
            break;
            case ID_HIT:
            {
               if(You.HandValue() &lt; 21 &amp;&amp; You.playing &amp;&amp; !You.bust){
                   //Deal a card to the player, if he hasn't won or lost
                   You.DealCard();
               }
               if((Dealer.HandValue() &lt;= 17 || Dealer.HandValue() &lt; You.HandValue()) &amp;&amp; Dealer.playing)
                         {
                           Dealer.DealCard();
                         }
              //Update Hand Value
              char Buffer[30];
              sprintf(Buffer, "%d", You.HandValue());
              HandValueLabel.SetText(Buffer);
              InvalidateRect(hWnd,0,TRUE);
              MoveWindow(HandValueLabel.Handle, (int)You.x[You.cards] + 80, (int)You.y[You.cards] + 25, 100, 20, TRUE);
              RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT);
            }
            break;
            case ID_STAND:
                if(Hit.Enabled){
                    //Don't deal more cards
                    Hit.Disable();
                    You.playing = false;
                }
                if((Dealer.HandValue() &lt;= 17 || Dealer.HandValue() &lt; You.HandValue()) &amp;&amp; Dealer.playing){
                    //Deal a card to the dealer
                    Dealer.DealCard();
                }
            }
  </code></pre>
  
  <h2>StatusChecker</h2>
  
  <pre><code>void ProcessStatus(HWND hWnd){
       if(Dealer.HandValue() &gt; 17){
            if(Dealer.HandValue() &gt; You.HandValue() &amp;&amp; Dealer.playing){
                Dealer.playing = false;
              }
            else if(!You.playing &amp;&amp; Dealer.HandValue() &lt;= You.HandValue() &amp;&amp; Dealer.playing){
                Dealer.DealCard();
              }
          }
        else if(Dealer.HandValue() &lt;= 17 &amp;&amp; Dealer.HandValue() &lt;= You.HandValue() &amp;&amp; !You.playing &amp;&amp; Dealer.playing){
            Dealer.DealCard();
          }
        if(EvaluateStatus() != 0){
            status = OVER;
          }
       if(EvaluateStatus() == -1){
           switch(MessageBoxA(hWnd, "You Lost! \n Keep Playing ?", "You Lost!", MB_YESNO | MB_ICONQUESTION))
           {
           case IDYES:
               Reset();
               break;
           case IDNO:
               exit(0);
               break;
           }
       }
       else if(EvaluateStatus() == 1){
           switch(MessageBoxA(hWnd, "You Won! \n Keep Playing ?", "You Won!", MB_YESNO | MB_ICONQUESTION))
           {
           case IDYES:
               Reset();
               break;
           case IDNO:
               exit(0);
               break;
           }
       }
      }
  int EvaluateStatus()
  {
    if(You.HandValue() &gt; 21 &amp;&amp; You.playing)
      {
        You.bust = true;
        Dealer.win = true;
        You.playing = NO;
        return -1;
      }
    if(You.HandValue() == 21)
      {
        You.win = true;
        return 1;
      }
    if(Dealer.HandValue() &gt; 21)
      {
        Dealer.bust = true;
        You.win = true;
        return 1;
      }
    if(Dealer.HandValue() == 21)
      {
        Dealer.win = true;
        return -1;
      }
    if(!You.playing &amp;&amp; Dealer.HandValue() &gt; You.HandValue() &amp;&amp;!Dealer.bust)
      {
        Dealer.win = true;
        return -1;
      }
    if(You.HandValue() &gt; Dealer.HandValue() &amp;&amp; (!You.playing &amp;&amp; (!Dealer.playing || Dealer.bust)))
      {
        You.win = true;
        return 1;
      }
    if(You.HandValue() == Dealer.HandValue() &amp;&amp; (!You.playing || !Dealer.playing))
      {
        You.win = true;
        return 1;
      }
  </code></pre>