/// Computes an index for two hole cards, only accounting for rank and /// suited-ness. The index is computed as follows: /// 23s, 23o, 24s, 24o, ..., 2As, 2Ao /// 34s, 34o, 35s, 35o, ..., 3As, 3Ao /// ... /// KAs, KAo /// 22, 33, ..., AA /// There are in total 2*(12+11+...+1)+13=169 combinations. /// This can also be viewed as drawing two cards (a,b) from 1..13 randomly. /// If a = b, this maps to a pair (off-suit); if a < b, this maps to off-suit; /// if a > b, this maps to same-suit. int compute_hole_index(const Hand &hand) { Card cards[2]; hand.GetCards(cards); int r1 = cards[0].rank, r2 = cards[1].rank; if (r1 > r2) // make sure r1 <= r2 std::swap(r1, r2); if (cards[0].suit == cards[1].suit) // same-suit return r2 * 13 + r1; else return r1 * 13 + r2; }
LRESULT CALLBACK StandButtonProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { if (msg == WM_LBUTTONDOWN) { GameEngine* gameEngine = GameEngine::getInstance(); User* user = gameEngine->getUser(); Table* table = gameEngine->getTable(); table->setState(TABLE_STATE_STANDING); Hand* dealerHand = table->getDealerHand(); Hand* playerHand = table->getPlayerHand(); // // Flip over the first card. // dealerHand->GetCards()->at(0)->setFacedown(false); PlaySound(L"sound-flipcard.wav", NULL, SND_FILENAME | SND_ASYNC); RedrawWindow(gameEngine->getHWnd(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); Sleep(500); // // See if we need additional cards. // while (true) { std::vector<int>* vals = dealerHand->GetValues(); bool done = false; for (int i = 0; i < vals->size(); i++) { // Dealer must stop taking cards // if he has a value of 17 or higher. if (vals->at(i) >= 17) { done = true; break; } } if (done) { break; } PlaySound(L"sound-flipcard.wav", NULL, SND_FILENAME | SND_ASYNC); dealerHand->dealCard(false); RedrawWindow(gameEngine->getHWnd(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); Sleep(500); } // // Determine winner. Update balance amounts. // // table->setState(TABLE_STATE_READY); std::vector<int>* dealerValues = dealerHand->GetValues(); std::vector<int>* playerValues = playerHand->GetValues(); int dealerFinal = 0; int playerFinal = 0; for (int i = 0; i < dealerValues->size(); i++) { if (dealerValues->at(i) > dealerFinal && dealerValues->at(i) < 22) { dealerFinal = dealerValues->at(i); } } for (int i = 0; i < playerValues->size(); i++) { if (playerValues->at(i) > playerFinal && playerValues->at(i) < 22) { playerFinal = playerValues->at(i); } } table->setState(TABLE_STATE_FINISHED); // If values are same, this is a push. if (dealerFinal == playerFinal) { updateTextarea(hStaticTableMiddleMessage, "Push"); // Return player's bet money. int bet = playerHand->getBetAmount(); user->setBalance(user->getBalance() + bet); } else if (dealerFinal < playerFinal) { // Player wins, return bet and winning. updateTextarea(hStaticTableMiddleMessage, "Player Wins!"); int bet = playerHand->getBetAmount(); user->setBalance(user->getBalance() + (bet*2) ); } else if (dealerFinal > playerFinal) { // No need to update cash. Has already been deducted // at time of bet. Update the middle message area. updateTextarea(hStaticTableMiddleMessage, "Dealer Wins."); } RedrawWindow(gameEngine->getHWnd(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } return CallWindowProc(oldStandButtonProc, hwnd, msg, wp, lp); }