//
//==========================================================
//
// Rebidding as opener after partner responds to a Michaels Cue Bid
//
BOOL CMichaelsCueBidConvention::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;
	double fPts = bidState.fPts;
	double fAdjPts = bidState.fAdjPts;
	double fCardPts = bidState.fCardPts;
	int nPrefSuit = bidState.nPrefSuit;
	int nPrefSuitStrength = bidState.nPrefSuitStrength;
	int nPreviousSuit = bidState.nPreviousSuit;
	int nPreviousBidLevel = bidState.nPreviousBidLevel;
	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;

	//
	// handling partner's Michaels response
	//
	int nStatus = bidState.GetConventionStatus(this);

	if (nStatus == CONV_INVOKED)
	{
		// 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 we're holding the STRONG Michaels hand indicate it by cue-bidding the
		// enemy suit again
		if (bidState.fPts >= PT_COUNT(17))
		{
			nBid = MAKEBID(nPreviousSuit, 3);
			status << "MCLRH12! with a strong Michaels hand (" & bidState.fPts & 
					  " pts), cue bid the enemy suit again at " & BTS(nBid) & 
					  " to indicate our strength.\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2);
			return TRUE;
		}

		// did partner bid 2NT, asking for the minor?
		if (ISMAJOR(nPreviousSuit) && (nPartnersBid == BID_2NT))
		{
			// with a weak Michaels opener, indicate the minor
			int nSuit = bidState.GetLongerSuit(CLUBS, DIAMONDS);
			nBid = MAKEBID(nSuit, 3);
			status << "MCLRH10! With the weak flavor of Michaels, respond to partner's Michaels minor inquiry with a bid of " & BTS(nBid) &
					  ", indicating " & STS(nSuit) & " as the unknown minor.\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2);
			return TRUE;
		}

		// did partner cue-bid the enemy suit (a slam try)?
		if ((nPartnersSuit == nPreviousSuit) && (nPartnersBidLevel == nPreviousBidLevel+1))
		{
			// determine the cheapest of the two suits
			int nCheapestSuit;
			if (ISMINOR(nPreviousSuit))
				nCheapestSuit = HEARTS;		// 5/5 in the majors, so Hearts is cheapest
			else
				nCheapestSuit = bidState.GetLongerSuit(CLUBS, DIAMONDS);

			// respond affirmatively only with a strong hand
			status << "2MCLRH20! Partner cue bid the enemy suit, which is a game or slam try.\n";
			if (bidState.fPts >= PT_COUNT(17))
			{
				// jump into Blackwood
				status << "MCLRH21! And with " & bidState.fPts & " pts in hand, proceed towards slam in the preferred "&
						  STSS(bidState.nPrefSuit) & " suit.\n";
				bidState.InvokeBlackwood(bidState.nPrefSuit);
			}
			else if ( (ISMAJOR(nCheapestSuit) && (bidState.fPts >= PT_COUNT(9))) ||
				(ISMINOR(nCheapestSuit) && (bidState.fPts >= PT_COUNT(12))) )
			{
				// stop at game in the cheapest suit
				nBid = bidState.GetGameBid(nCheapestSuit);
				status << "MCLRH22! But with only " & bidState.fPts & " pts in hand, forget about slam and stop at game in the cheapest suit ("&
						  STS(nCheapestSuit) & ") at " & BTS(nBid) & ".\n";
				bidState.SetBid(nBid);
			}
			else 
			{
				// 8 or fewer pts -- bail out in the cheapest suit
				nBid = bidState.GetCheapestShiftBid(nCheapestSuit);
				status << "MCLRH23! But with only " & bidState.fPts & " pts in hand, forget about slam and bail out in the cheapest suit (" &
						  STS(nCheapestSuit) & ") at " & BTS(nBid) & ".\n";
				bidState.SetBid(nBid);
			}
			// done
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		}

		//
		// else partner made a signoff, invitational, or game bid
		//
		if (bidState.IsGameBid(nPartnersBid))
		{
			status << "MCLRH30! Partner responded to our Michaels Cue bid with a game bid of " & 
					  bidState.szPB & ", so we should pass.\n";
			nBid = BID_PASS;	
		}
		else if (nPartnersBid != BID_PASS) 
		{
			// see if we should raise partner to game
			status << "2MCLRH40! Partner responded to our Michaels Cue bid with a bid of " & 
					  bidState.szPB & ", a possible invitation to game.\n";
			// go to game with 17+ pts (strong hand)
			if (fPts < PT_COUNT(17))
			{
				nBid = BID_PASS;	
				status << "MCLRH41! But since we opened Michaels with a weak hand (" & fPts &
						  ") pts, we likely do not have the points for game and have to pass.\n";
			}
			else
			{
				nBid = bidState.GetGameBid(nPartnersSuit);	
				status << "MCLRH42! and since we opened Michaels with a strong hand (" & fPts &
						  ") pts, we can raise to game at " & BTS(nBid) & ".\n";
			}
		}
		else
		{
			status << "2MCLRH49! Partner passed" & (bidState.bLHOInterfered? "after opponents interference" : "") &
					  ", so Michaels is off.\n";
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return FALSE;
		}

		// done
		bidState.SetBid(nBid);
		bidState.SetConventionStatus(this, CONV_FINISHED);
		return TRUE;

	}
	else if (nStatus == CONV_INVOKED_ROUND2)
	{
		// last time, we either showed our minor suit or indicated our strength 
		// with another cue bid of the opponents' suit

		// 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);
		}

		// did we have the strong hand?
		if (bidState.fPts >= PT_COUNT(17))
		{
			// see what partner's reaction was
			if (nPartnersSuit == BID_4NT)
			{
				// parter still wants to see our minor!!!
				int nSuit = bidState.GetLongerSuit(CLUBS, DIAMONDS);
				nBid = bidState.GetCheapestShiftBid(nSuit);
				status << "MCLRH50! After our second Michaels cue bid of the enemy suit, partner still wants to see the unknown minor, so show it (" &
						  STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n";
				bidState.SetBid(nBid);
				bidState.SetConventionStatus(this, CONV_INVOKED_ROUND3);
				return TRUE;
			}

			// else partner's bid was natural
			if (bidState.IsGameBid(nPartnersBid))
			{
				if (fPts < PT_COUNT(20))
				{
					status << "MCLRH55! Partner responded to our second Michaels cue bid with a game bid of " & 
							  bidState.szPB & ", so we should pass.\n";
					nBid = BID_PASS;
				}
				else
				{
					// jump to slam
					nBid = MAKEBID(nPartnersSuit, 6);
					status << "MCLRH55! Partner responded to our second Michaels cue bid with a game bid of " & 
							  bidState.szPB & ", and with " & fPts & "+ in hand, we can go ahead and jump to slam at " & BTS(nBid) & ".\n";
				}
			}
			else if (nPartnersBid != BID_PASS)
			{
				// see if we should raise partner to game
				nBid = bidState.GetGameBid(nPartnersSuit);
				status << "MCLRH56! Partner responded to our second Michaels cue bid of the enemy suit with a bid of " & 
						  bidState.szPB & ", an invitation to game -- so go ahead and bid game at " & BTS(nBid) & ".\n";
			}
			else
			{
				if (bidState.bLHOInterfered)
					status << "MCLRH58! Partner passed our second Michaels cue bid after interference, so we have to pass also.\n";
				else
					status << "MCLRH59! Partner passed in spite of our second Michaels cue bid, so we should pass also.\n";
				nBid = BID_PASS;
			}
		}
		else
		{
			// partner responded to our minor answer
			if (bidState.IsGameBid(nPartnersBid))
			{
				status << "MCLRH60! Partner responded to our Michaels minors answer with a game bid of " & 
						  bidState.szPB & ", so we should pass.\n";
				nBid = BID_PASS;
			}
			else if (nPartnersBid != BID_PASS)
			{
				// see if we should raise partner to game
				status << "MCLRH70! Partner responded to our Michaels minor answer with a bid of " & 
						  bidState.szPB & ", a possible invitation to game.\n";

				// go to game with 17+ pts (strong hand)
				if (fPts < PT_COUNT(17))
				{
					nBid = BID_PASS;	
					status << "MCLRH72! But since we opened Michaels with a weak hand (" & fPts &
							  ") pts, we likely do not have the points for game and have to pass.\n";
				}
				else
				{
					nBid = bidState.GetGameBid(nPartnersSuit);	
					status << "MCLRH72! and since we opened Michaels with a strong hand (" & fPts &
							  ") pts, we can raise to game at " & BTS(nBid) & ".\n";
				}
			}
			else
			{
				if (bidState.bLHOInterfered)
					status << "MCLRH75! Partner passed our Michaels minor answer after interference, so we have to pass also.\n";
				else
					status << "MCLRH76! Partner passed our Michaels minor answer, so we should pass also.\n";
				nBid = BID_PASS;
			}
		}

		// done
		bidState.SetBid(nBid);
		bidState.SetConventionStatus(this, CONV_FINISHED);
		return TRUE;

	}
	else if (nStatus == CONV_INVOKED_ROUND3)
	{
		// 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);
		}

		// we indicated our strength with another cue bid, and partner asked
		// to see our minor, _then_ bid
		if (bidState.IsGameBid(nPartnersBid))
		{
			if (fPts < PT_COUNT(20))
			{
				status << "MCLRH80! Partner responded to our Michaels minor answer with a game bid of " & 
						  bidState.szPB & ", so we should pass.\n";
				nBid = BID_PASS;
			}
			else
			{
				// jump to slam
				nBid = MAKEBID(nPartnersSuit, 6);
				status << "MCLRH81! Partner responded to our Michaels minor answer with a game bid of " & 
						  bidState.szPB & ", and with " & fPts & "+ in hand, we can go ahead and jump to slam at " & BTS(nBid) & ".\n";
			}
		}
		else if (nPartnersBid != BID_PASS)
		{
			// see if we should raise partner to game
			nBid = bidState.GetGameBid(nPartnersSuit);
			status << "MCLRH85! Partner responded to our Michaels minor answer with a bid of " & 
					  bidState.szPB & ", an invitation to game -- so go ahead and bid game at " & BTS(nBid) & ".\n";
		}
		else
		{
			if (bidState.bLHOInterfered)
				status << "MCLRH86! Partner passed our Michaels minor answer after interference, so we have to pass also.\n";
			else
				status << "MCLRH87! Partner passed in spite of our Michaels minor answer, so we should pass also.\n";
			nBid = BID_PASS;
		}

		// done (finally!)
		bidState.SetBid(nBid);
		bidState.SetConventionStatus(this, CONV_FINISHED);
		return TRUE;
	}

	// oops!
	bidState.SetConventionStatus(this, CONV_ERROR);
	return FALSE;
}
Exemplo n.º 2
0
//
//---------------------------------------------------------------
//
// 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);;				

}
//
//-----------------------------------------------------
//
// 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;
}