// //=============================================================================== // // TryConvention() // // check if we can use an Jacoby 2NT Bid here // BOOL CJacoby2NTConvention::TryConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // // the requirements for an Jacoby 2NT Bid are: // 1: Partner must have opened with 1 of a major // 2: we must not have bid yet // 3: we have 13+ points and 4+ card trump support int nOpeningBid = pDOC->GetOpeningBid(); int nPartnersBid = bidState.nPartnersBid; // test conditions 1 - 4 if ( ISBID(nOpeningBid) && (nOpeningBid == nPartnersBid) && (ISMAJOR(BID_SUIT(bidState.nPartnersBid))) && (bidState.nPartnersBidLevel == 1) && (bidState.m_numBidTurns == 0) && (bidState.fPts >= OPEN_PTS(13)) && (bidState.numSupportCards >= 4) ) { // passed the test } else { return FALSE; } // calc adjusted pts int nSuit = bidState.nPartnersSuit; bidState.SetAgreedSuit(nSuit); bidState.fAdjPts = hand.RevalueHand(REVALUE_DUMMY, nSuit, TRUE); // status << "J2N1! Partner opened " & BTS(nPartnersBid) & ", and with " & bidState.fAdjPts & " pts in hand and " & bidState.numSupportCards & "-card trump support, we can bid Jacoby 2NT to ask for partner's strength.\n"; bidState.SetBid(BID_2NT); bidState.SetConventionStatus(this, CONV_INVOKED); return TRUE; }
// //========================================================= // // RespondToConvention() // // respond to partner's preemptive shutout bid of 3, 4, or 5 // BOOL CShutoutBidsConvention::RespondToConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // first see if another convention is active if (bidState.GetActiveConvention()) return FALSE; // // Bidding in response to an opening preemptive shutout bid? // check requirements // int nPartnersBid = bidState.nPartnersBid; int nPartnersBidLevel = bidState.nPartnersBidLevel; int nPartnersSuit = bidState.nPartnersSuit; // // check to see if partner did in fact make a shutout bid // if (((nPartnersBidLevel >= 3) && (nPartnersBidLevel <= 5)) && (bidState.m_numPartnerBidsMade == 1) && (nPartnersSuit != NOTRUMP) && (bidState.m_bPartnerOpenedForTeam)) { // okay, met requirements } else { // failed the test return FALSE; } // // in general, pass a shutout bid unless we have an exceedingly // strong hand // // first state expectations bidState.m_fPartnersMin = OPEN_PTS(6); bidState.m_fPartnersMax = OPEN_PTS(9); status << "SHUTR0! Partner made a preemptive " & bidState.szPB & " bid, showing a " & ((bidState.nPartnersBidLevel==3)? 7:(bidState.nPartnersBidLevel==4)? 8:9) & "-card " & bidState.szPSS & " suit with no tricks outside the suit, and most likely " & bidState.m_fPartnersMin & "-" & bidState.m_fPartnersMax & " points.\n"; // adjust team point estimates double fPts = bidState.fPts; double fAdjPts = bidState.fAdjPts; double fCardPts = bidState.fCardPts; bidState.m_fMinTPPoints = fAdjPts + bidState.m_fPartnersMin; bidState.m_fMaxTPPoints = fAdjPts + bidState.m_fPartnersMax; bidState.m_fMinTPCPoints = fCardPts + bidState.m_fPartnersMin; bidState.m_fMaxTPCPoints = fCardPts + bidState.m_fPartnersMax; // raise a 3 bid to game if we have enough to make game // the requiremetns are: // 1: 4 cards in the suit, // 2: 5 playing tricks for a major suit, or 6 for a minor // 3: 2 QT's, and // 4: >= 26 team pts for a major game, or >= 29 pts for a minor game int nBid; int numSupportCards = bidState.numSupportCards; int nPartnersSuitSupport = bidState.nPartnersSuitSupport; double numQuickTricks = bidState.numQuickTricks; int numLikelyWinners = bidState.numLikelyWinners; double fMinTPPoints = bidState.m_fMinTPPoints; double fMaxTPPoints = bidState.m_fMaxTPPoints; // if ((nPartnersBidLevel == 3) && (ISMAJOR(nPartnersSuit)) && (numSupportCards >= 4) && (numQuickTricks >= 2) && (numLikelyWinners >= 5) && (fMinTPPoints >= PTS_GAME)) { nBid = MAKEBID(nPartnersSuit,4); status << "SHUTR2! We have " & fCardPts & "/" & fPts & "/" & fAdjPts & " points in hand, for a total of " & fMinTPPoints & "-" & fMaxTPPoints & " points in the partnership, strong support for partner's long " & bidState.szPSS & " suit (holding " & bidState.szHP & "), plus " & numQuickTricks & " QTs and " & numLikelyWinners & " likely winners, so we can safely bid game at " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); return TRUE; } // raise a minor to game as above, but with 5-card // support && 6+ winners && 28+ TPs if ((nPartnersBidLevel <= 4) && (ISMINOR(nPartnersSuit)) && (numSupportCards >= 5) && (numQuickTricks >= 2) && (numLikelyWinners >= 6) && (fMinTPPoints >= PTS_MINOR_GAME)) { nBid = MAKEBID(nPartnersSuit,5); status << "SHUTR4! We have " & fCardPts & "/" & fPts & "/" & fAdjPts & " points in hand, for a total of " & fMinTPPoints & "-" & fMaxTPPoints & " points in the partnership, strong support for partner's long " & bidState.szPSS & " suit (holding " & bidState.szHP & "), plus " & numQuickTricks & " QTs and " & numLikelyWinners & " likely winners, so we can safely bid a minor game at " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); return TRUE; } // raise a 3 or 4 bid to slam with strong support, // >= 32 TPs, and 4 QTs if ((nPartnersBidLevel < 5) && (nPartnersSuitSupport >= SS_GOOD_SUPPORT) && (numQuickTricks >= 4) && (fMinTPPoints >= PTS_SLAM)) { nBid = MAKEBID(nPartnersSuit,6); status << "SHUTR6! We have " & fCardPts & "/" & fPts & "/" & fAdjPts & " points in hand, for a total of " & fMinTPPoints & "-" & fMaxTPPoints & " points in the partnership, " & bidState.SLTS(nPartnersSuit) & " support for partner's long " & bidState.szPSS & " suit (holding " & bidState.szHP & "), plus " & numQuickTricks & " QTs, so we can safely bid a slam at " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); return TRUE; } // else, just pass nBid = BID_PASS; status << "SHUTR9! With " & fCardPts & "/" & fPts & "/" & fAdjPts & " points in hand, for a total of " & fMinTPPoints & "-" & fMaxTPPoints & " points in the partnership, holding " & bidState.szHP & " in support of partner's " & bidState.szPSS & " suit, and with only " & numQuickTricks & " QTs and " & numLikelyWinners & " likely winners, we have no real reason to bid anything, so just pass.\n"; bidState.SetBid(nBid); return TRUE; }
// //=============================================================================== // // TryConvention() // // check if we can use an Gambling 3NT Bid here // BOOL CGambling3NTConvention::TryConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // // the requirements for opening a STANDARD Gambling 3NT Bid are: // 1: a solid 7+ card minor suit, // 2: 10-12 HCPs, // 3: no voids or small singletons, and // 4: no outside stoppers // // the requirements for opening an ACOL Gambling 3NT Bid are: // 1: a solid 7+ card minor suit, // 2: 16-21 HCPs, // 3: no voids or small singletons, and // 4: stoppers in at least 2 of the remaining 3 suits // see which version we're playing int bStandardGambling3NT = (pCurrConvSet->GetValue(tnGambling3NTVersion) == 0); // see if we have any small singletons bool bSmallSingletons = false; if (bidState.numSingletons > 0) { for(int i=0; i<4; i++) { CSuitHoldings& suit = hand.GetSuit(i); if ((suit.GetNumCards() == 1) && (suit[0]->GetFaceValue() < TEN)) { bSmallSingletons = true; break; } } } // see if we have a solid suit int nSuit = NONE; if (hand.GetSuit(CLUBS).IsSolid() && (bidState.numCardsInSuit[CLUBS] >= 7)) nSuit = CLUBS; else if (hand.GetSuit(DIAMONDS).IsSolid() && (bidState.numCardsInSuit[DIAMONDS] >= 7)) nSuit = DIAMONDS; // test for std and ACOL Gambling 3NT conditions int numValidBidsMade = pDOC->GetNumValidBidsMade(); if ( bStandardGambling3NT && (numValidBidsMade == 0) && (ISSUIT(nSuit)) && (bidState.fCardPts >= OPEN_PTS(10)) && (bidState.fCardPts <= OPEN_PTS(12)) && (bidState.numVoids == 0) && !bSmallSingletons && (bidState.numSuitsStopped == 1) ) { // passed the test for standard gambling 3NT status << "G3NT1! With a solid " & bidState.numCardsInSuit[nSuit] & "-card " & STSS(nSuit) & " suit, " & bidState.fCardPts & " HCPs, no voids, no small singletons, and no outside stoppers, " " go ahead and bid a Gambling 3NT.\n"; } else if ( !bStandardGambling3NT && (numValidBidsMade == 0) && (ISSUIT(nSuit)) && (bidState.fCardPts >= OPEN_PTS(16)) && (bidState.fCardPts <= OPEN_PTS(21)) && (bidState.numVoids == 0) && !bSmallSingletons && (bidState.numSuitsStopped >= 3) ) { // passed the test for ACOL gambling 3NT status << "G3NT2! With a solid " & bidState.numCardsInSuit[nSuit] & "-card " & STSS(nSuit) & " suit, " & bidState.fCardPts & " HCPs, no voids, no small singletons, and stoppers in " & ((bidState.numSuitsStopped == 4)? "all four suits" : "two outside suits") & ", go ahead and bid an ACOL Gambling 3NT.\n"; } else { return FALSE; } // OK, go ahead and bid 3NT bidState.SetBid(BID_3NT); bidState.SetConventionStatus(this, CONV_INVOKED); return TRUE; }
// //----------------------------------------------------- // // respond to partner's Gambling 3NT Bid // BOOL CGambling3NTConvention::RespondToConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // first see if another convention is active if ((bidState.GetActiveConvention() != NULL) && (bidState.GetActiveConvention() != this)) return FALSE; // // make a responding bid // int nPartnersBid = bidState.nPartnersBid; int nOpeningBid = pDOC->GetOpeningBid(); int nBid = NONE; // int nStatus = bidState.GetConventionStatus(this); if (nStatus == CONV_INACTIVE) { // // Bidding in response to partner's Gambling 3NT // // and test conditions // partner must have opened at 3NT if ( (nOpeningBid == nPartnersBid) && (bidState.nPartnersBid == BID_3NT) ) { // passed the test } else { return FALSE; } // see which version of gambling 3NT we're playing int bStandardGambling3NT = (pCurrConvSet->GetValue(tnGambling3NTVersion) == 0); // if (bStandardGambling3NT) { // standard Gambling 3NT status << "G3NT10! Partner bid a Gambling 3NT, indicating " & OPEN_PTS(10) & "-" & OPEN_PTS(12) & " HCPs, a solid 7+ card minor, " " no voids or small singletons, and no outside stoppers.\n"; // revalue partnership totals bidState.AdjustPartnershipPoints(10, 12); // if we have stoppers in at least 3 suits and no void minors, pass if ((bidState.numSuitsStopped >= 3) && (bidState.numCardsInSuit[CLUBS] > 0) && (bidState.numCardsInSuit[DIAMONDS] > 0)) { status << "G3NT12! Since we have " & bidState.numSuitsStopped & " suits stopped and no minor suit voids, we can pass.\n"; nBid = BID_3NT; } else { nBid = BID_4C; if (bidState.numSuitsStopped < 3) status << "G3NT13! But since we have only " & bidState.numSuitsStopped & " suits stopped, we have to respond with " & BTS(nBid) & ", which partner can correct to 4D if necessary.\n"; else status << "G3NT14! But since we are void in the " & ((bidState.numCardsInSuit[CLUBS] == 0)? "Club" : "Diamond") & " suit, we have to respond at " & BTS(nBid) & ", which partner can correct to 4D if necessary.\n"; // bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND1); return TRUE; } } else { // ACOL Gambling 3NT // pass unless there's interest in slam status << "G3NT20! Partner bid an ACOL Gambling 3NT, indicating " & OPEN_PTS(16) & "-" & OPEN_PTS(21) & " HCPs, a solid 7+ card minor, " " no voids or small singletons, and stoppers in at least 2 outside suits.\n"; // revalue partnership totals bidState.AdjustPartnershipPoints(16, 21); // respond positively only if there's interest in slam if (bidState.m_fMinTPPoints >= PTS_SLAM) { // bid slam directly if (bidState.m_fMinTPPoints >= PTS_GRAND_SLAM) { nBid = BID_7NT; status << "G3NT21! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMinTPPoints & " pts in the partnership, bid a grand slam directly at " & BTS(nBid) & ".\n"; } else { nBid = BID_6NT; status << "G3NT22! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMinTPPoints & " pts in the partnership, bid slam directly at " & BTS(nBid) & ".\n"; } } else { // gotta pass status << "G3NT29! But with a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMinTPPoints & " pts in the partnership, we have no interest in slam and have to pass.\n"; nBid = BID_PASS; } } // bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else if (nStatus == CONV_RESPONDED_ROUND1) { // we must have responded with a 4C, so pass here // see if partner made sense if ((nPartnersBid == BID_4D) || (nPartnersBid == BID_PASS)) status << "G3NT40! Pass partner's " & BTS(nPartnersBid) & " and conclude the Gambling 3NT convention and pass.\n"; else status << "G3NT41! Partner's " & BTS(nPartnersBid) & " bid doesn't make sense, so end the Gambling 3NT convention and pas.\n"; // bidState.SetBid(BID_PASS); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // return FALSE; }
// //--------------------------------------------------------------- // // MakeOpeningBid() // // make initial bid // int CBidEngine::MakeOpeningBid() { CPlayerStatusDialog& status = *m_pStatusDlg; // status << "2Opening bid for team.\n"; // //-------------------------------------------------------- // // First check to see if we can open using a convention // e.g., weak 2, stong 2, preemptive 3/4, etc. // if (pCurrConvSet->ApplyConventionTests(*m_pPlayer, *m_pHand, *m_pCardLocation, m_ppGuessedHands, *this, *m_pStatusDlg)) { return ValidateBid(m_nBid); } // //-------------------------------------------------------- // // see if we can open No Trumps // int NTMin[3], NTMax[3]; // NTMin[0] = pCurrConvSet->GetValue(tn1NTRangeMinPts); NTMax[0] = pCurrConvSet->GetValue(tn1NTRangeMaxPts); NTMin[1] = pCurrConvSet->GetValue(tn2NTRangeMinPts); NTMax[1] = pCurrConvSet->GetValue(tn2NTRangeMaxPts); NTMin[2] = pCurrConvSet->GetValue(tn3NTRangeMinPts); NTMax[2] = pCurrConvSet->GetValue(tn3NTRangeMaxPts); // if ((bBalanced) && (fCardPts >= OPEN_PTS(NTMin[0]))) { // status << "A00! Have " & fCardPts & " HCP's with a balanced hand.\n"; // but if we have a good 5-card major, open it in a suit // but not if we have to overcall to do so BOOL bNeedToOvercall = FALSE; if ( ((nLHOBid > BID_PASS) || (nRHOBid > BID_PASS)) && (nPartnersBid <= BID_PASS)) bNeedToOvercall = TRUE; // if (IsSuitOpenable(HEARTS) && !bNeedToOvercall) { status << "A02! But with an openable " & numCardsInSuit[HEARTS] & "-card Heart suit, prefer to open in the major instead of in No Trump.\n"; goto escape1; } if (IsSuitOpenable(SPADES) && !bNeedToOvercall) { status << "A04! But with an openable " & numCardsInSuit[SPADES] & "-card Spade suit, prefer to open in the major instead of in No Trump.\n"; goto escape1; } // check range for 1NT // NCR-285 Need stopper if opponents have bid!!! BOOL bHaveOppsStopped = TRUE; if ((nRHOBid != BID_PASS) && ISSUIT(nRHOSuit)) bHaveOppsStopped = m_pHand->IsSuitStopped(nRHOSuit); // NCR-285 consider if their suit is stopped else if ((nLHOBid != BID_PASS) && ISSUIT(nLHOSuit)) bHaveOppsStopped = m_pHand->IsSuitStopped(nLHOSuit); // NCR-285 ditto if ((fCardPts >= OPEN_PTS(NTMin[0])) && (fCardPts <= NTMax[0]) && bHaveOppsStopped) // NCR-285 added test { // NCR-18 Check if RHO bid NT and double if(nRHOBid == BID_1NT){ m_nBid = BID_DOUBLE; // NCR-337 Problem here. This is not a Takeout double??? status << "A07! This meet the rqmts for the 1NT opening range (" & NTMin[0] & "-" & NTMax[0] & "), but RHO has bid 1NT, so Double.\n"; }else { // open 1NT m_nBid = BID_1NT; status << "A08! This meet the rqmts for the 1NT opening range (" & NTMin[0] & "-" & NTMax[0] & "), so bid 1NT.\n"; } return ValidateBid(m_nBid); } else if ((fCardPts > OPEN_PTS(NTMax[0])) && (fCardPts < NTMin[1])) { // in-between 1 & 2 situation; bid interim suit m_nNextIntendedBid = NIB_JUMP_NT; if (numOpenableSuits > 0) { // bid 1 of lowest openable suit m_nBid = GetLowestOpenableBid(SUITS_ANY,OT_OPENER,1); // NCR-335 Don't bid 4 card major with 5CardMajor convention if (ISMAJOR(BID_SUIT(m_nBid)) && pCurrConvSet->IsConventionEnabled(tid5CardMajors) && (numCardsInSuit[BID_SUIT(m_nBid)] < 5) ) { // Use Diamonds if 4, else clubs (have balanced hand here) Suit bidThis = numCardsInSuit[DIAMONDS] >= 4 ? DIAMONDS : CLUBS; m_nBid = MAKEBID(bidThis, 1); // NCR-335 use minor } status << "A10! This exceeds the max pts for a 1NT opening (" & NTMax[0] & "), but is less than min pts for 2NT (" & NTMin[1] & "). So bid the lowest openable suit of " & BTS(m_nBid) & " for now, then try for a jump shift to 2NT later.\n"; } else { // go ahead and bid the preferred suit if (!pCurrConvSet->IsConventionEnabled(tid5CardMajors) ) { m_nBid = MAKEBID(nPrefSuit,1); } else { m_nBid = BID_1C; } status << "A14! This exceeds the max pts for a 1NT opening (" & NTMax[0] & "), but is less than min pts for 2NT (" & NTMin[1] & " and we have no good openable suit, so just bid " & BTS(m_nBid) & " for now.\n"; } return ValidateBid(m_nBid); } // NCR can't use 2NT if using unusual NT convention else if ((fCardPts >= OPEN_PTS(NTMin[1])) && (fCardPts <= NTMax[1]) // && !pCurrConvSet->IsConventionEnabled(tidUnusualNT) // NCR not relevant for Opening??? // NCR test that hand does NOT have a worthless doubleton && ((m_pHand->GetNumDoubletons() == 0) // OK if no doubletons || (m_pHand->GetNumDoubletons() >= 1) && !m_pHand->HasWorthlessDoubleton()) //or if its not worthless ) { // open 2NT m_nBid = BID_2NT; status << "A20! This meets the rqmts for a 2NT opening (" & NTMin[1] & "-" & NTMax[1] & "), so bid 2NT.\n"; return ValidateBid(m_nBid); } else if ((fCardPts >= OPEN_PTS(NTMax[1])) && (NTMin[2] < 0)) // NCR ??? see next else if { // > pts for 2NT, but 3NT opening not allowed NCR what does not allowed mean??? // so bid 2C m_nBid = BID_2C; status << "A30! This exceeds the max pts for a 2NT opening (" & NTMax[1] & "), but a 3NT opening has been disallowed, so open with " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } else if ((fCardPts > OPEN_PTS(NTMax[1])) && (fCardPts < NTMin[2])) { // in-between 2 & 3 situation; bid 2 of interim suit // and bid NT later m_nNextIntendedBid = NIB_NT; if (numOpenableSuits > 0) { // bid 1 of lowest openable suit m_nBid = GetLowestOpenableBid(SUITS_ANY,OT_OPENER,1); status << "A40! This exceeds the max pts for a 2NT opening (" & NTMax[1] & "), but is less than min pts for 3NT (" & NTMin[2] & "). So bid the lowest openable suit of " & BTS(m_nBid) & " for now, then jump shift to NT later.\n"; } else { // no good openable suits; just bid preferred suit m_nBid = MAKEBID(nPrefSuit,1);; status << "A42! This exceeds the max pts for a 2NT opening (" & NTMax[1] & "), but is less than min pts for 3NT (" & NTMin[2] & "), and have no good openable suit, so bid " & BTS(m_nBid) & " for now.\n"; } return ValidateBid(m_nBid); } else if ((fCardPts >= OPEN_PTS(NTMin[2])) && (fCardPts <= NTMax[2]) // NCR test that hand does NOT have a worthless doubleton && ((m_pHand->GetNumDoubletons() == 0) // OK if no doubletons || (m_pHand->GetNumDoubletons() >= 1) && !m_pHand->HasWorthlessDoubleton()) //or if its not worthless ) { // open 3NT m_nBid = BID_3NT; status << "A50! Bid 3NT.\n"; return ValidateBid(m_nBid); } /* NCR remove falling into a 3NT bid else // if(!pCurrConvSet->IsConventionEnabled(tidUnusualNT)) // NCR added Unusual test??? { // > 3NT point range? unusual, but open 3NT for now m_nBid = BID_3NT; status << "A60! bid 3NT with balanced hand and " & fCardPts & " points.\n"; // NCR return ValidateBid(m_nBid); } */ } // end balanced hand with > min pts escape1: // //------------------------------------------------------------------- // // See if we can open at the 1-level // // open at the 1-level if we have: // 1: 14+ points in high cards // 2: 13+ HCPs with 2 Quick Tricks // 3: 12+ HCPs with 2 QTs and a rebiddable suit // 4: 12+ HCPs with 2 QTs and a 5-card suit // 5: 12+ HCPs with balanced dist (weak NT mode only) // 6: 10+ HCPs opening in 3rd or 4th seat and a good suit NCR ??? // 7: 15+ Total points with 2 QTs // 8: 14+ Total points with 2 QTs and a rebiddable suit // 9: 13+ Total points with 2 QTs and a rebiddable suit of 6+ cards // // we can only open if the opponents haven't opened yet // if they have, the COvercallsCovention object should have looked into // a posssible overcall. if ((nLHOBid > BID_PASS) || (nRHOBid > BID_PASS)) { status << "B00! We cannot overcall and the hand is not appropriate for any other bid, so pass.\n"; m_nBid = BID_PASS; return ValidateBid(m_nBid); } // the suit to open us usually the best suit nSuit = GetBestOpeningSuit(); // case 1: 14+ points in high cards if (fCardPts >= OPEN_PTS(14)) { m_nBid = MAKEBID(nSuit,1); status << "E01! Have " & fCardPts & " points in high cards, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // case 2: 13+ HCP's && 2 QT's if ((fCardPts >= OPEN_PTS(13)) && (numQuickTricks >= 2)) { m_nBid = MAKEBID(nSuit,1); status << "E02! Have " & fCardPts & " points in high cards and " & numQuickTricks & " quick tricks, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } // case 3: 12+ HCP's, 2 QT's, & a rebiddable suit // NCR-680 reduce QTs if ((fCardPts >= OPEN_PTS(12)) && (numQuickTricks >= PT_COUNT(2)) && (numRebiddableSuits > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E03! Have " & fCardPts & " points in high cards, " & numQuickTricks & " quick tricks, and a rebiddable suit in " & STS(nSuit) & ", so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } // case 4: 12+ HCP's, 2 QT's, & a 5-card suit if ((fCardPts >= OPEN_PTS(12)) && (numQuickTricks >= 2) && (m_pHand->GetNumSuitsOfAtLeast(5) > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E04! Have " & fCardPts & " points in high cards, " & numQuickTricks & " quick tricks, and a " & numCardsInSuit[nSuit] & "-card suit, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // case 5: 12+ HCP's & a balanced dist in Weak NTs if ((fCardPts >= OPEN_PTS(12)) && (bBalanced) && (pCurrConvSet->GetValue(tn1NTRange) == 0)) { m_nBid = BID_1NT; status << "E05! Have " & fCardPts & " points in high cards, a balanced hand, " & "and playing Weak No Trumps, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // case 6: 10+ HCPs opening in 3rd or 4th seat & a good suit // if ((fCardPts >= OPEN_PTS(10)) if ((fCardPts >= 10) // NCR-206 Hard 10 and > 4 cards && (((nBiddingOrder == 2) && (numCardsInSuit[nSuit] > 4)) // NCR require Having spades to open light in 4th || ((nBiddingOrder == 3) & (numCardsInSuit[SPADES] > 3)) && (nSuit == SPADES)) && (numOpenableSuits > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E07! Have " & fCardPts & " points in high cards in " & ((nBiddingOrder == 2)? "3rd" : "4th") & " position and a " & SSTS(nSuit) & " " & STSS(nSuit) & " suit, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // case 7: 15+ Total points and 10 HCPs, with 2 QTs if ((fPts >= OPEN_PTS(15)) && (fCardPts >= OPEN_PTS(10)) && (numQuickTricks >= 2)) { m_nBid = MAKEBID(nSuit,1); status << "E08! Have " & fCardPts & "/" & fPts & " total points with " & numQuickTricks & " QT's, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // // case 8: 14+ Total points with 10+ HCPs, 2 QTs // and a rebiddable suit if ((fPts >= OPEN_PTS(14)) && (fCardPts >= OPEN_PTS(10)) && (numQuickTricks >= 2) && (numRebiddableSuits > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E09! Have " & fCardPts & "/" & fPts & " total points with " & numQuickTricks & " QT's and a rebiddable suit, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } // // case 9: 13+ Total points with 10+ HCPs, 2 QTs and a // rebiddable suit of 6+ cards if ((fPts >= OPEN_PTS(13)) && (fCardPts >= OPEN_PTS(10)) && (numQuickTricks >= 2) && (numRebiddableSuits > 0) && (numPrefSuitCards >= 6) && (nSuitStrength[nPrefSuit] > SS_OPENABLE)) { m_nBid = MAKEBID(nSuit,1); status << "E10! Have " & fCardPts & "/" & fPts & " total points with " & numQuickTricks & " QT's and a " & numCardsInSuit[nSuit] & "-card rebiddable suit, so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // //--------------------------------------------------------- // // now test for optional 1-level openings // int nAllowed1Opens = pCurrConvSet->GetValue(tnAllowable1Openings); // // option 1: 11+ HCPs with 2 QTs, a rebiddable suit, & // length in both majors // if ((nAllowed1Opens & OB_11_HCPS_RBS_LM) && (fCardPts >= OPEN_PTS(11)) && (numQuickTricks >= 2) && (numRebiddableSuits > 0) && (numCardsInSuit[HEARTS] >= 4) && (numCardsInSuit[SPADES] >= 4)) { m_nBid = MAKEBID(nSuit,1); status << "E21! Have " & fCardPts & " points in high cards, " & numQuickTricks & " quick tricks, a rebiddable suit, and length in both majors " & "(optional opening condition #1), so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // // option 2: 11+ HCPs with 2 QTs and a 6-card suit // if ((nAllowed1Opens & OB_11_HCPS_6CS) && (fCardPts >= OPEN_PTS(11)) && (numQuickTricks >= 2) && (m_pHand->GetNumSuitsOfAtLeast(6) > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E22! Have " & fCardPts & " points in high cards with " & numQuickTricks & " QT's and a " & numCardsInSuit[nSuit] & "-card suit (optional opening condition #2), so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } // // option 3: 14+ Total points with 10 HCPs, 2 QTs, and a // good suit // if ((nAllowed1Opens & OB_14_TCPS_GS) && (fPts >= OPEN_PTS(14)) && (fCardPts >= OPEN_PTS(10)) && (numQuickTricks >= 2) && (numSolidSuits > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E23! Have " & fCardPts & "/" & fPts & "total points with " & numQuickTricks & " QT's and a " & SSTS(nSuit) & " " & STSS(nSuit) & " suit (optional opening condition #3), so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } // // option 4: 14+ Total points with 10 HCPs, 2 QTs, and a // long suit (6+ cards) // if ((nAllowed1Opens & OB_14_TCPS_LS) && (fPts >= OPEN_PTS(14)) && (fCardPts >= OPEN_PTS(10)) && (numQuickTricks >= 2) && (m_pHand->GetNumSuitsOfAtLeast(6) > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E24! Have " & fCardPts & "/" & fPts & " total points with " & numQuickTricks & " QT's and a " & numCardsInSuit[nSuit] &"-card " & STSS(nSuit) & " suit (optional opening condition #4), so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } // // option 5: 13+ Total points with 2 QTs, 10 HCPs, // and a 6-card suit // if ((nAllowed1Opens & OB_13_TCPS_LS) && // NCR-390 Add in distribution points here and below in status msg ((fPts + fDistPts) >= OPEN_PTS(13)) && (fCardPts >= OPEN_PTS(10)) && (numQuickTricks >= 2) && (m_pHand->GetNumSuitsOfAtLeast(6) > 0)) { m_nBid = MAKEBID(nSuit,1); status << "E25! Have " & fCardPts & "/" & (fPts+fDistPts) &" total points with " & numQuickTricks & " QT's and a " & numCardsInSuit[nSuit] & "-card " & STSS(nSuit) & " suit (optional opening condition #5), so bid " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } /* // // special case: 13 pts + 1 for every 0.5 QTs missing if ((fPts > OPEN_PTS(13)) && (numQuickTricks < 2)) { int nRqmt = 13 + (int)(((2.0 - numQuickTricks)*2)); if (fPts >= nRqmt) { m_nBid = MAKEBID(nSuit,1); status << "E27! Have " & fCardPts & "/" & fPts & " total points; shade opening requirement of 2 QT's and make do with " & numQuickTricks & " QT's in light of the high total point count; open " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } } */ // NCR-356 Loosen up a bit here - bid 5 card major if ... if((fCardPts >= OPEN_PTS(13)) && ISMAJOR(nSuit) && (numCardsInSuit[nSuit] >= 5) && pCurrConvSet->IsConventionEnabled(tid5CardMajors) ) { m_nBid = MAKEBID(nSuit,1); status << "E28! Have " & fCardPts & "/" & fPts & " total points; shade opening requirement of 2 QT's and make do with " & numQuickTricks & " QT's; open " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid);; } // end NCR-356 // NCR Is Convenient minor (goes with 5card Majors) appropriate - 13 HCPs and 3 clubs if((fCardPts >= OPEN_PTS(13)) && pCurrConvSet->IsConventionEnabled(tid5CardMajors) && (numCardsInSuit[CLUBS] >= 3)) { m_nBid = BID_1C; if(numCardsInSuit[DIAMONDS] > numCardsInSuit[CLUBS]) // NCR-507 Bid Diamonds if more of them m_nBid = BID_1D; status << "E31! Have " & fCardPts & " points in high cards , so bid a Convenient minor " & BTS(m_nBid) & ".\n"; return ValidateBid(m_nBid); } // //-------------------------------------------------------- // // All attempts at opening failed, so return a PASS // status << "Z00! Hand is insufficient for any opening, so pass.\n"; m_nBid = BID_PASS; return ValidateBid(m_nBid);; }
// //=============================================================================== // // TryConvention() // // check if we can bid a takeout double here // BOOL CNegativeDoublesConvention::TryConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // // Negative doubles are made in the third position after // partner opens and RHO overcalls up to 2S. // The requirements for a negative doubles are: // 1: partner must have opened the bidding, // 2: we must either have passesed or not bid yet // 3: RHO must have overcalled at a level no higher than 2S, // 4: have 4+ cards in each unbid major, (5+ at the 2-level), // 5: holding 6+ points at the 1-level, or 11+ at the 2-level, and finally, // 6: don't have decent support for partner's suit // test conditions 1, 2, 3, and 5 if ((bidState.m_bPartnerOpenedForTeam) && (bidState.m_numBidTurns <= 1) && (bidState.nLHOBid <= BID_PASS) && (bidState.nRHOBid > BID_PASS) // NCR-145 Can't do NegDouble over Opening bid of Double && (bidState.nPartnersOpeningBid != BID_DOUBLE) // NCR-294 Can't do NegDbl over NT && (bidState.nRHOSuit != NOTRUMP) // NCR-116 split test into 2 parts depending on bid level && (((bidState.nRHOBid <= BID_1S) && (bidState.fCardPts >= OPEN_PTS(6))) // NCR-116 higher level takes more points || ((bidState.nRHOBid <= BID_2S) && (bidState.fCardPts >= OPEN_PTS(11)))) && !ISBID(bidState.nPreviousBid)) // NCR test if we made a previous bid { // passed the initial tests } else { return FALSE; } // test condition #6 // if we can raise partner or shift over the opponent, // don't bother with a negative double int nRHOBid = bidState.nRHOBid; int nRHOBidLevel = bidState.nRHOBidLevel; int nRHOSuit = bidState.nRHOSuit; // if (nRHOBidLevel == 1) { /* // see if we can raise partner at the 2-level if (pCurrConvSet->IsConventionEnabled(tidLimitRaises)) { if ((bidState.numSupportCards >= 3) && (bidState.fPts >= OPEN_PTS(6))) { // we can raise partner at the 2-level, so forget the neg double return FALSE; } else if (bidState.numSupportCards >= 3) && (bidState.fPts >= OPEN_PTS(6))) { // likewise, w/o limit raises return FALSE; } } */ if ((bidState.numSupportCards >= 3) && (bidState.numSupportCards >= 3) && (bidState.fPts >= OPEN_PTS(6))) { // if we can raise partner at the 2-level, forget the neg double if (pCurrConvSet->IsConventionEnabled(tidLimitRaises) && (bidState.fPts >= OPEN_PTS(11)) && (bidState.fPts < OPEN_PTS(13))) return FALSE; // limit raise else if (!pCurrConvSet->IsConventionEnabled(tidLimitRaises) && (bidState.fPts >= OPEN_PTS(13)) && (bidState.fPts < OPEN_PTS(17))) return FALSE; // single raise } // check up to 2 suits for (int i=0;i<2;i++) { // see if we can switch to this suit int nSuit = hand.GetSuitsByPreference(i); if (bidState.IsSuitShiftable(nSuit) && (nSuit > nRHOSuit)) return FALSE; } } // if (nRHOBidLevel == 2) { // see if we can safely raise partner at the 2-level if ((bidState.numSupportCards >= 3) && (bidState.fPts >= OPEN_PTS(6)) && (bidState.nPartnersSuit > nRHOSuit)) { // we can raise partner at the 2-level, so forget the neg double return FALSE; } // see if we can raise partner to the 3-level (either 11 or 13 pts) double nReqPts = pCurrConvSet->IsConventionEnabled(tidLimitRaises)? OPEN_PTS(11) : OPEN_PTS(13); if ((bidState.numSupportCards >= 4) && (bidState.fPts >= nReqPts)) { // we can raise partner to the 3-level, so forget the neg double return FALSE; } // check up to 2 suits for a shift at the 2-level for (int i=0;i<2;i++) { // see if we can switch to this suit int nSuit = hand.GetSuitsByPreference(i); if (bidState.IsSuitShiftable(nSuit)) { // we can shift to the suit, but see if we have the pts if ((nSuit < bidState.nPartnersSuit) && (bidState.fPts >= OPEN_PTS(10))) return FALSE; // can shift to a lower suit at the 2-level else if ((nSuit > bidState.nPartnersSuit) && (bidState.fPts >= OPEN_PTS(19))) return FALSE; // can (jump) shift to a higher suit at the 2-level } } } else if (nRHOBidLevel == 3) { // opp. overcalled at 3-level; too high a level for a neg. double return FALSE; } // test condition 4 // mark which majors are unbid int nMajorSuits[2] = { 1, 1 }; if (bidState.nPartnersSuit == HEARTS) nMajorSuits[0] = 0; // Hearts have been bid else if (bidState.nPartnersSuit == SPADES) nMajorSuits[1] = 0; // spades have been bid // if (bidState.nRHOSuit == HEARTS) nMajorSuits[0] = 0; else if (bidState.nRHOSuit == SPADES) nMajorSuits[1] = 0; // if both majors have been bid, we can't use negative doubles if ((!nMajorSuits[0]) && (!nMajorSuits[1])) return FALSE; // if (bidState.nRHOBidLevel == 1) { // at the 1-level, need 4+ cards in each unbid major and 6+ pts if ( ((nMajorSuits[0]) && (hand.GetNumCardsInSuit(HEARTS) < 4)) || ((nMajorSuits[1]) && (hand.GetNumCardsInSuit(SPADES) < 4)) || (bidState.fPts < OPEN_PTS(6))) return FALSE; } else { // at the 2-level, need 5+ cards in each unbid major and 11+ pts if ( ((nMajorSuits[0]) && (hand.GetNumCardsInSuit(HEARTS) < 5)) || ((nMajorSuits[1]) && (hand.GetNumCardsInSuit(SPADES) < 5)) || (bidState.fPts < OPEN_PTS(11))) return FALSE; } // // finally, see if we have _too many_ points for a neg. double (19+) // if (bidState.fPts >= OPEN_PTS(19)) { // status << "NEGDBLX! We have the holdings for a negative double, but our " & // bidState.fPts & " points are too much\n"; return FALSE; } // // we've now passed all the tests, so make the bid // if (bidState.nRHOBidLevel == 1) status << "NEGDBL1! With " & bidState.fPts & "/" & bidState.fPts & " points and 4 cards in the unbid majors, bid a negative double.\n"; else status << "NEGDBL2! With " & bidState.fPts & "/" & bidState.fPts & " points and 5+ cards in the unbid majors, bid a negative double.\n"; int nBid = BID_DOUBLE; bidState.SetBid(nBid); // bidState.SetConventionStatus(this, CONV_INVOKED); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; }
// //----------------------------------------------------- // // respond to partner's negative double // BOOL CNegativeDoublesConvention::RespondToConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // first see if another convention is active if ((bidState.GetActiveConvention() != NULL) && (bidState.GetActiveConvention() != this)) return FALSE; // // Bidding in response to partner's negative bid? check requirements // // the identifying marks of a negative double are: // 1: this must be round #1 or 2 // 2: we must have opened bidding, and // 3: LHO must have bid over our initial bid, up to 2S // int nBid; int nPartnersBid = bidState.nPartnersBid; int nMajorSuits[2] = { 1, 1 }; if (bidState.nPreviousSuit == HEARTS) nMajorSuits[0] = 0; else if (bidState.nPreviousSuit == SPADES) nMajorSuits[1] = 0; // if (bidState.nLHOSuit == HEARTS) nMajorSuits[0] = 0; else if (bidState.nLHOSuit == SPADES) nMajorSuits[1] = 0; // apply tests #1, 2, and 3 if ( (nPartnersBid == BID_DOUBLE) && ((bidState.nRound == 0) || (bidState.nRound == 1)) && (bidState.m_bOpenedBiddingForTeam) && (bidState.nLHOBid > BID_PASS) && (bidState.nLHOBid <= BID_2S) // NCR-195 bid must be suit && ISSUIT(BID_SUIT(bidState.nLHOBid)) ) { // status << "NEGDR2! Partner has bid a negative double, indicating 4+ cards in the unbid majors " & ((nMajorSuits[0] && nMajorSuits[1])? "(Hearts and Spades)" : nMajorSuits[0]? "(Hearts)" : "(Spades)") & ".\n"; } else { return FALSE; } // // estimate partner's strength // if (bidState.nLHOBidLevel == 1) { // 6-9 pts for a neg dbl the 1-level (NCR TryConvention uses 19 max???) bidState.m_fPartnersMin = OPEN_PTS(6); bidState.m_fPartnersMax = Min(OPEN_PTS(19),40 - bidState.fCardPts); // NCR changed 9 to 19 bidState.m_fMinTPPoints = bidState.fPts + bidState.m_fPartnersMin; bidState.m_fMaxTPPoints = bidState.fPts + bidState.m_fPartnersMax; bidState.m_fMinTPCPoints = bidState.fCardPts + bidState.m_fPartnersMin; bidState.m_fMaxTPCPoints = bidState.fCardPts + bidState.m_fPartnersMax; status << "2NEGDR8! Partner's negative double indicates " & bidState.m_fPartnersMin & "-" & bidState.m_fPartnersMax & " points, for a total in the partnership of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " points.\n"; } else { // 11-18 pts for a neg double at the 2 level bidState.m_fPartnersMin = OPEN_PTS(11); bidState.m_fPartnersMax = Min(OPEN_PTS(18),40 - bidState.fCardPts); bidState.m_fMinTPPoints = bidState.fPts + bidState.m_fPartnersMin; bidState.m_fMaxTPPoints = bidState.fPts + bidState.m_fPartnersMax; bidState.m_fMinTPCPoints = bidState.fCardPts + bidState.m_fPartnersMin; bidState.m_fMaxTPCPoints = bidState.fCardPts + bidState.m_fPartnersMax; status << "2NEGDRT8! Partner's negative double indicates 11+ pts, for a total in the partnership of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " points.\n"; } // // and respond to the bid // int nSuit; double fCardPts = bidState.fCardPts; double fPts = bidState.fPts; int nLHOBid = bidState.nLHOBid; int nRHOBid = bidState.nRHOBid; // // with support for one or the other major, raise // but discount the majors already bid by us or LHO // int numHearts = hand.GetNumCardsInSuit(HEARTS); int numSpades = hand.GetNumCardsInSuit(SPADES); // gotta beat RHO's bid if possible int nTopBid = nLHOBid; if ((nRHOBid > BID_PASS) && (nRHOBid != BID_REDOUBLE)) nTopBid = nRHOBid; // see if the majors are available if ( (nMajorSuits[0] && nMajorSuits[1]) && ((numHearts >= 3) || (numSpades >= 3)) ) { // both majors are available, so pick the better one int nSuit = bidState.PickSuperiorSuit(HEARTS,SPADES); nBid = bidState.GetCheapestShiftBid(nSuit, nTopBid); // see if the bid is affordable if (bidState.IsBidSafe(nBid)) { status << "NEGDTR20! With " & bidState.m_fMinTPPoints & " pts in the partnership and " & " both majors available in response to the negative double, go with the " & hand.GetNumCardsInSuit(nSuit) & "-card " & STSS(nSuit) & " suit and bid " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); } else { status << "NEGDTR21! We have both majors avaialblem but with " & bidState.m_fMinTPPoints & " pts in the partnership, we do not have enough points to bid either suit and have to pass.\n"; bidState.SetBid(BID_PASS); } bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else if ( ((nMajorSuits[0]) && (numHearts >= 3)) || ((nMajorSuits[1]) && (numSpades >= 3)) ) { // bid the suit if ((nMajorSuits[0]) && (numHearts >= 3)) nSuit = HEARTS; else nSuit = SPADES; nBid = bidState.GetCheapestShiftBid(nSuit, nTopBid); // see if the bid is affordable double fAdj = bidState.fAdjPts; // NCR-717 theApp.GetBiddingAgressiveness()*1.5; // NCR change test amt? if (bidState.IsBidSafe(nBid, fAdj)) // NCR adjust??? { status << "NEGDTR30! With " & bidState.m_fMinTPPoints & " pts in the partnership and " & hand.GetNumCardsInSuit(nSuit) & " cards available in " & STS(nSuit) &", bid " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); } else { status << "NEGDTR31! We have " & hand.GetNumCardsInSuit(nSuit) & " cards in the " & STSS(nSuit) & " suit, but with only " & bidState.m_fMinTPPoints & " pts in the partnership, we can't go any higher.\n"; bidState.SetBid(BID_PASS); } bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // // we have no majors available, so bid NT if possible // if (bidState.BidNoTrumpAsAppropriate(FALSE)) { bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // else bid something, anything nSuit = bidState.GetRebidSuit(bidState.nPreviousSuit); if(nSuit == NONE) { //NCR test for no rebidable suit return nBid = BID_1NT; // NCR Hardcoded ??? vs get cheapest }else{ nBid = bidState.GetCheapestShiftBid(nSuit, nTopBid); } // NCR-415 Test if safe bid if (!bidState.IsBidSafe(nBid, bidState.fDistPts) // NCR-592 set adj to dist pts && (bidState.nRHOBid > BID_PASS) ) // NCR-637 Only if RHO bid { nBid = BID_PASS; status << "NEGDTR36! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we cannot safely bid further, so pass.\n"; } // end NCR-415 else { if (!ISMAJOR(nSuit)) status << "NEGDTR40! Unfortunately we don't have a major to respond with, so bid " & BTS(nBid) & ".\n"; else status << "NEGDTR41! Our best response is " & BTS(nBid) & ".\n"; } bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; }
// //--------------------------------------------------------------- // // RespondToConvention() // // Check to see if a Gerber query has been made, // and if so, respond as appropriate // // BOOL CGerberConvention::RespondToConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // first see if another convention is active // if ((bidState.GetActiveConvention() != NULL) && // (bidState.GetActiveConvention() != this)) // return FALSE; // // first look for a Gerber _Query_ from partner -- // any 4C in response to a natural NT bid is Gerber // NCR unless partner has bid clubs before // int nGerberStatus = bidState.GetConventionStatus(this); int numAces = bidState.numAces; int numKings = bidState.numKings; int nPrevioousBid = bidState.nPreviousBid; int nBid; // is partner asking for aces? if ( (bidState.nPartnersBid == BID_4C) // NCR-552 I didn't open 1C && (bidState.nNextPrevBid != BID_1C) // Or test if CLUBs ??? // NCR-521 4C must be Jump to be Gerber && ((bidState.GetBidType(bidState.nPartnersBid) & (BT_Jump + BT_Leap)) != 0) // NCR-551 Also Leap && ((nPrevioousBid == BID_1NT) || ((nPrevioousBid == BID_2NT) // NCR-184 was it Unusual 2NT ? use pts ??? && (bidState.fCardPts >= OPEN_PTS(13))) // NCR-324 use OPEN_PTS /* NCR-466 || ((nPrevioousBid == BID_3NT) // NCR-152 & NCR-170 Check if clubs are partner's suit // NCR-299 Not if I bid clubs && ((bidState.nPartnersPrevSuit != CLUBS) && (bidState.nNextPrevSuit != CLUBS)) ) */ // NCR-14 After 3NT ??? //NCR-246a Also after Stayman 2C || ((bidState.nPartnersPrevBid == BID_2C) && (bidState.nNextPrevSuit == NOTRUMP) // NCR-509 Pard is using Gerber only if I opened NT && bidState.m_bOpenedBiddingForTeam) ) ) { // respond if ((numAces == 0) || (numAces == 4)) nBid = BID_4D; else if (numAces == 1) nBid = BID_4H; else if (numAces == 2) nBid = BID_4S; else if (numAces == 3) nBid = BID_4NT; // NCR 4NT NOT 5 // status << "GRB10! With " & numAces & " Ace" & ((numAces > 1)? "s," : ",") & " respond to partner's Gerber inquiry with " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND1); // answered Aces, ready for Kings return TRUE; } // is partner asking for kings? if ((nGerberStatus == CONV_RESPONDED_ROUND1) && (bidState.nPartnersBid == BID_5C)) { // respond if ((numKings == 0) || (numKings == 4)) nBid = BID_5D; else if (numKings == 1) nBid = BID_5H; else if (numKings == 2) nBid = BID_5S; else if (numKings == 3) nBid = BID_5NT; // status << "GRB12! With " & numKings & " King" & ((numKings > 1)? "s," : ",") & " respond to partner's Gerber inquiry with " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND2); // Gerber complete return TRUE; } // no Gerber return FALSE; }
// //----------------------------------------------------- // // respond to partner's Jacoby 2NT Bid // BOOL CJacoby2NTConvention::RespondToConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // first see if another convention is active if ((bidState.GetActiveConvention() != NULL) && (bidState.GetActiveConvention() != this)) return FALSE; // // make a responding bid // int nPartnersBid = bidState.nPartnersBid; int nPreviousBid = bidState.nPreviousBid; int numTotalBidTurns = pDOC->GetNumBidsMade(); // int nBid; double fPts = bidState.fPts; double fCardPts = bidState.fCardPts; // // see what round this is // int nStatus = bidState.GetConventionStatus(this); if (nStatus == CONV_INACTIVE) { // // Bidding in response to partner's Jacoby 2NT bid? // // the requirements for a Jacoby 2NT Bid are: // 1: we must have opened the bidding with 1 of a major // 2: Partner responded with 2NT int nOpeningBid = pDOC->GetOpeningBid(); // test conditions if ( (bidState.m_numBidTurns == 1) && (ISMAJOR(BID_SUIT(nPreviousBid))) && (nOpeningBid == nPreviousBid) && (BID_LEVEL(nPreviousBid) == 1) && (bidState.nPartnersBid == BID_2NT) ) { // passed the test } else { return FALSE; } status << "J2N20! Partner has made a Jacoby 2NT inquiry bid, indicating " & OPEN_PTS(13) & " pts and 4+ card support.\n"; // adjust points as declarer int nSuit = bidState.nPreviousSuit; bidState.SetAgreedSuit(nSuit); fPts = bidState.fAdjPts = hand.RevalueHand(REVALUE_DECLARER, nSuit, TRUE); // partner has 13+ pts bidState.AdjustPartnershipPoints(13, 13); // // our options are as follows, in order: // // - with 18+ pts, rebid the suit at the 3 level // - with 15-17 pts and a strong 5-card side suit, bid that suit at the 4-level // - with 15-17 pts and a short suit, bid the short suit at the 3 level // - with 15-17 pts an no short suit, bid 3NT // - otherwise, sign off in game at the 4-level // check point count if (fPts >= 18) { nBid = MAKEBID(nSuit, 3); status << "J2N21! With " & fPts & " points in hand, " "respond to partner's Jacoby 2NT inquiry with a bid of " & BTS(nBid) & ".\n"; } else if (fPts >= 15) { // see if we have a strong side suit int nSideSuit = NONE; for(int i=0;i<4;i++) { if ((i != nSuit) && (bidState.nSuitStrength[i] <= SS_STRONG) && (bidState.numCardsInSuit[i] >= 5)) break; } // if (i < 4) { // bid the suit at the 4 level nSuit = i; nBid = MAKEBID(nSuit, 4); status << "J2N22! With " & fPts & " points in hand and a good " & bidState.numCardsInSuit[nSuit] & "-card suit in " & STS(nSuit) & ", respond to partner's Jacoby 2NT inquiry with " & BTS(nBid) & ".\n"; } else if (bidState.numVoids >= 1) { // bid the void suit for(nSuit=0;nSuit<4;nSuit++) { if (bidState.numCardsInSuit[nSuit] == 0) break; } nBid = MAKEBID(nSuit, 3); status << "J2N24! With " & fPts & " points in hand and a void suit in " & STS(nSuit) & ", respond to partner's Jacoby 2NT inquiry with a bid of " & BTS(nBid) & ".\n"; } else if (bidState.numSingletons >= 1) { // bid the singleton for(nSuit=0;nSuit<4;nSuit++) { if (bidState.numCardsInSuit[nSuit] == 1) break; } nBid = MAKEBID(nSuit, 3); status << "J2N26! With " & fPts & " points in hand and a singleton in " & STS(nSuit) & ", respond to partner's Jacoby 2NT inquiry with a bid of " & BTS(nBid) & ".\n"; } else { // bid 3NT nBid = BID_3NT; status << "J2N28! With " & fPts & " points in hand and no short suits, " " respond to partner's Jacoby 2NT inquiry with a bid of " & BTS(nBid) & ".\n"; } } else { // sign off at the 4-level nBid = MAKEBID(nSuit, 4); status << "J2N31! With only " & fPts & " points in hand, sign off in game at " & BTS(nBid) & ".\n"; } // and return bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // return FALSE; }
// //========================================================== // // Rebidding as opener after partner responds to an Jacoby 2NT Bid // BOOL CJacoby2NTConvention::HandleConventionResponse(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // check status if ((bidState.GetConventionStatus(this) != CONV_INVOKED_ROUND1) && (bidState.GetConventionStatus(this) != CONV_INVOKED_ROUND2)) return FALSE; // get some info // int nBid = NONE; int nPrevSuit = bidState.nPartnersPrevSuit; int nSuit = bidState.nPartnersSuit; int nPartnersBid = bidState.nPartnersBid; int nPartnersBidLevel = bidState.nPartnersBidLevel; int numSupportCards = bidState.numSupportCards; // // handling partner's Drury response // int nStatus = bidState.GetConventionStatus(this); if (nStatus == CONV_INVOKED) { // // here, our actions depend on partner's response // if (bidState.nPartnersBid == MAKEBID(nPrevSuit, 3)) { // partner responded in the suit at the 3-level, for 18+ pts status << "J2N40! Partner responded to our Jacoby 2NT inquiry by rebidding his " & STSS(nPrevSuit) & " suit at the 3-level, indicating " & OPEN_PTS(18) & "+ points.\n"; // revalue partnership totals bidState.AdjustPartnershipPoints(18, pCurrConvSet->GetValue(tn2ClubOpeningPoints)); } else if ((nPartnersBidLevel == 3) && ISSUIT(nSuit) && (nSuit != nPrevSuit)) { // partner responded in a different suit at the 3-level status << "J2N41! Partner responded to our Jacoby 2NT inquiry by bidding the " & STSS(nSuit) & " suit at the 3-level, indicating " & OPEN_PTS(15) & "-" & OPEN_PTS(17) & " points and a singleton or void in " & STS(nSuit) & ".\n"; // revalue partnership totals bidState.AdjustPartnershipPoints(15, 17); } else if (nPartnersBid == BID_3NT) { // partner responded with 3NT status << "J2N42! Partner responded to our Jacoby 2NT inquiry by bidding 3NT, indicating " & OPEN_PTS(15) & "-" & OPEN_PTS(17) & " points with a balanced hand.\n"; // revalue partnership totals bidState.AdjustPartnershipPoints(15, 17); } else if ((nPartnersBidLevel == 4) && ISSUIT(nSuit) && (nSuit != nPrevSuit)) { // partner responded in a different suit at the 4-level status << "J2N44! Partner responded to our Jacoby 2NT inquiry by bidding the " & STSS(nSuit) & " suit at the 4-level, indicating a strong 5-card side suit and " & OPEN_PTS(15) & "-" & OPEN_PTS(17) & " points in the hand.\n"; // revalue partnership totals bidState.AdjustPartnershipPoints(15, 17); } else if ((nPartnersBidLevel == 4) && (nSuit == nPrevSuit)) { // partner responded in the original suit at the 4-level status << "J2N44! Partner responded to our Jacoby 2NT inquiry by rebidding his " & STSS(nSuit) & " suit at the 4-level, indicating a minimum opener of approx. " & OPEN_PTS(12) & "-" & OPEN_PTS(14) & " points in the hand.\n"; // revalue partnership totals bidState.AdjustPartnershipPoints(12, 14); } else if ((nPartnersBid == BID_DOUBLE) || (nPartnersBid == BID_REDOUBLE)) { // the convention is cancelled! bidState.SetConventionStatus(this, CONV_ERROR); return FALSE; } // now figure out what to do if (bidState.m_fMinTPPoints >= PTS_SLAM) { // go to Blackwood status << "J2N60! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, push on to slam in partner's " & STSS(nPrevSuit) & " suit.\n"; bidState.InvokeBlackwood(nPrevSuit); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else if (bidState.m_fMinTPPoints >= PTS_MAJOR_GAME) { // we want to bid game if (nPartnersBid < bidState.GetGameBid(nPrevSuit)) { // raise or shift to game nBid = bidState.GetGameBid(nPrevSuit); status << "J2N62! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, go to game in " & STS(nPrevSuit) & " with a bid of " & BTS(nBid) & ".\n"; } else { // here partner bid game or higher -- pass unless it needs correction if (nSuit == nPrevSuit) { nBid = BID_PASS; status << "J2N64! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, pass partner's " & BTS(nPartnersBid) & " bid.\n"; } else { // correct to the original suit nBid = bidState.GetCheapestShiftBid(nPrevSuit, nPartnersBid); status << "J2N66! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we want to stop at game in " & STS(nPrevSuit) & "; correct partner's " & BTS(nPartnersBid) & " bid to " & BTS(nBid) & ".\n"; } } } else { // oops, caught with too few points // either pass 3NT , or return to the suit at the cheapest level possible if ((nPartnersBid == BID_3NT) || ((nSuit == nPrevSuit))) { nBid = BID_PASS; status << "J2N70! With a total of only " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we have to stop here at " & BTS(nPartnersBid) & ", so pass.\n"; } else { nBid = bidState.GetCheapestShiftBid(nPrevSuit, nPartnersBid); status << "J2N72! With a total of only " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we have to return to the " & STSS(nPrevSuit) & " and stop at " & BTS(nBid) & ".\n"; } } // done bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // oops! bidState.SetConventionStatus(this, CONV_ERROR); return FALSE; }
// //=============================================================================== // // TryConvention() // // check if we can use a Michaels Cue Bid here // BOOL CMichaelsCueBidConvention::TryConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // // the requirements for a Michaels Cue Bid are: // 1: RHO must have opened a suit (not NT) at the 1-level // 2: this must be our first bidding opportunity // 3: need a 2-suited hand; i.e., // - if RHO bid a minor, need 5/5 or 5/(good)4 in the majors // - if RHO bid a major, need 5 in the other major, plus 5 in a minor // the two suits should also be rather comparable // 4: need either 6-11 pts or 17+ pts // (with 12-16 pts, we generally overcall or double for takeout) // 5: if we have 12+ pts and playing takeout doubles, cannot have a // hand suitable for a takeout (???) // test conditions 1, 2, & 4 if ( ((bidState.nRHOBid >= BID_1C) && (bidState.nRHOBid <= BID_1S)) && ( ((bidState.fPts >= OPEN_PTS(6)) && (bidState.fPts <= OPEN_PTS(11))) || ((bidState.fPts >= OPEN_PTS(17))/*&& (bidState.fPts <= 18)*/) ) && (bidState.m_numBidTurns == 0) && (bidState.m_numPartnerBidTurns == 0) ) { // passed } else { return FALSE; } // test condition #3 int nOppSuit = bidState.nRHOSuit; BOOL bEnoughLength = FALSE; // if (ISMINOR(nOppSuit)) { // need 5/5 in the majors, or 5 + good 4 int numHearts = hand.GetNumCardsInSuit(HEARTS); int numSpades = hand.GetNumCardsInSuit(SPADES); if ((hand.GetSuitStrength(HEARTS) < SS_MARGINAL_OPENER) || (hand.GetSuitStrength(SPADES) < SS_MARGINAL_OPENER) || (Abs(hand.GetSuitStrength(HEARTS) - hand.GetSuitStrength(SPADES)) > 1) ) return FALSE; // if ((numHearts >= 5) && (numSpades >= 5)) { bEnoughLength = TRUE; status << "2MCL1! We have at least 5/5 in the majors, so we can make a Michaels cue bid.\n"; } else if ((numHearts >= 5) && (numSpades == 4) && (hand.GetSuitStrength(SPADES) >= SS_STRONG)) { bEnoughLength = TRUE; status << "2MCL2! We have 5/4 in the majors, but the 4 Spades are strong, so we can make a Michaels cue bid.\n"; } else if ((numHearts == 4) && (numSpades >= 5) && (hand.GetSuitStrength(HEARTS) >= SS_STRONG)) { bEnoughLength = TRUE; status << "2MCL3! We have 5/4 in the majors, but the 4 Hearts are strong, so we can make a Michaels cue bid.\n"; } } else { // need 5 in the unbid major, and 5 in a minor int nOtherMajor = (nOppSuit == HEARTS)? SPADES : HEARTS; int numMajors = hand.GetNumCardsInSuit(nOtherMajor); int numClubs = hand.GetNumCardsInSuit(CLUBS); int numDiamonds = hand.GetNumCardsInSuit(CLUBS); // check that the major suit is OK if ((numMajors < 5) || (hand.GetSuitStrength(nOtherMajor) < SS_MARGINAL_OPENER)) return FALSE; // then check the minor & compare the suits if ((numClubs >= 5) && (hand.GetSuitStrength(CLUBS) >= SS_MARGINAL_OPENER) && (Abs(hand.GetSuitStrength(nOtherMajor) - hand.GetSuitStrength(CLUBS)) <= 1) ) { bEnoughLength = TRUE; status << "2MCL5! We have 5+ cards in " & STS(nOtherMajor) & " and 5+ cards in a minor (Clubs), so we can make a Michaels cue bid.\n"; } else if ((numDiamonds >= 5) && (hand.GetSuitStrength(DIAMONDS) >= SS_MARGINAL_OPENER) && (Abs(hand.GetSuitStrength(nOtherMajor) - hand.GetSuitStrength(DIAMONDS)) <= 1) ) { bEnoughLength = TRUE; status << "2MCL5! We have 5+ cards in " & STS(nOtherMajor) & " and 5+ cards in a minor (Diamonds), so we can make a Michaels cue bid.\n"; } } // check condition if (!bEnoughLength) return FALSE; // OK, go ahead and cue-bid the enemy suit int nBid = MAKEBID(nOppSuit, 2); status << "MCL9! With a 2-suited hand, make a Michaels cue bid over RHO's " & STS(nOppSuit) & " with a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_INVOKED); return TRUE; }
// //----------------------------------------------------- // // respond to partner's Michaels Cue Bid // BOOL CMichaelsCueBidConvention::RespondToConvention(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // first see if another convention is active if ((bidState.GetActiveConvention() != NULL) && (bidState.GetActiveConvention() != this)) return FALSE; // // make a responding bid // int nPartnersBid = bidState.nPartnersBid; int nPartnersBidLevel = bidState.nPartnersBidLevel; int nPartnersSuit = bidState.nPartnersSuit; int nPartnersPrevSuit = bidState.nPartnersPrevSuit; // int nBid, nSuit; double fPts = bidState.fPts; double fCardPts = bidState.fCardPts; // // see what round this is // int nStatus = bidState.GetConventionStatus(this); if (nStatus == CONV_INACTIVE) { // // Bidding in response to partner's Michael's bid? check requirements // // the identifying marks of a Michaels bid are: // 1: we must not have bid yet // 2: LHO must have bid a suit at the 1 level, and // 3: partner overcalled LHO's suit at the 2 level int nLastValidBid = pDOC->GetLastValidBid(); // apply tests #1, 2, and 3 int nOpeningBid = pDOC->GetOpeningBid(); int nOpeningBidder = pDOC->GetOpeningBidder(); BOOL bLHOMajor = ISMAJOR(nOpeningBid); if (ISBID(nOpeningBid) && (GetPlayerTeam(nOpeningBidder) != player.GetTeam()) && ((nOpeningBid >= BID_1C) && (nOpeningBid <= BID_1S)) && (nPartnersSuit == bidState.nLHOSuit) && (nPartnersBidLevel == 2) && (bidState.m_numBidsMade == 0) ) { // status << "MCLR10! Partner has made a Michaels Cue bid of " & BTS(nPartnersBid) & ", indicating 5/5 length in " & (bLHOMajor? ((bidState.nLHOSuit == HEARTS)? "Spades and a minor" : "Hearts and a minor") : "the majors") & ".\n"; } else { return FALSE; } // did partner bid a minor, indicating both majors? if (ISMINOR(nPartnersSuit)) { // Pard has both majors -- pick the preferred one nSuit = bidState.PickSuperiorSuit(HEARTS, SPADES); if (hand.GetNumCardsInSuit(nSuit) < 3) { // should have at least 3 trumps int nOtherSuit = (nSuit == HEARTS)? SPADES : HEARTS; if (hand.GetNumCardsInSuit(nOtherSuit) >= 3) nSuit = nOtherSuit; } } else if (nPartnersSuit == HEARTS) { // pard has Spades + a minor // see if Spades are decent (3-card support) // if ((hand.GetNumCardsInSuit(SPADES) >= 3) && (hand.GetSuitStrength(SPADES) >= SS_MODERATE_SUPPORT)) if (hand.GetNumCardsInSuit(SPADES) >= 3) { // fine, go with Spades nSuit = SPADES; } else { // Spades are too weak; look for a minor if ((hand.GetSuitStrength(CLUBS) >= SS_MODERATE_SUPPORT) || (hand.GetSuitStrength(DIAMONDS) >= SS_MODERATE_SUPPORT)) nSuit = NOTRUMP; else nSuit = SPADES; // minors are no good either, so go with Spades } } else { // pard has Hearts + a minor // see if Hearts are decent (3-card support) // if ((hand.GetNumCardsInSuit(HEARTS) >= 3) && (hand.GetSuitStrength(HEARTS) >= SS_MODERATE_SUPPORT)) if (hand.GetNumCardsInSuit(HEARTS) >= 3) { // fine, go with Hearts nSuit = HEARTS; } else { // Spades are too weak; look for a minor if ((hand.GetSuitStrength(CLUBS) >= SS_MODERATE_SUPPORT) || (hand.GetSuitStrength(DIAMONDS) >= SS_MODERATE_SUPPORT)) nSuit = NOTRUMP; else nSuit = HEARTS; // minors are no good either, so go with Hearts } } // now adjust point count if (ISSUIT(nSuit)) { bidState.SetAgreedSuit(nSuit); fPts = bidState.fAdjPts = hand.RevalueHand(REVALUE_DECLARER, nSuit, TRUE); } // partner may have 6-11 OR 17+ pts; assume it's a weak hand bidState.AdjustPartnershipPoints(6, 11); // and make a responding bid CString strChoices = ISMINOR(nPartnersSuit)? "the two majors" : (nPartnersSuit == HEARTS)? "Spades and a minor" : "Hearts and an unknown minor"; int numTrumps = ISSUIT(nSuit)? hand.GetNumCardsInSuit(nSuit) : 0; // set initial convention status to finished bidState.SetConventionStatus(this, CONV_FINISHED); // see if we need to look at the minor if (nSuit == NOTRUMP) { // bid 2NT to ask for the minor nBid = BID_2NT; if (nBid > nLastValidBid) { if (nPartnersSuit == HEARTS) status << "MCLR12! Given a choice between a " & hand.GetNumCardsInSuit(SPADES) & "-card Spade suit and an unknown minor, we're forced to ask for the minor by bidding " & BTS(nBid) & ".\n"; else status << "MCLR12! Given a choice between a " & hand.GetNumCardsInSuit(HEARTS) & "-card Heart suit and an unknown minor, we're forced to ask for the minor by bidding " & BTS(nBid) & ".\n"; // this convention will go another round bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND1); } else { nBid = BID_PASS; status << "MCLR13! We'd like to bid 2NT to ask for partner's minor, but we can't do so after RHO's interference, so we have to pass.\n"; } } else if ((numTrumps >= 5) && (bidState.m_fMinTPPoints <= PT_COUNT(20)) && ISMAJOR(nSuit) && (MAKEBID(nSuit, 4) > nLastValidBid)) { // make a preemptive bid if possible nBid = MAKEBID(nSuit, 4); status << "MCLR15! With " & numTrumps & " " & STS(nSuit) & " and a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, make a shutout bid in " & STS(nSuit) & " by jumping to " & BTS(nBid) & ".\n"; } else if (bidState.m_fMinTPPoints <= PT_COUNT(21)) { // respond at the 2-level nBid = bidState.GetCheapestShiftBid(nSuit, nLastValidBid); if (BID_LEVEL(nBid) == 2) { status << "MCLR20! Given a choice between " & strChoices & ", respond to partner's Michaels with the preferred " & STSS(nSuit) & " suit with a bid of " & BTS(nBid) & ".\n"; } else { nBid = BID_PASS; status << "MCLR21! After RHO interference, we don't have the points to go to the 3-level in response to partner's Michaels, so pass.\n"; } } else if (bidState.m_fMinTPPoints <= PT_COUNT(24)) { // bid at the 3-level nBid = MAKEBID(nSuit, 3); if (nBid > nLastValidBid) { status << "MCLR24! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership and a choice between " & strChoices & ", invite game in " & STS(nSuit) & " by jumping to " & BTS(nBid) & ".\n"; } else { nBid = BID_PASS; status << "MCLR25! After RHO interference, we don't have the points to go to the 4-level in response to partner's Michaels, so pass.\n"; } } else if (ISMINOR(nSuit) && (bidState.m_fMinTPPoints <= PT_COUNT(27))) { // with 25+ pts, bid game nBid = bidState.GetGameBid(nSuit); if (nBid > nLastValidBid) { status << "MCLR27! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership and a choice between " & strChoices & ", jump to the 4-level in " & STS(nSuit) & " with a bid of " & BTS(nBid) & ".\n"; } else { nBid = BID_PASS; status << "MCLR28! After RHO interference, we don't have the points to go to the 5-level in response to partner's Michaels, so pass.\n"; } } else { // with 25+ pts in a major, or 28+ pts in a minor, bid game nBid = bidState.GetGameBid(nSuit); if (nBid > nLastValidBid) { status << "MCLR30! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership and a choice between " & strChoices & ", jump to game in " & STS(nSuit) & " at " & BTS(nBid) & ".\n"; } else { nBid = BID_PASS; status << "MCLR31! After RHO interference, we don't want to bid past game, so pass.\n"; } } // done! bidState.SetBid(nBid); return TRUE; } else if (nStatus == CONV_RESPONDED_ROUND1) { // // round 2 -- we must've bid 2NT last time to ask for partner's minor // // see if partner cue bid the enemy suit again if (nPartnersSuit == nPartnersPrevSuit) { // partner has 17+ pts bidState.AdjustPartnershipPoints(OPEN_PTS(17), MIN(17,40 - bidState.fCardPts)); // bid 4NT to ask for the minor again if (fPts >= PT_COUNT(15)) { // else make a natural game bid nBid = BID_4NT; status << "MCLR35! Partner cue bid the enemy suit again, indicating a strong Michaels opening hand with " & OPEN_PTS(17) & "+ pts; so with " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, ask for the other minor by bidding " & BTS(nBid) & ".\n"; bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND2); } else { // else make a natural 3NT game bid nBid = BID_3NT; status << "MCLR36! Partner cue bid the enemy suit again, indicating a strong Michaels opening hand with " & OPEN_PTS(17) & "+ pts; but with " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, stop at game with a natural bid of " & BTS(nBid) & ".\n"; bidState.SetConventionStatus(this, CONV_FINISHED); } // done bidState.SetBid(nBid); return TRUE; } // see if partner's bid is valid if (!ISMINOR(nPartnersSuit)) { status << "MCLR40! After his opening Michaels Cue Bid, partner did not respond properly to our 2NT minor suit inquiry, so michaels is off.\n"; bidState.SetConventionStatus(this, CONV_ERROR); return FALSE; } // see if we can live with partner's minor int nAgreedSuit; if (hand.GetNumCardsInSuit(nPartnersSuit) >= 3) { // stick with the minor status << "4MCLR41! Since we have " & hand.GetNumCardsInSuit(nPartnersSuit) & " cards in the " & STSS(nPartnersSuit) & " suit, choose that suit for our response.\n"; nAgreedSuit = nPartnersSuit; } else { // minor's not so great; select the better of the minor or the major nAgreedSuit = bidState.PickSuperiorSuit(nPartnersSuit, bidState.nPartnersPrevSuit); if (nAgreedSuit == nPartnersSuit) status << "4MCLR42! The " & STSS(nPartnersSuit) & " suit isn't great, but it's better than " & STS(bidState.nPartnersPrevSuit) & ", so choose that suit for our response.\n"; else status << "4MCLR43! The " & STSS(nPartnersSuit) & " suit is poor, so pick the major suit ("& STS(bidState.nPartnersPrevSuit) & ") for our response.\n"; bidState.SetAgreedSuit(bidState.PickSuperiorSuit(nPartnersSuit, bidState.nPartnersPrevSuit)); } // recalc points as dummy bidState.SetAgreedSuit(nAgreedSuit); fPts = bidState.fAdjPts = hand.RevalueHand(REVALUE_DECLARER, nAgreedSuit, TRUE); bidState.AdjustPartnershipPoints(); // select the bid level if (ISMINOR(nAgreedSuit)) { // Clubs or Diamonds if (bidState.m_fMinTPPoints <= PTS_MINOR_GAME-6) // <= 22 nBid = BID_PASS; else if (bidState.m_fMinTPPoints <= PTS_MINOR_GAME-4) // <= 24 nBid = MAKEBID(nPartnersBid, 4); else nBid = MAKEBID(nPartnersBid, 5); // go for game // if (nBid == BID_PASS) status << "MCLR45! Partner showed his minor to be " & STS(nPartnersSuit) & ", which we can support with " & hand.GetNumCardsInSuit(nPartnersSuit) & " trumps, but with only " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we have to pass.\n"; else status << "MCLR46! Partner showed his minor to be " & STS(nPartnersSuit) & ", which we can support with " & hand.GetNumCardsInSuit(nPartnersSuit) & " trumps, so with " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we bid " & BTS(nBid) & ".\n"; } else { // sticking with the major (though not a very good one!) // sign off at the 3-level or go to game if (bidState.m_fMinTPPoints < PTS_MAJOR_GAME) // < 25 nBid = MAKEBID(nPartnersBid, 3); else nBid = MAKEBID(nPartnersBid, 4); // if (BID_LEVEL(nBid) == 3) status << "MCLR47! With " & hand.GetNumCardsInSuit(nAgreedSuit) & "-card support for partner's " & STS(nAgreedSuit) & ", and with only " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we have to pass.\n"; else status << "MCLR47! With " & hand.GetNumCardsInSuit(nAgreedSuit) & "-card support for partner's " & STS(nAgreedSuit) & ", and with " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership, we can go to game at " & BTS(nBid) & ".\n"; } // done! bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else if (nStatus == CONV_RESPONDED_ROUND2) { // // round 3 -- we must've bid 4NT last time to ask for partner's minor // after partner's second Michaels cue bid // } // return FALSE; }