// // GetMaxCardsInSuit() // // returns the maximum number of cards a player currently holds in a suit // int CPlayEngine::GetMaxCardsInSuit(int nPlayer, int nSuit) const { VERIFY((nPlayer >= 0) && (nPlayer <= 3) && ISSUIT(nSuit)); // see if the hand's cards have all been identified CGuessedSuitHoldings& suit = m_ppGuessedHands[nPlayer]->GetSuit(nSuit); if (suit.AreAllCardsIdentified()) return suit.GetNumMaxRemainingCards(); // else see if the player is dummy & his cards are visible if (nPlayer == pDOC->GetDummyPosition() && pDOC->IsDummyExposed()) { CHandHoldings& hand = pDOC->GetDummyPlayer()->GetHand(); return hand.GetNumCardsInSuit(nSuit); } // else calc // initial max is 13 cards in a suit int nMax = 13; // deduct the # of our original suit cards nMax -= m_pHand->GetInitialHand().GetNumCardsOfSuit(nSuit); // deduct dummy's suit holdings, if visible CPlayer* pDummy = pDOC->GetDummyPlayer(); if (pDummy->AreCardsExposed()) { CCardHoldings& initialHand = pDummy->GetHand().GetInitialHand(); nMax -= initialHand.GetNumCardsOfSuit(nSuit); } // and deduct the cards that have been played by the other two players int nDummyPos = pDummy->GetPosition(); int nOurPos = m_pPlayer->GetPosition(); for(int nPos=0;nPos<4;nPos++) { if ((nPos == nDummyPos) || (nPos == nOurPos)) continue; nMax -= GetNumCardsPlayedInSuit(nPos, nSuit); } // if the max == 0, all the player's suit cards have been identified if (nMax == 0) { // update status suit.MarkAllCardsIdentified(); // and update counts suit.SetNumOriginalCards(nMax + m_ppGuessedHands[nPlayer]->GetSuit(nSuit).GetNumCardsPlayed()); suit.SetNumRemainingCards(nMax); suit.SetNumLikelyCards(nMax); suit.SetNumMinRemainingCards(nMax); suit.SetNumMaxRemainingCards(nMax); } // and we're done return nMax; }
// // GetOutstandingCards() // // determine the list of outstanding cards in this suit // outstanding means all the cards that are not in our own hand // (or dummy), _and_ which have not been played // int CPlayEngine::GetOutstandingCards(int nSuit, CCardList& cardList, bool bCountDummy) const { VERIFY(ISSUIT(nSuit)); // first fill the list with all the cards in the suit for(int i=2;i<=ACE;i++) cardList << deck.GetSortedCard(MAKEDECKVALUE(nSuit,i)); cardList.Sort(); // then remove the cards remaining in our own hand CSuitHoldings& suit = m_pHand->GetSuit(nSuit); for(i=0;i<suit.GetNumCards();i++) cardList.Remove(suit[i]); // then remove the cards in dummy from the list // but only if indicated, _and_ dummy's cards are visible if (!bCountDummy) // i.e, don't count dummy's cards as outstanding { CPlayer* pDummy = pDOC->GetDummyPlayer(); if (pDummy->AreCardsExposed() && (GetPlayerPosition() != pDOC->GetDummyPosition())) { CSuitHoldings& dummySuit = pDummy->GetHand().GetSuit(nSuit); for(int i=0;i<dummySuit.GetNumCards();i++) cardList.Remove(dummySuit[i]); } } // then search the list of guessed cards for cards in this suit // that have already been played, and remove them from the list int nOurPos = m_pPlayer->GetPosition(); for(int nPlayer=0;nPlayer<4;nPlayer++) { CGuessedSuitHoldings& suit = m_ppGuessedHands[nPlayer]->GetSuit(nSuit); for(int j=0;j<suit.GetNumDefiniteCards();j++) { if (suit[j]->WasPlayed()) cardList.Remove(deck.GetSortedCard(suit[j]->GetDeckValue())); } } // now we have only the outstanding cards in the suit cardList.Sort(); return cardList.GetNumCards(); }
// // AdjustCardCountFromPlay() // // adjust card count and analysis after a card is played // void CPlayEngine::AdjustCardCountFromPlay(int nPos, CCard* pCard) { // default code // if (nPos != m_pPlayer->GetPosition()) // { // note the card that was played CGuessedHandHoldings* pPlayerHoldings = m_ppGuessedHands[nPos]; CGuessedCard* pGuessedCard = new CGuessedCard(pCard, // card FALSE, // no longer outstanding nPos, // location 1.0); // known with certainty *pPlayerHoldings << pGuessedCard; // see if the player showed out CPlayerStatusDialog& status = *m_pStatusDlg; CCard* pCardLed = pDOC->GetCurrentTrickCardByOrder(0); if (pCard) { int nSuitLed = pCardLed->GetSuit(); ASSERT(nSuitLed != NONE); CGuessedSuitHoldings& suit = pPlayerHoldings->GetSuit(nSuitLed); if ((pCard->GetSuit() != nSuitLed) && (!suit.IsSuitShownOut())) { status << "4RCP10! " & PositionToString(nPos) & " shows out of " & STS(nSuitLed) & ".\n"; suit.MarkSuitShownOut(); if (pPlayerHoldings->GetNumSuitsFullyIdentified() > 1) { // multiple suits identified status << "4RCP1A! " & PositionToString(nPos) & " is now known to have started with "; int numTotalIdentifiedSuits = pPlayerHoldings->GetNumSuitsFullyIdentified(); int numIdentifiedSuits = 0; int numTotalIdentifiedCards = 0; int numTotalOriginalCards = 0; int nIdentifiedSuits[4]; for(int i=0;i<4;i++) { if (pPlayerHoldings->GetSuit(i).AreAllCardsIdentified()) { CGuessedSuitHoldings& currSuit = pPlayerHoldings->GetSuit(i); status < ((numIdentifiedSuits > 0)? " and " : " ") & currSuit.GetNumOriginalCards() & " " & ((suit.GetNumOriginalCards() > 1)? STS(i) : STSS(i)); nIdentifiedSuits[numIdentifiedSuits] = i; numIdentifiedSuits++; numTotalIdentifiedCards += currSuit.GetNumDefiniteCards(); numTotalOriginalCards += currSuit.GetNumOriginalCards(); } } status < ".\n"; // if the number of cards is known in 3 suits, the orignal // and current length of the 4th suit is also known if (numTotalIdentifiedSuits == 3) { // first identify the fourth suit int nFourthSuit = NONE; for(int i=0;i<4;i++) { // test each suit to see if it's in the list of know suits for(int j=0;j<3;j++) { if (nIdentifiedSuits[j] == i) break; } if (j == 3) nFourthSuit = i; } // VERIFY(nFourthSuit != NONE); CGuessedSuitHoldings& fourthSuit = pPlayerHoldings->GetSuit(nFourthSuit); int numOriginalCards = 13 - numTotalOriginalCards; VERIFY(numOriginalCards >= 0); fourthSuit.SetNumOriginalCards(numOriginalCards); int numRemainingCards = numOriginalCards - fourthSuit.GetNumCardsPlayed(); VERIFY(numRemainingCards >= 0); // mark the # of remaining cards // revisit this later // fourthSuit.SetNumLikelyCards(numRemainingCards); fourthSuit.SetNumRemainingCards(numRemainingCards); // status << "4RCP1B! Therefore, " & PositionToString(nPos) & " started with " & numOriginalCards & " " & STS(nFourthSuit) & " and has " & numRemainingCards & " left.\n"; } } else { status < "RCP5A! " & PositionToString(nPos) & " is now known to have started with " & suit.GetNumOriginalCards() & " " & ((suit.GetNumOriginalCards() == 1)? STSS(nSuitLed) : STS(nSuitLed)) & ".\n"; } } // also, if this is the dummy, and the dummy plays his last card // in the suit, he has effectively shown out CPlayer* pDummy = pDOC->GetDummyPlayer(); if ((nPos == pDummy->GetPosition()) && (pDummy->AreCardsExposed())) { if ((pCard->GetSuit() == nSuitLed) && (pDummy->GetHand().GetNumCardsInSuit(nSuitLed) == 0) && (!pPlayerHoldings->IsSuitShownOut(nSuitLed))) { status << "3RCP20! Dummy is now out of " & STS(nSuitLed) & ".\n"; pPlayerHoldings->MarkSuitShownOut(nSuitLed); } } } // } // special code -- if dummy has just been laid down, mark a suit as shown // out if dummy is void in the suit CPlayer* pDummy = pDOC->GetDummyPlayer(); int nRound = pDOC->GetPlayRound(); if ((nRound == 0) && (nPos == pDummy->GetPosition()) && (pDummy->AreCardsExposed())) { CHandHoldings& dummy = pDummy->GetHand(); for(int i=0;i<4;i++) { if (dummy.GetNumCardsInSuit(i) == 0) { status << "3RCP25! Dummy is shown to be void in " & STS(i) & ".\n"; pPlayerHoldings->MarkSuitShownOut(i); } } } }