// // FlashButton() // // used to temporarily flash a button's border // void CBidDialogSmall::FlashButton(int nBid) { // CWnd *pWnd1 = NULL, *pWnd2 = NULL; // if (ISBID(nBid)) { int nLevel = BID_LEVEL(nBid); int nSuit = BID_SUIT(nBid); pWnd1 = GetDlgItem(IDC_BID_LEVEL_1 + nLevel - 1); pWnd2 = GetDlgItem(IDC_SUIT_CLUBS + nSuit); } else if (nBid == BID_PASS) pWnd1 = GetDlgItem(IDC_BID_PASS); else if (nBid == BID_DOUBLE) pWnd1 = GetDlgItem(IDC_BID_DOUBLE); else if (nBid == BID_REDOUBLE) pWnd1 = GetDlgItem(IDC_BID_REDOUBLE); // if (pWnd1 == NULL) return; // FlashWindow(pWnd1, pWnd2); }
/** * @brief Set bid info for the play. * @param bid The contract. * @param bidDouble Double/redouble? * @param openLeader The open leader. */ void CPlayHistory::setBidInfo(Bids bid, Bids bidDouble, Seat openLeader) { this->openLeader = openLeader; resetPlayHistory(); this->bid = bid; trumpSuit = BID_SUIT(bid); level = BID_LEVEL(bid); this->bidDouble = bidDouble; }
int CGameRecord::DetermineRoundWinner(const int nRound) const { ASSERT((nRound >= 0) && (nRound < 13)); // can't determine winner if < 4 cards played in round) if (m_numCardsPlayed < ((nRound+1) * 4)) return -1; int nStart = nRound * 4; int nEnd = nStart + 4; int nTop = NONE; int nTopTrump = NONE; int nTopPos = NONE; BOOL bTrumpPlayed = FALSE; int nContractSuit = BID_SUIT(m_nContract); // int nPos = m_nRoundLead[nRound]; int nCardLed = m_nGameTrick[nRound][nPos]; int nSuitLed = CARDSUIT(nCardLed); // for(int i=nStart;i<nEnd;i++) { int nCard = m_nGameTrick[nRound][nPos]; int nSuit = CARDSUIT(nCard); int nFaceVal = FACEVAL(nCard); // if (nSuit == nContractSuit) { // a trump card was played -- see if it's high if (nFaceVal > nTopTrump) { nTopTrump = nFaceVal; nTopPos = nPos; bTrumpPlayed = TRUE; } } else if (!bTrumpPlayed) { // else if no trump was played so far, check if this card is high if ((nSuit == nSuitLed) && (nFaceVal > nTop)) { nTop = nFaceVal; nTopPos = nPos; } } // nPos = ::GetNextPlayer(nPos); } // ASSERT(nTopPos != NONE); return nTopPos; }
// // PressBidButton() // // used to make a button it appear pressed // void CBidDialogSmall::PressBidButton(int nBid) { // CButton *pButton1 = NULL, *pButton2 = NULL; // if (ISBID(nBid)) { int nLevel = BID_LEVEL(nBid); int nSuit = BID_SUIT(nBid); pButton1 = (CButton*) GetDlgItem(IDC_BID_LEVEL_1 + nLevel - 1); pButton2 = (CButton*) GetDlgItem(IDC_SUIT_CLUBS + nSuit); } else if (nBid == BID_PASS) pButton1 = (CButton*) GetDlgItem(IDC_BID_PASS); else if (nBid == BID_DOUBLE) pButton1 = (CButton*) GetDlgItem(IDC_BID_DOUBLE); else if (nBid == BID_REDOUBLE) pButton1 = (CButton*) GetDlgItem(IDC_BID_REDOUBLE); // if (pButton1 == NULL) return; // BOOL bWindow2Enabled = pButton2? pButton2->IsWindowEnabled() : FALSE; // pButton1->SetState(TRUE); if (pButton2) { pButton2->EnableWindow(TRUE); pButton2->SetState(TRUE); } // Sleep(300); // pButton1->SetState(FALSE); if (pButton2) { pButton2->SetState(FALSE); pButton2->EnableWindow(bWindow2Enabled); } // done return; }
// //=============================================================================== // // 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; }
// // SetGameIndex() // void CGameReviewDialog::SetGameIndex(int nGame, BOOL bRefresh) { if ((nGame < 0) || (nGame >= m_numGamesAvailable)) return; // init m_nGameIndex = nGame; m_nBidIndex = 0; m_nPlayIndex = 0; m_nPlayRound = 0; // fill tags list // first clear existing items m_listTags.DeleteAllItems(); // then add entries CGameRecord* pGameRecord = pDOC->GetGameRecord(m_nGameIndex); if (!pGameRecord) return; // fill the tags list int nIndex = 0; int nMaxWidth = 0; const int tnColSpacer = 14; CString strTag, strValue; std::map<CString,CString>::const_iterator iter; for(iter=pGameRecord->m_mapTagValues.begin();iter!=pGameRecord->m_mapTagValues.end();iter++) { // get the next tag & value strTag = (*iter).first; strValue = (*iter).second; // skip certain tags if ((strTag.CompareNoCase("Auction") == 0) || (strTag.CompareNoCase("Play") == 0)) continue; // set tag column m_listTags.InsertItem(nIndex, strTag); // set value column m_listTags.SetItem(nIndex, 1, LVIF_TEXT, strValue, 0, 0, 0, 0L); int nWidth = m_listTags.GetStringWidth(strValue) + tnColSpacer; if (nWidth > nMaxWidth) nMaxWidth = nWidth; nIndex++; } // set value column width m_listTags.SetColumnWidth(1, nMaxWidth); // m_nGameIndex = nGame; m_nPlayerPosition = pGameRecord->m_nRoundLead[0]; UpdateData(FALSE); // now update the display iter = pGameRecord->m_mapTagValues.find(_T("DEAL")); if (iter != pGameRecord->m_mapTagValues.end()) strValue = (*iter).second; pDOC->LoadGameRecord(*pGameRecord); if (bRefresh) pDOC->ResetDisplay(); pDOC->UpdateBiddingHistory(); pDOC->UpdatePlayHistory(); pMAINFRAME->SetAllIndicators(); // NCR-759 Check if this hand has data to show if(pDOC->GetDeclarerPosition() == NONE) { return; // No plays to make } // end NCR-759 // set prompt pMAINFRAME->SetMessageText(FormString("Contract is %s. Declarer is %s; %s leads.", pDOC->GetFullContractString(), PositionToString(pDOC->GetDeclarerPosition()), PositionToString(pDOC->GetRoundLead()))); // set game info m_numPlaysAvailable = pGameRecord->m_numCardsPlayed; if (m_numPlaysAvailable > 0) m_numTricksAvailable = ((m_numPlaysAvailable-1) / 4) + 1; else m_numTricksAvailable = 0; // reset suit sequence theApp.InitDummySuitSequence(BID_SUIT(pGameRecord->m_nContract), GetPartner(pGameRecord->m_nDeclarer)); // enable/disable play controls GetDlgItem(IDC_PREV)->EnableWindow(FALSE); GetDlgItem(IDC_FIRST)->EnableWindow(FALSE); if (m_numPlaysAvailable <= 1) { GetDlgItem(IDC_NEXT)->EnableWindow(FALSE); GetDlgItem(IDC_LAST)->EnableWindow(FALSE); } else { GetDlgItem(IDC_NEXT)->EnableWindow(TRUE); GetDlgItem(IDC_LAST)->EnableWindow(TRUE); } // and enable/disable game nav controls if (m_nGameIndex == 0) { GetDlgItem(IDC_PREV_GAME)->EnableWindow(FALSE); GetDlgItem(IDC_FIRST_GAME)->EnableWindow(FALSE); } else { GetDlgItem(IDC_PREV_GAME)->EnableWindow(TRUE); GetDlgItem(IDC_FIRST_GAME)->EnableWindow(TRUE); } // if (m_nGameIndex >= m_numGamesAvailable-1) { GetDlgItem(IDC_NEXT_GAME)->EnableWindow(FALSE); GetDlgItem(IDC_LAST_GAME)->EnableWindow(FALSE); } else { GetDlgItem(IDC_NEXT_GAME)->EnableWindow(TRUE); GetDlgItem(IDC_LAST_GAME)->EnableWindow(TRUE); } }
// //--------------------------------------------------------------- // // TryCueBid() // BOOL CCueBidConvention::TryCueBid(CHandHoldings& hand, CBidEngine& bidState, CPlayerStatusDialog& status) { // check basic requirements if (bidState.m_nAgreedSuit == NONE) return FALSE; // don't make a cue bid if we're already done with it int nStatus = bidState.GetConventionStatus(this); if (nStatus != CONV_INACTIVE) return FALSE; // get adjusted point count as declarer // NCR BIG PROBLEM HERE - This changes a global variable. The changes are now always wanted ??? bidState.fAdjPts = hand.RevalueHand(REVALUE_DECLARER, bidState.m_nAgreedSuit, TRUE); bidState.m_fMinTPPoints = bidState.fAdjPts + bidState.m_fPartnersMin; bidState.m_fMaxTPPoints = bidState.fAdjPts + bidState.m_fPartnersMax; bidState.m_fMinTPCPoints = bidState.fCardPts + bidState.m_fPartnersMin; bidState.m_fMaxTPCPoints = bidState.fCardPts + bidState.m_fPartnersMax; // // try a cue bid only if we have an interest in slam // if (bidState.m_fMinTPPoints < 30) return FALSE; // also, we shouldn't use cue bid if we have all four aces if (bidState.numAces == 4) return FALSE; // or if we're already at a slam level if (bidState.nPartnersBidLevel >= 6) return FALSE; int nLastBid = pDOC->GetLastValidBid(); if (nLastBid >= bidState.GetGameBid(BID_SUIT(nLastBid))) return FALSE; // special test -- dont' cue bid if partner just raised a suit that we // shifted to artificially if ((bidState.nPartnersSuit == bidState.nPreviousSuit) && ( (ISSUIT(bidState.m_nAgreedSuit) && (bidState.nPreviousSuit != bidState.m_nAgreedSuit)) || (ISSUIT(bidState.m_nIntendedSuit) && (bidState.nPreviousSuit != bidState.m_nIntendedSuit)) ) ) return FALSE; // // see what stage we're at // if (nStatus == CONV_INACTIVE) { // // showing first round controls // // bidState.SetConventionStatus(this, CONV_INVOKED_ROUND1); // find cheapest ace int nBid; int nAgreedSuit = bidState.m_nAgreedSuit; int nSuit = GetCheapestAce(hand, nAgreedSuit); // if ((nSuit != bidState.m_nAgreedSuit) && (nSuit != bidState.nPartnersSuit)) { // found a suit to cue bid // the bid must be at a level that commits the partnership to game // i.e., for a major, it must be > 3 of the suit; for a minor, > 4 nBid = bidState.GetCheapestShiftBid(nSuit); int nBidLevel = BID_LEVEL(nBid); // see if the bid is too high to qualify as a cue bid if ( (ISMAJOR(nAgreedSuit) && (nBidLevel >= 5)) || (ISMINOR(nAgreedSuit) && (nBidLevel >= 6)) ) return FALSE; // else if it's too low, adjust it upwards if ( (ISMAJOR(nAgreedSuit) && (nBid < MAKEBID(nAgreedSuit,3))) || (ISMINOR(nAgreedSuit) && (nBid < MAKEBID(nAgreedSuit,4))) ) nBid += 5; // alternatively, see if the bid is too high if (nBid > bidState.GetGameBid(nAgreedSuit)) return FALSE; status << "CUET10! With " & bidState.m_fMinTPPoints & "+ pts and possible slam aspirations, make a cue bid, showing the cheapest ace (" & STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_INVOKED_ROUND1); return TRUE; } else { // either we don't have any aces, or the ace is in the trump suit // either way, we can't make a cue bid with this holding return FALSE; } } else if (nStatus == CONV_INVOKED_ROUND1) { // // showing second round controls, necesary if we want to proceed to a grand slam // bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); // find cheapest king or void suit int nSuit = GetCheapestKingOrVoid(hand, bidState.m_nAgreedSuit); int nPartnersBid = bidState.nPartnersBid; // if (nSuit != bidState.m_nAgreedSuit) { // found a suit to cue bid int nBid = bidState.GetCheapestShiftBid(nSuit); status << "CUET20! Make a second-round cue bid, showing the cheapest " & ((hand.GetSuitLength(nSuit) == 0)? "void suit" : "king") & " (in " & STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); return TRUE; } else { // either we don't have any second-round control to show, // so stop cue bidding and return to the trump suit int nBid = bidState.GetCheapestShiftBid(bidState.m_nAgreedSuit); status << "CUET24! With no second-round controls to cue bid, we have to return to the trump suit at a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); return TRUE; } } else if (nStatus == CONV_INVOKED_ROUND2) { // both we and partner have shown first and second-round controls, so // it;s time to put up or shut up } else { // error! AfxMessageBox("Error while attempting cue bid!"); bidState.SetConventionStatus(this, CONV_ERROR); } // return TRUE; }
// //--------------------------------------------------------------- // // RespondToConvention() // BOOL CCueBidConvention::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() && (bidState.GetActiveConvention() != this)) return FALSE; // basic test -- see if we had agreed on a suit last time if (bidState.m_nAgreedSuit == NONE) return FALSE; // get status int nStatus = bidState.GetConventionStatus(this); // int nPartnersBid = bidState.nPartnersBid; int nPartnersBidLevel = bidState.nPartnersBidLevel; int nPartnersSuit = bidState.nPartnersSuit; int nPartnersPrevSuit = bidState.nPartnersPrevSuit; int nAgreedSuit = bidState.m_nAgreedSuit; int nSupportLevel = bidState.nPartnersSuitSupport; int nBid; // see if partner made a cue bid // it needs to be a bid that commits the partnership to game, // after a suit has been agreed upon if ((nAgreedSuit != NONE) && (nPartnersSuit != NOTRUMP) && (nPartnersSuit != nAgreedSuit) && ((nPartnersBid > MAKEBID(nAgreedSuit,3)) && (nPartnersBid < bidState.GetGameBid(nAgreedSuit)))) { //NCR what if suit was previously bid by this player??? // EG: N->1H, S->2C, N->3C, S->3H 3H is NOT a cue bid, it's a response to this player's previous bid // NCR how to test if partner's current bid was in suit previously bid ??? // NCR what about a game bid??? int nSuit = BID_SUIT(nPartnersBid); for(int i=0; i < player.GetNumBidsMade(); i++) { // NCR had to add const to this function def int nSuitBid = pDOC->GetBidByPlayer(player.GetPosition(), i); if(BID_SUIT(nSuitBid) == nSuit) return FALSE; // NCR not cue if partner bid before ??? } // NCR-295 game bid in agreed suit??? if(bidState.IsGameBid(nPartnersBid) && (nSuit == nAgreedSuit) ) // || CheckIfSuitBid(player, BID_SUIT(nPartnersBid))) { return FALSE; //NCR don't treat Game bid as cue bid } // met the requirements status << "CUR0! Partner made a cue bid of " & BTS(nPartnersBid) & ", hinting at slam prospects.\n"; } else { // this is not a cue bid return FALSE; } // // respond to a cue bid only if we have an interest in slam // // only qualify if we have 30+ team points, _OR_ // strong trump support and 28+ poitns // if (bidState.m_fMinTPPoints >= 30) { // 30+ team points status << "2CUR1! And since we have " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & "+ points in the partnership, we want to respond favorably.\n"; } else if ((nSupportLevel >= SS_GOOD_SUPPORT) && (bidState.m_fMinTPPoints >= 28)) { // good support (4 good or 5 moderate cards) status << "2CUR2! And since we have " & bidState.SLTS(nPartnersSuit) & " trump support, " & ((bidState.m_fMinTPPoints >= 30)? " as well as " : " albeit only with ") & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " points in the partnership, we want to respond favorably.\n"; } else { // insufficient strength for slam -- correct back to the agreed suit nBid = bidState.GetCheapestShiftBid(nAgreedSuit); status << "CUR4! But we don't have the points (only " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership) or the excellent trump support needed for a marginal slam, so we decline by returning to the agreed suit at a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // // else we're playing along -- find the cheapest response // if (nStatus == CONV_INACTIVE) { // first invocation -- find the cheapest Ace int nSuit = GetCheapestAce(hand, nPartnersSuit, bidState.m_nAgreedSuit); // found a suit with an ace? if ((nSuit != nPartnersSuit) && (nSuit != nAgreedSuit)) { // found a suit to cue bid nBid = bidState.GetCheapestShiftBid(nSuit); status << "CUR20! Respond to partner's cue bid, showing our cheapest ace (" & STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND1); return TRUE; } else { // found no ace, or else it's in the trump suit, so either way // just sign off at the agreed suit nBid = bidState.GetCheapestShiftBid(nAgreedSuit); if (hand.SuitHasCard(nSuit, ACE)) status << "CUR22! But our only Ace is in the trump suit of " & STSS(nAgreedSuit) & ", so sign off at a bid of " & BTS(nBid) & ".\n"; else status << "CUR24! We have no other Aces to offer, so sign off with the agreed " & STSS(nAgreedSuit) & " suit at a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } } else if (nStatus == CONV_RESPONDED_ROUND1) { // second invocation -- find cheapest King or void // first invocation -- find teh cheapest Ace int nSuit = GetCheapestKingOrVoid(hand, nPartnersSuit, bidState.m_nAgreedSuit); // found an appropriate suit? if ((nSuit != nPartnersSuit) && (nSuit != nAgreedSuit)) { // found a suit to cue bid nBid = bidState.GetCheapestShiftBid(nSuit); status << "CUR30! Respond to partner's cue bid, showing our cheapest " & ((hand.GetSuitLength(nSuit) > 0)? "King" : "void suit") & " (in " & STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); // bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND2); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else { // found no king or void, or else found a king in the trump suit, // so either way, just sign off at the agreed suit nBid = bidState.GetCheapestShiftBid(nAgreedSuit); if (hand.SuitHasCard(nSuit, KING)) status << "CUR32! But our only Ace is in the trump suit of " & STSS(nAgreedSuit) & ", so sign off at a bid of " & BTS(nBid) & ".\n"; else status << "CUR34 We have no other Kings or void suits to offer, so sign off with the agreed " & STSS(nAgreedSuit) & " suit at a bid of " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } } else { // error! bidState.SetConventionStatus(this, CONV_ERROR); 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);; }
// //========================================================== // // Rebidding as opener after partner responds to a takeout double // BOOL CNegativeDoublesConvention::HandleConventionResponse(const CPlayer& player, const CConventionSet& conventions, CHandHoldings& hand, CCardLocation& cardLocation, CGuessedHandHoldings** ppGuessedHands, CBidEngine& bidState, CPlayerStatusDialog& status) { // there's no code here for now return FALSE; // check status if ((bidState.GetConventionStatus(this) != CONV_INVOKED_ROUND1) && (bidState.GetConventionStatus(this) != CONV_INVOKED_ROUND2)) return FALSE; // // get some info // // int nBid; double fPts = bidState.fPts; double fAdjPts = bidState.fAdjPts; double fCardPts = bidState.fCardPts; int nPrefSuit = bidState.nPrefSuit; int nPrefSuitStrength = bidState.nPrefSuitStrength; int nPreviousSuit = bidState.nPreviousSuit; BOOL bBalanced = bidState.bBalanced; // int nPartnersBid = bidState.nPartnersBid; int nPartnersBidLevel = bidState.nPartnersBidLevel; int nPartnersSuit = bidState.nPartnersSuit; int nPartnersSuitSupport = bidState.nPartnersSuitSupport; int nPartnersPrevSuit = bidState.nPartnersPrevSuit; int numSupportCards = bidState.numSupportCards; // first check for a strange response if ((nPartnersBid == BID_DOUBLE) || (nPartnersBid == BID_REDOUBLE)) { // we don't understand partner's bid return CConvention::HandleConventionResponse(player, conventions, hand, cardLocation, ppGuessedHands, bidState, status); } // if (bidState.GetConventionStatus(this) == CONV_INVOKED_ROUND1) { // //-------------------------------------------------------- // responding to partner's forced bid // - estimate partner's strength // // // did partner pass? (horror of horrors!) // if (nPartnersBid == BID_PASS) { if (bidState.nLHOBid >= BID_PASS) status << "NGDRb10! After interference from the left-hand opponent, partner passed our takeout.\n"; else status << "NGDRb12! Partner unexpectedly passed our takeout double, which is supposed to be forcing. Bidding will proceed as if the takeout was not made\n"; bidState.SetConventionStatus(this, CONV_FINISHED); return FALSE; } // set team point estimates -- be conservative BOOL bPartnerJumped = FALSE; BOOL bPartnerJumpedToGame = FALSE; int nEnemyBid = pDOC->GetValidBidRecord(0); int nEnemyBidLevel = BID_LEVEL(nEnemyBid); int nEnemySuit = BID_SUIT(nEnemyBid); if (nPartnersBidLevel > (nEnemyBidLevel + 1)) bPartnerJumped = TRUE; if (nPartnersBid == bidState.GetGameBid(nPartnersSuit)) bPartnerJumpedToGame = TRUE; // flag to see if we doubled in preference to an overcall BOOL bWantedToOvercall = FALSE; // if (nPartnersSuit == NOTRUMP) { // if (nPartnersBid == BID_1NT) { // partner has 6-9 HCPs bidState.m_fPartnersMin = 6; bidState.m_fPartnersMax = 9; } else if (nPartnersBid == BID_2NT) { // partner has 10-12 HCPs, maybe more bidState.m_fPartnersMin = 10; bidState.m_fPartnersMax = 12; } else if (nPartnersBid == BID_3NT) { // partner has 13+ HCPs bidState.m_fPartnersMin = 13; bidState.m_fPartnersMax = 40 - fCardPts; status << "NGDRb20! Partner's response of 3NT to our takeout double indicates that the opponent's suit is well stopped.\n"; } else { // partner has 13+ HCPs??? status << "NGDRb21! Partner's response of " & BTS(nPartnersBid) & " to our takeout double is unorthodox; treating it like a 3NT response.\n"; bidState.m_fPartnersMin = 13; bidState.m_fPartnersMax = MIN(22, 40 - fCardPts); } // accept NT if we hold at least a semi-balanced // and we don't have a 6-card major if ( !(ISMAJOR(bidState.nPrefSuit) && (bidState.numPrefSuitCards >= 6)) && (bidState.bSemiBalanced) ) bidState.m_nAgreedSuit = NOTRUMP; // 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; status << "NGDRb29! Partner's response of " & BTS(nPartnersBid) & " to our takeout double indicates " & bidState.m_fPartnersMin & "-" & bidState.m_fPartnersMax & " HCPs, for a total of " & bidState.m_fMinTPCPoints & "-" & bidState.m_fMaxTPCPoints & " / " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts in the partnership.\n"; } else { // partner bid a suit // see if we really intended to overcall last time if (bidState.GetConventionStatus(&overcallsConvention) == CONV_SUBSUMED) bWantedToOvercall = TRUE; // if (nPartnersSuit == nEnemySuit) { // partner bid the enemy suit, showing 13+ pts. status << "NEGDRb40! Partner has responded in the enemy suit, indicating 13+ pts but no long suits.\n"; bidState.m_fPartnersMin = 13; bidState.m_fPartnersMax = MIN(22, 40 - bidState.fCardPts); bidState.m_bGameForceActive = TRUE; } else if (bPartnerJumpedToGame) { // partner had 13+ pts & a 5-card major status << "NEGDRb41! Partner has jumped to game in " & STS(nPartnersSuit) & ", indicating 13+ pts and a 5+ card suit.\n"; bidState.m_fPartnersMin = 30; bidState.m_fPartnersMax = MIN(22, 40 - bidState.fCardPts); if (!bWantedToOvercall) bidState.m_nAgreedSuit = nPartnersSuit; } else if (bPartnerJumped) { // partner had 10-12 pts status << "NEGDRb42! Partner has made a jump response of " & BTS(nPartnersBid) & ", indicating 10-12 pts and a 4-5 card suit.\n"; bidState.m_fPartnersMin = 10; bidState.m_fPartnersMax = 12; if (!bWantedToOvercall) bidState.m_nAgreedSuit = nPartnersSuit; } else { // partner had <= 9 pts status << "NEGDRb43! Partner has made a minimum response of " & BTS(nPartnersBid) & ", indicating no more than 9 points.\n"; bidState.m_fPartnersMin = 0; bidState.m_fPartnersMax = 9; if (!bWantedToOvercall) bidState.m_nAgreedSuit = nPartnersSuit; } // 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; status << "NGDRb49! The total point count in the partnership is therefore " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " pts.\n"; } // // see if RHO bid after partner's response -- that mitigates our responsibility // to bid again, unless partner's bid was game forcing // // if (bidState.nRHOBid > BID_PASS) if ((bidState.nRHOBid > BID_PASS) && (bidState.nRHOBid != BID_DOUBLE) && (bidState.nRHOBid != BID_REDOUBLE)) { status << "2NGDRb51! The right-hand opponent has " & ((bidState.nRHOBid == BID_DOUBLE)? "doubled" : "bid") & " after partner's response, interfering with our communication.\n"; } // //--------------------------------------------------------------------- // see if we have an agreed suit // int nBid; if (bidState.m_nAgreedSuit > NONE) { if (bidState.m_nAgreedSuit == NOTRUMP) { // we've agreed to play in NoTrump // see if we can raise partner to a higher NT contract if (bidState.BidNoTrumpAsAppropriate(FALSE,STOPPED_DONTCARE)) { bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // else pass nBid = BID_PASS; status << "NGDRb69! With a total of " & bidState.m_fMinTPCPoints & "-" & bidState.m_fMaxTPCPoints & " HCPs in the partnership, we have insufficient strength to raise partner's " & BTS(nPartnersBid) & " bid, so we have to pass.\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else { // we've agreed on a suit, so raise if possible // if partner didn't jump, we may have credited him with // zero pts, so adjust rqmts accordingly // if partner jumped to game && we have < 32 pts, pass if ((bPartnerJumpedToGame) && (bidState.m_fMinTPPoints < 32)) { status << "NGDRb70! Partner jumped to game in his " & bidState.szPSS & " suit, so with a team total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " points, we pass.\n"; bidState.SetBid(BID_PASS); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } // raise partner if possible -- bearing in mind that // partner may have a wide range of points // raise a major to game with 23-31 pts and 4 trumps // or with 26-31 pts and 3 trumps // or raise to the 3-level with 20-24 pts and 3 trumps if ( (bidState.RaisePartnersSuit(SUIT_MAJOR,RAISE_TO_4,PTS_MAJOR_GAME-3,31,SUPLEN_4)) || (bidState.RaisePartnersSuit(SUIT_MAJOR,RAISE_TO_4,PTS_MAJOR_GAME,31,SUPLEN_3)) || (bidState.RaisePartnersSuit(SUIT_MAJOR,RAISE_TO_3,PTS_MAJOR_GAME-6,24,SUPLEN_3))) { if (!bPartnerJumped) status << "NGDRb71a! (we can assume partner has some strength in the " & bidState.szPSS & " suit, so we are shading the requirements slightly.\n"; bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); return TRUE; } // raise a minor to game with 28-32 pts and 4 trumps // or with 29-32 pts and 3 trumps // or raise to the 4-level with 26-28 pts and 3 trumps // or raise to the 3-level with 23-25 pts and 3 trumps if ( (bidState.RaisePartnersSuit(SUIT_MINOR,RAISE_TO_5,PTS_MINOR_GAME-1,PTS_SLAM-1,SUPLEN_4)) || (bidState.RaisePartnersSuit(SUIT_MINOR,RAISE_TO_5,PTS_MINOR_GAME,PTS_SLAM-1,SUPLEN_3)) || (bidState.RaisePartnersSuit(SUIT_MINOR,RAISE_TO_4,PTS_MINOR_GAME-3,PTS_MINOR_GAME-1,SUPLEN_3)) || (bidState.RaisePartnersSuit(SUIT_MINOR,RAISE_TO_3,PTS_MINOR_GAME-6,PTS_MINOR_GAME-4,SUPLEN_3)) ) { if (!bPartnerJumped) status << "NGDRb71b! We can assume partner has some strength in the " & bidState.szPSS & " suit, so we can shade the requirements slightly.\n"; bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); return TRUE; } // with 32+ pts, invoke Blackwood if (bidState.m_fMinTPCPoints >= 32) { bidState.InvokeBlackwood(bidState.m_nAgreedSuit); bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); return TRUE; } // else pass nBid = BID_PASS; status << "NGDRb90! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints & " points in the partnership, we have insufficient strength to raise partner's " & BTS(nPartnersBid) & " bid, so we have to pass.\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } } // //-------------------------------------------------------------------------- // here, we have no suit agreement (e.g., partner bid the opponents' suit) // int nLastBid = pDOC->GetLastValidBid(); if (bBalanced) { // try notrumps if (hand.IsSuitProbablyStopped(nEnemySuit)) { status << "NGDRb80! Without clear suit agreement, and holding a blanaced hand, we want to steer towards a contract in No Trump.\n"; if (bidState.BidNoTrumpAsAppropriate(FALSE,STOPPED_DONTCARE)) { bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); return TRUE; } } // else pass status << "NGDRb81! But as we do not have a proper hand to bid No Trump at the appropriate level, we have to pass.\n"; bidState.SetBid(BID_PASS); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else if (bidState.numPrefSuitCards >= 5) { // bid the suit nBid = bidState.GetCheapestShiftBid(nPrefSuit, nLastBid); if (bidState.IsBidSafe(nBid, 4)) { if (bWantedToOvercall) status << "NGDRb90! Partner's forced response of " & bidState.szPB & " not withstanding, we can now show the " & STSS(nPrefSuit) & " suit that we wanted to overcall with last round by bidding " & BTS(nBid) & ".\n"; else status << "NGDRb91! Without clear suit agreement, we bid our " & bidState.numPrefSuitCards & "-card " & STSS(bidState.nPrefSuit) & " suit at " & BTS(nBid) & ".\n"; bidState.SetBid(nBid); bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2); return TRUE; } } // //-------------------------------------------------------------------------- // else we have no other options, so pass status << "NEGDRb99! We see no good fit with partner and no other options, so pass.\n"; bidState.SetBid(BID_PASS); bidState.SetConventionStatus(this, CONV_FINISHED); return TRUE; } else { // // responding after partner's second response to our takeout // // did partner pass? if (nPartnersBid == BID_PASS) { bidState.SetConventionStatus(this, CONV_FINISHED); return FALSE; } // // otherwise, consider the choices: // // - with suit agreement, raise if possible // S N S N S // e.g., X -> 1C -> 1S -> 2S -> ??? // - without suit agreement, // e.g., X -> 1C -> 1S -> 2H -? ??? // bid the 4th suit if we have the pts (26+) // - without suit agreement, but if partner bids NT, // or if we have a balanaced hand, bid NT // double fMinTPPoints = bidState.m_fMinTPPoints; double fMaxTPPoints = bidState.m_fMaxTPPoints; double fMinTPCPoints = bidState.m_fMinTPCPoints; double fMaxTPCPoints = bidState.m_fMaxTPCPoints; int nBid; // // see if we have suit agreement // if (nPartnersSuit == nPreviousSuit) { // partner raised our suit -- re-raise if possible bidState.m_nAgreedSuit = nPreviousSuit; if (nPartnersBid >= bidState.GetGameBid(nPreviousSuit)) { // partner bid game or beyond if ((nPartnersBidLevel == 7) || ((nPartnersBidLevel == 6) && (fMinTPPoints <= 36)) ) { nBid = BID_PASS; status << "NGDRc10! Partner raised our " & bidState.szPVSS & " suit to a slam, so pass.\n"; } else if ((nPartnersBidLevel <= 6) && (fMinTPPoints >= 37)) { nBid = MAKEBID(nPreviousSuit, 7); status << "NGDRc11! Partner raised our " & bidState.szPVSS & " suit to " & ((nPartnersBidLevel == 6)? "slam" : "game") & ", but we have the poitns to push to a grand slam, so bid " & BTS(nBid) & ".\n"; } else if ((nPartnersBidLevel < 6) && (fMinTPPoints >= 33)) { nBid = MAKEBID(nPreviousSuit, 6); status << "NGDRc12! Partner raised our " & bidState.szPVSS & " suit to game, but we have the poitns for a slam, so bid " & BTS(nBid) & ".\n"; } else { nBid = BID_PASS; status << "NGDRc13! Partner raised our " & bidState.szPVSS & " suit to game, which is acceptable with " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership, so pass.\n"; } } else { // partner raised below game // re-raise if possible if ( (ISMAJOR(nPreviousSuit) && (fMinTPPoints >= PTS_MAJOR_GAME)) || (ISMINOR(nPreviousSuit) && (fMinTPPoints >= PTS_MINOR_GAME)) ) { nBid = bidState.GetGameBid(nPreviousSuit); status << "NGDRc20! With a total of " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership, raise to game in the " & bidState.szPVSS & " suit at " & BTS(nBid) & ".\n"; } else { // else try to raise cheaply nBid = bidState.GetCheapestShiftBid(nPreviousSuit); if (bidState.IsBidSafe(nBid)) { status << "NGDRc22! With a total of " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership, we can raise again to " & BTS(nBid) & ".\n"; } else { nBid = BID_PASS; status << "NGDRc29! With a total of " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership, we cannot safely raise any partner further, so pass.\n"; } } } } else if ((nPartnersSuit == NOTRUMP) || (bidState.bBalanced)) { // // partner bid NT, or else we have a balanced hand // if (bidState.BidNoTrumpAsAppropriate(FALSE, STOPPED_DONTCARE)) { nBid = bidState.m_nBid; status << "NGDRc30! With a total of " & fMinTPCPoints & "-" & fMaxTPCPoints & " HCPs in the partnership, we can bid " & BTS(nBid) & ".\n"; } else { nBid = BID_PASS; if (nPartnersSuit == NOTRUMP) status << "NGDRc35! We're willing to accept a contract in NoTrumps, but don't have the points to raise further, so pass.\n"; else status << "NGDRc36! We'd like to play in NoTrumps, but don't have the points to bid agian, so pass.\n"; } } else { // // else we have no suit agreement, and can't play NT // // // bid the 4th suit if we have enough pts // int nSuit = bidState.GetFourthSuit(nPreviousSuit, nPartnersSuit, nPartnersPrevSuit); nBid = bidState.GetCheapestShiftBid(nSuit); if ((fMinTPPoints >= PTS_GAME) && (nBid < bidState.GetGameBid(nSuit))) { status << "NGDRc40! With a total of " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership and no suit agreement, bid another suit (" & STS(nSuit) & ") at " & BTS(nBid) & ".\n"; } else { // gotta pass nBid = BID_PASS; if (nPartnersBid >= bidState.GetGameBid(nPartnersSuit)) status << "NGDRc45! With a total of " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership, partner has gone to game in his suit at " & bidState.szPB & ", so pass.\n"; else if (fMinTPPoints >= PTS_GAME) status << "NGDRc46! With a total of " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership, but having run out of bidding room, we have to bail out and pass.\n"; else status << "NGDRc47! With a total of only " & fMinTPPoints & "-" & fMaxTPPoints & " pts in the partnership, and no agreement in suits, we have to pass.\n"; } } // done with the second rebid bidState.SetBid(nBid); bidState.ClearConventionStatus(this); 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; }
// //--------------------------------------------------------- // // PBN File output routine // BOOL CEasyBDoc::WriteFilePBN(CArchive& ar) { pFile = ar.GetFile(); ASSERT(pFile != NULL); // write header WriteComment(""); WriteComment("EXPORT"); WriteComment("PBN Format 1.0"); WriteComment(FormString("File generated by Easy Bridge version %s", theApp.GetProgramVersionString())); WriteComment(""); // // write the data // // Event tag WriteLine(TAG_EVENT, FormString("%s Game", theApp.GetValue(tstrProgramTitle))); // Site Tag WriteLine(TAG_SITE, "At Home"); // NCR added At Home // Date Tag CTime time = CTime::GetCurrentTime(); WriteLine(TAG_DATE, time.Format("%Y.%m.%d")); /* * skip the round tag -- no longer mandatory in PBN 0.91+ * // Round Tag WriteLine(TAG_ROUND, ""); */ // Board Tag WriteLine(TAG_BOARD, "1"); // NCR added 1 // West/North/East/South Tags WriteLine(TAG_WEST, "Computer"); WriteLine(TAG_NORTH, "Computer"); WriteLine(TAG_EAST, "Computer"); WriteLine(TAG_SOUTH, "Human Player"); // Dealer Tag WriteLine(TAG_DEALER, FormString("%c", PositionToChar(m_nDealer))); // Vulnerable Tag CString strVulnerable; if ((m_bVulnerable[NORTH_SOUTH]) && (m_bVulnerable[EAST_WEST])) strVulnerable = "Both"; else if (m_bVulnerable[NORTH_SOUTH]) strVulnerable = "NS"; else if (m_bVulnerable[EAST_WEST]) strVulnerable = "EW"; else strVulnerable = "None"; WriteLine(TAG_VULNERABLE, strVulnerable); // deal tag CString strDeal = "W:"; int nPos = WEST; int i; // NCR-FFS added here, removed below for(/*int*/ i=0;i<4;i++) { CCardHoldings& cards = m_pPlayer[nPos]->GetHand().GetInitialHand(); strDeal += cards.GetGIBFormatHoldingsString(); nPos = GetNextPlayer(nPos); if (i < 3) strDeal += ' '; } WriteLine(TAG_DEAL, strDeal); // Scoring tag if (theApp.IsRubberInProgress()) WriteLine(TAG_SCORING, _T("Rubber")); else WriteLine(TAG_SCORING, _T("None")); // Declarer Tag if (ISPOSITION(m_nDeclarer)) WriteLine(TAG_DECLARER, FormString("%c", PositionToChar(m_nDeclarer))); else WriteLine(TAG_DECLARER, "?"); // Contract Tag if (ISBID(m_nContract)) { // NCR Include ContractToString() here as PBN file does NOT have space before X CString strBid; strBid.Format("%d%s", BID_LEVEL(m_nContract), szSuitNameShort[BID_SUIT(m_nContract)]); int nModifier = pDOC->GetContractModifier(); if (nModifier > 0) strBid += FormString("%s", ((nModifier == 1)? "X" : "XX")); // w/o space WriteLine(TAG_CONTRACT, strBid); // NCR replaced ContractToString(m_nContract) } else WriteLine(TAG_CONTRACT, "?"); // Result tag if (m_numTricksPlayed == 13) WriteLine(TAG_RESULT, FormString("%d", m_numTricksWon[m_nContractTeam])); // NCR removed extra "s else WriteLine(TAG_RESULT, "?"); // // write out the hands in comment form // CString strHands = "{\r\n" + pDOC->FormatOriginalHands() + "}"; WriteLine(strHands); // // write out auction // CString strBids = FormString("[Auction \"%c\"]", PositionToChar(m_nDealer)); // NCR Lowercased if (m_numBidsMade > 0) strBids += "\r\n"; nPos = m_nDealer; for(i=0;i<m_numBidsMade;i++) { strBids += FormString("%s ", ::BidToPBNString(m_nBiddingHistory[i])); nPos = ::GetNextPlayer(nPos); if ( (((i+1) % 4) == 0) && (i < m_numBidsMade-1) ) strBids += "\r\n"; } // add marker if needed if (!ISBID(m_nContract)) strBids += "\r\n*"; // and write out WriteLine(strBids); // // write out plays // CString strPlays = FormString("[Play \"%c\"]", PositionToChar(m_nGameLead)); // NCR Lowercased if (m_numTricksPlayed> 0) strPlays += "\r\n"; bool bLastRowFnd = false; // NCR added - only output single row with -s for(i=0;i<m_numTricksPlayed;i++) { int nPos = m_nGameLead; for(int j=0;j<4;j++) { CCard* pCard = m_pGameTrick[i][nPos]; if (pCard == NULL) { strPlays += "- "; bLastRowFnd = true; // NCR this row will end the output } else strPlays += FormString("%s ", pCard->GetName()); nPos = ::GetNextPlayer(nPos); } // end for(j) thru poisitions if (i < m_numTricksPlayed-1) strPlays += "\r\n"; if(bLastRowFnd) break; // NCR finished output plays on line with -s } // end for(i) thru tricks // add marker if needed if (m_numTricksPlayed < 13) strPlays += "\r\n*"; // and write out WriteLine(strPlays); // Generator Tag WriteLine(TAG_GENERATOR, FormString("Easy Bridge version %s", theApp.GetProgramVersionString())); // Description Tag WriteLine(TAG_DESCRIPTION, m_strFileDescription); // blank line // SkipLine(); // // write out the auction // // // All done // ar.Flush(); return TRUE; }
void CBidDialogSmall::DisableControls() { int nLastBid = pDOC->GetLastValidBid(); int nLastBidLevel = BID_LEVEL(nLastBid); int nLastBidSuit = BID_SUIT(nLastBid); // check if a bid level has been specified if (m_nSelectedLevel == 0) { // if no bid level has been selected yet, disable the suits for(int i=IDC_SUIT_CLUBS;i<=IDC_SUIT_NOTRUMP;i++) GetDlgItem(i)->EnableWindow(FALSE); // and disable all lower bid levels if (nLastBidSuit == NOTRUMP) { // disble up to & including current level for(int i=IDC_BID_LEVEL_1;i<IDC_BID_LEVEL_1+nLastBidLevel;i++) GetDlgItem(i)->EnableWindow(FALSE); } else { // disble up to prev level for(int i=IDC_BID_LEVEL_1;i<IDC_BID_LEVEL_1+nLastBidLevel-1;i++) GetDlgItem(i)->EnableWindow(FALSE); } } else { // a bid level has been specified, so disable certain suits if ((m_nSelectedLevel == nLastBidLevel) && (nLastBidSuit != NOTRUMP)) { for(int i=IDC_SUIT_CLUBS;i<=IDC_SUIT_CLUBS+nLastBidSuit;i++) GetDlgItem(i)->EnableWindow(FALSE); } } // set defaults for double/redouble buttons BOOL bEnableDouble = TRUE; BOOL bEnableReDouble = FALSE; // can't double if no valid bids yet if (nLastBid <= BID_PASS) bEnableDouble = FALSE; // or if already doubled or redoubled if (pDOC->IsContractDoubled() || pDOC->IsContractRedoubled()) bEnableDouble = FALSE; // can't double own team's bid int nBidTeam = pDOC->GetLastValidBidTeam(); if ((nBidTeam == pDOC->GetCurrentPlayer()->GetTeam()) && !m_bTrainingMode) bEnableDouble = FALSE; // can redouble only if already doubled && is team contract (or is training) if (pDOC->IsContractDoubled() && ((nBidTeam == NORTH_SOUTH) || m_bTrainingMode)) bEnableReDouble = TRUE; // and set GetDlgItem(IDC_BID_DOUBLE)->EnableWindow(bEnableDouble); GetDlgItem(IDC_BID_REDOUBLE)->EnableWindow(bEnableReDouble); }
// //----------------------------------------------------- // // 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; }