//
//==========================================================
//
// Rebidding as opener after a strong 2-level opening
//
//
BOOL CArtificial2ClubConvention::HandleConventionResponse(const CPlayer& player, 
													      const CConventionSet& conventions, 
														  CHandHoldings& hand, 
														  CCardLocation& cardLocation, 
														  CGuessedHandHoldings** ppGuessedHands,
														  CBidEngine& bidState,  
														  CPlayerStatusDialog& status)
{
	int nStatus = bidState.GetConventionStatus(this);
	if (nStatus <= 0)
		return FALSE;

	//
	// estimate partner's strength
	//
	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 nPartnersBid = bidState.nPartnersBid;
	int nPartnersBidLevel = bidState.nPartnersBidLevel;
	int nPartnersSuit = bidState.nPartnersSuit;
	int nPartnersSuitSupport = bidState.nPartnersSuitSupport;
	int numSupportCards = bidState.numSupportCards;
	BOOL bBalanced = bidState.bBalanced;
	BOOL bSemiBalanced = bidState.bSemiBalanced;


	// see if this is our first rebid
	if (nStatus == CONV_INVOKED_ROUND1)
	{
		// 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 get a negative response? (2D in response to the 2C)
		//
		if (nPartnersBid == BID_2D) 
		{
			status << "CRB0! After our strong 2 Club opening, partner's 2 Diamond bid is a negative response, denying slam values (less than 1 Quick Trick).\n";

			// estimate points -- 0 to 6 for now
			bidState.m_fPartnersMin = 0;
			bidState.m_fPartnersMax = 6;
			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;

			// bid game or slam with 26+ pts
			if ((bidState.m_fMinTPCPoints >= PTS_NT_GAME) && (bidState.m_fMinTPCPoints < PTS_SMALL_SLAM))
			{
				if (bBalanced || bSemiBalanced)
				{
					nBid = BID_3NT;
					status << "CRB1! With a balanced distribution and " &
							  fCardPts & " HCPs in hand, rebid " & BTS(nBid) & ".\n";
				}
				else if ( (ISMAJOR(nPrefSuit) && (bidState.m_fMinTPPoints >= PTS_MAJOR_GAME)) ||
						  (ISMINOR(nPrefSuit) && (bidState.m_fMinTPPoints >= PTS_MINOR_GAME)) )
				{
					nBid = bidState.GetGameBid(nPrefSuit);
					status << "CRB2! With no help from partner, we have to unilaterally push on to game at " & BTS(nBid) & ".\n";
				}
				bidState.SetConventionStatus(this, CONV_FINISHED);
			}
			else if ((bidState.m_fMinTPCPoints >= PTS_SMALL_SLAM) && (bidState.m_fMinTPCPoints < PTS_GRAND_SLAM))
			{
				if (bBalanced || bSemiBalanced)
				{
					nBid = BID_6NT;
					status << "CRB4! With a balanced distribution and " &
							  fCardPts & " HCPs in hand, bid a slam at " & BTS(nBid) & ".\n";
				}
				else
				{
					nBid = MAKEBID(nPrefSuit, 6);
					status << "CRB5! With no help from partner but with a total of " & bidState.m_fMinTPPoints &
							  " points in the partnership, we have to unilaterally push on to a slam at " & BTS(nBid) & ".\n";
				}
				bidState.SetConventionStatus(this, CONV_FINISHED);
			}
			else if (bidState.m_fMinTPCPoints >= PTS_GRAND_SLAM)
			{
				if (bBalanced || bSemiBalanced)
				{
					nBid = BID_7NT;
					status << "CRB6! With a balanced distribution and " &
							  fCardPts & " HCPs in hand, bid a grand slam at " & BTS(nBid) & ".\n";
				}
				else
				{
					nBid = MAKEBID(nPrefSuit, 7);
					status << "CRB5! With no help from partner but with a total of " & bidState.m_fMinTPPoints &
							  " points in the partnership, we have to unilaterally push on to a grand slam at " & BTS(nBid) & ".\n";
				}
				bidState.SetConventionStatus(this, CONV_FINISHED);
			}
			else
			{
				// else show our preferred suit and see if partner bids again
				nBid = bidState.GetCheapestShiftBid(nPrefSuit);
				status << "CRB8! Show our strongest suit (" & bidState.szPrefS &
						  ") with a bid of " & BTS(nBid) & ".\n";
				bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2);
			}
			//
			bidState.SetBid(nBid);
			return TRUE;
		}

		//
		// otherwise, we got a positive response, and partner has shown 
		// his long suit -- so either raise partner's suit, bid NT, or
		// rebid our own suit
		//
		status << "2CRB20! After our strong 2 Club opening, partner's " & bidState.szPB & 
				  " bid was a positive response, indicating 7+ pts and 1+ Quick Tricks.\n";

		// estimate points -- 7+ pts for now
		bidState.m_fPartnersMin = 7;
		bidState.m_fPartnersMax = MIN(22, 40 - fCardPts);
		bidState.m_fMinTPPoints = fAdjPts + bidState.m_fPartnersMin;
		bidState.m_fMaxTPPoints = fAdjPts + bidState.m_fPartnersMax;
		bidState.m_fMinTPCPoints = fCardPts + bidState.m_fPartnersMin;
		bidState.m_fMaxTPCPoints = fCardPts + bidState.m_fPartnersMax;

		// respond to partner's NT bid here
		// bid No Trump if reasonably balanced or have poor support
		if (nPartnersBid == BID_2NT) 
		{
			if ( bidState.bSemiBalanced ||
				 ((nPartnersSuitSupport <= SS_WEAK_SUPPORT) && (bBalanced)) )
			{
				if (bidState.m_fMinTPCPoints >= PTS_SLAM)
					nBid = BID_6NT;
				else
					nBid = BID_3NT;
				if (ISSUIT(nPartnersSuit))
					status << "CRB21! With a balanced hand and " & 
							  bidState.SLTS(nPartnersSuit) & " support for partner's " & bidState.szPS &
							  ", plus a total of " & bidState.m_fMinTPCPoints & "-" & bidState.m_fMaxTPCPoints &
							  " HCPs in the partnership, move to Notrump and bid " & 
							  ((BID_LEVEL(nBid) >= 6)? "slam" : "game") & " at " & BTS(nBid) & ".\n";
				else
					status << "CRB22! With a " & (!bBalanced? "semi-" : "") &
							  "balanced hand and a total of " & 
							  bidState.m_fMinTPCPoints & "-" & bidState.m_fMaxTPCPoints &
							  " HCPs in the partnership, raise partner to " & ((BID_LEVEL(nBid) >= 6)? "slam" : "game") &
							  " at " & BTS(nBid) & ".\n";
			}
			else
			{
				// we're not balanced, so show our preferred suit if possible
				nBid = bidState.GetCheapestShiftBid(nPrefSuit);
				status << "CRB25! We don't like Notrump, so so bid our " & 
						  bidState.szPrefS & " suit at " & BTS(nBid) & ".\n";
			}
			//
			bidState.SetBid(nBid);
			return TRUE;
		} 

		// raise partner's suit if possible
		if ((nPartnersSuit != NOTRUMP) && (nPartnersSuitSupport >= SS_GOOD_SUPPORT))
		{
			// double raise partner if major, or go directly to Blackwood
			// if minor (double raise from 3C or 3D would exceed 4NT
			if (ISMAJOR(nPartnersSuit))
			{
				bidState.m_nAgreedSuit = nPartnersSuit;
				nBid = bidState.GetGameBid(nPartnersSuit);
				BOOL bJumped = (nPartnersBidLevel == 2);
				status << "CRB28! With " & bidState.SLTS(nPartnersSuit) & 
						  " support for partner's " & bidState.szPS & 
						  " (holding " & bidState.szHP & 
						  "), go ahead and " & (bJumped? "jump" : "") & 
						  " raise to " & BTS(nBid) & ".\n";
				bidState.SetBid(nBid);
			}
			else
			{
				status << "CRB32! We have " & bidState.SLTS(nPartnersSuit) & 
						  " support for partner's " & bidState.szPS & 
						  " (holding " & bidState.szHP & "), so push towards slam.\n";
				bidState.InvokeBlackwood(nPartnersSuit);
				bidState.SetConventionStatus(this, CONV_FINISHED);
			}
			return TRUE;
		}

		// else show our preferred suit
		nBid = bidState.GetCheapestShiftBid(nPrefSuit);
		status << "CRB44! But we don't like partner's " & bidState.szPSS & 
				  " suit (holding " & bidState.szHP & "), so bid our own " & 
				  bidState.szPrefS & " suit at " & BTS(nBid) & ".\n";

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

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

		// partner bid another suit after our rebid of our suit 
		// AFTER her negative response to our opening strong 2C
		int nPartnersSuit = bidState.nPartnersSuit;
		if ((nPartnersSuit != NOTRUMP) && (nPartnersSuit != bidState.nPreviousSuit))
		{
			status << "CRB60! Partner bid " & bidState.szPB & " after we bid our " & bidState.szPVS & 
					  " suit, indicating a strong preference for the " & bidState.szPS & " suit.\n";
			
			// support partner's suit if we have decent holdings, else bid our own suit
			if (bidState.nPartnersBid < bidState.GetGameBid(nPartnersSuit))
			{
				// see if we like partner's suit
				if (bidState.nPartnersSuitSupport >= SS_GOOD_SUPPORT)
				{
					nBid = bidState.GetGameBid(nPartnersSuit);
					status << "CRB62! So with " & bidState.SLTS(nPartnersSuitSupport) & " support for partner's " &
							   bidState.szPS & ", raise to game at " & BTS(nBid) & ".\n";
				}
				else
				{
					nBid = bidState.GetCheapestShiftBid(bidState.nPreviousSuit);
					status << "CRB62! But with only " & bidState.SLTS(nPartnersSuitSupport) & " support for partner's " &
							   bidState.szPS & ", return to our own suit at " & BTS(nBid) & ".\n";
				}
			}
			else
			{
				// partner bid game!
				if (bidState.m_fMinTPPoints < PTS_SLAM)
				{
					// we don't have points for a slam, so pass
					nBid = BID_PASS;
					if (bidState.nPartnersBidLevel < 6)
						status << "CRB68! Partner's " & bidState.szPB & " bid is at game level, so pass.\n";
					else
						status << "CRB69! Partner's " & bidState.szPB & " bid is at slam level, so pass.\n";
				}
				else
				{
					// we do have the points for a slam!
					if (bidState.nPartnersBidLevel < 6)
					{
						nBid = BID_6NT;
						status << "CRB72! While we do not have suit agreement, we have the points for a slam, so bid " & 
								  BTS(nBid) & ".\n";
					}
					else
					{
						nBid = BID_PASS;
						status << "CRB74! Partner has bid slam in his suit, so pass.\n";
					}
				}
			}
		}
		else if (nPartnersSuit == NOTRUMP)
		{
			// partner bid NT
			// bid 3NT if possible
			if ( bidState.bSemiBalanced ||
				 ((nPartnersSuitSupport <= SS_WEAK_SUPPORT) && (bBalanced)) )
			{
				if (bidState.m_fMinTPCPoints >= PTS_SLAM)
					nBid = BID_6NT;
				else
					nBid = BID_3NT;
				if (ISSUIT(nPartnersSuit))
					status << "CRB76! With a balanced hand and " & 
							  bidState.m_fMinTPCPoints & "-" & bidState.m_fMaxTPCPoints &
							  " HCPs in the partnership, respond at " & 
							  ((BID_LEVEL(nBid) >= 6)? "slam" : "game") & " with a bid of " & BTS(nBid) & ".\n";
				else
					status << "CRB77! With a " & (!bBalanced? "semi-" : "") &
							  "balanced hand and a total of " & 
							  bidState.m_fMinTPCPoints & "-" & bidState.m_fMaxTPCPoints &
							  " HCPs in the partnership, raise partner to " & ((BID_LEVEL(nBid) >= 6)? "slam" : "game") &
							  " at " & BTS(nBid) & ".\n";
			}
			else
			{
				// we're not balanced, so show our preferred suit if possible
				nBid = bidState.GetCheapestShiftBid(nPrefSuit);
				status << "CRB78! We don't like Notrump, so so bid our " & 
						  bidState.szPrefS & " suit at " & BTS(nBid) & ".\n";
			}
			//
			bidState.SetBid(nBid);
			return TRUE;
		}
		else
		{
			// partner raised, which is strange!
			status << "CRB80! Partner raised our " & bidState.szPVSS & " suit, which is strange, ";
			if (bidState.nPartnersBid < bidState.GetGameBid(nPartnersSuit))
			{
				nBid = bidState.GetGameBid(bidState.nPartnersSuit);
				status << "but go ahead and raise to game.";
			}
			else
			{
				nBid = BID_PASS;
				status << "but since we're at game, stop here and pass.\n";
			}
		}

		// and we're done
		bidState.SetBid(nBid);
		bidState.SetConventionStatus(this, CONV_FINISHED);
		return TRUE;
	}
	
	// shouldn't be here!
	return FALSE;

}
//
//==========================================================
//
// 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;
	}
}
//
//==========================================================
//
// Rebidding as opener after partner responds to an Jacoby 2NT Bid
//
BOOL CJacoby2NTConvention::HandleConventionResponse(const CPlayer& player, 
													const CConventionSet& conventions, 
													CHandHoldings& hand, 
													CCardLocation& cardLocation, 
													CGuessedHandHoldings** ppGuessedHands,
													CBidEngine& bidState,  
													CPlayerStatusDialog& status)
{
	// check status
	if ((bidState.GetConventionStatus(this) != CONV_INVOKED_ROUND1) &&
		(bidState.GetConventionStatus(this) != CONV_INVOKED_ROUND2))
		return FALSE;

	// get some info
	//
	int nBid = NONE;
	int nPrevSuit = bidState.nPartnersPrevSuit;
	int nSuit = bidState.nPartnersSuit;
	int nPartnersBid = bidState.nPartnersBid;
	int nPartnersBidLevel = bidState.nPartnersBidLevel;
	int numSupportCards = bidState.numSupportCards;

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

	if (nStatus == CONV_INVOKED)
	{
		//
		// here, our actions depend on partner's response
		//
		if (bidState.nPartnersBid == MAKEBID(nPrevSuit, 3))
		{
			// partner responded in the suit at the 3-level, for 18+ pts
			status << "J2N40! Partner responded to our Jacoby 2NT inquiry by rebidding his " & 
					   STSS(nPrevSuit) & " suit at the 3-level, indicating " & 
					   OPEN_PTS(18) & "+ points.\n";

			// revalue partnership totals
			bidState.AdjustPartnershipPoints(18, pCurrConvSet->GetValue(tn2ClubOpeningPoints));
		}
		else if ((nPartnersBidLevel == 3) && ISSUIT(nSuit) && (nSuit != nPrevSuit))
		{
			// partner responded in a different suit at the 3-level
			status << "J2N41! Partner responded to our Jacoby 2NT inquiry by bidding the " & 
					   STSS(nSuit) & " suit at the 3-level, indicating " & OPEN_PTS(15) & "-" & OPEN_PTS(17) & 
					   " points and a singleton or void in " & STS(nSuit) & ".\n";

			// revalue partnership totals
			bidState.AdjustPartnershipPoints(15, 17);
		}
		else if (nPartnersBid == BID_3NT)
		{
			// partner responded with 3NT
			status << "J2N42! Partner responded to our Jacoby 2NT inquiry by bidding 3NT, indicating " &
					   OPEN_PTS(15) & "-" & OPEN_PTS(17) & " points with a balanced hand.\n";

			// revalue partnership totals
			bidState.AdjustPartnershipPoints(15, 17);
		}
		else if ((nPartnersBidLevel == 4) && ISSUIT(nSuit) && (nSuit != nPrevSuit))
		{
			// partner responded in a different suit at the 4-level
			status << "J2N44! Partner responded to our Jacoby 2NT inquiry by bidding the " & 
					   STSS(nSuit) & " suit at the 4-level, indicating a strong 5-card side suit and " & 
					   OPEN_PTS(15) & "-" & OPEN_PTS(17) & " points in the hand.\n";

			// revalue partnership totals
			bidState.AdjustPartnershipPoints(15, 17);
		}
		else if ((nPartnersBidLevel == 4) && (nSuit == nPrevSuit))
		{
			// partner responded in the original suit at the 4-level
			status << "J2N44! Partner responded to our Jacoby 2NT inquiry by rebidding his " & 
					   STSS(nSuit) & " suit at the 4-level, indicating a minimum opener of approx. " & 
					   OPEN_PTS(12) & "-" & OPEN_PTS(14) & " points in the hand.\n";

			// revalue partnership totals
			bidState.AdjustPartnershipPoints(12, 14);
		}
		else if ((nPartnersBid == BID_DOUBLE) || (nPartnersBid == BID_REDOUBLE))
		{
			// the convention is cancelled!
			bidState.SetConventionStatus(this, CONV_ERROR);
			return FALSE;
		}

		// now figure out what to do
		if (bidState.m_fMinTPPoints >= PTS_SLAM)
		{
			// go to Blackwood
			status << "J2N60! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " pts in the partnership, push on to slam in partner's " & STSS(nPrevSuit) & " suit.\n";
			bidState.InvokeBlackwood(nPrevSuit);
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		}
		else if (bidState.m_fMinTPPoints >= PTS_MAJOR_GAME)
		{
			// we want to bid game
			if (nPartnersBid < bidState.GetGameBid(nPrevSuit))
			{
				// raise or shift to game
				nBid = bidState.GetGameBid(nPrevSuit);
				status << "J2N62! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
						  " pts in the partnership, go to game in " & STS(nPrevSuit) &
						  " with a bid of " & BTS(nBid) & ".\n";
			}
			else
			{
				// here partner bid game or higher -- pass unless it needs correction
				if (nSuit == nPrevSuit)
				{
					nBid = BID_PASS;
					status << "J2N64! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
							  " pts in the partnership, pass partner's " & BTS(nPartnersBid) & " bid.\n";
				}
				else
				{
					// correct to the original suit
					nBid = bidState.GetCheapestShiftBid(nPrevSuit, nPartnersBid);
					status << "J2N66! With a total of " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
							  " pts in the partnership, we want to stop at game in " & STS(nPrevSuit) & 
							  "; correct partner's " & BTS(nPartnersBid) & " bid to " & BTS(nBid) & ".\n";
				}
			}
		}
		else
		{
			// oops, caught with too few points
			// either pass 3NT , or return to the suit at the cheapest level possible
			if ((nPartnersBid == BID_3NT) || ((nSuit == nPrevSuit)))
			{
				nBid = BID_PASS;
				status << "J2N70! With a total of only " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
						  " pts in the partnership, we have to stop here at " & BTS(nPartnersBid) &
						  ", so pass.\n";
			}
			else
			{
				nBid = bidState.GetCheapestShiftBid(nPrevSuit, nPartnersBid);
				status << "J2N72! With a total of only " & bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
						  " pts in the partnership, we have to return to the " & STSS(nPrevSuit) & 
						  " and stop at " & BTS(nBid) & ".\n";
			}
		}

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

	}

	// oops!
	bidState.SetConventionStatus(this, CONV_ERROR);
	return FALSE;
}
//
//==========================================================
//
// Rebidding as opener after a strong 2-level opening
//
//
BOOL CStrongTwoBidsConvention::HandleConventionResponse(const CPlayer& player, 
												        const CConventionSet& conventions, 
												        CHandHoldings& hand, 
												        CCardLocation& cardLocation, 
													    CGuessedHandHoldings** ppGuessedHands,
												        CBidEngine& bidState,  
												        CPlayerStatusDialog& status)
{
	if (bidState.GetConventionStatus(this) != CONV_INVOKED)
		return FALSE;
	bidState.ClearConventionStatus(this);

	//
	// estimate partner's strength
	//
	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 nPartnersBid = bidState.nPartnersBid;
	int nPartnersBidLevel = bidState.nPartnersBidLevel;
	int nPartnersSuit = bidState.nPartnersSuit;
	int nPartnersSuitSupport = bidState.nPartnersSuitSupport;
	int numSupportCards = bidState.numSupportCards;
	BOOL bBalanced = bidState.bBalanced;

	//
	// did we get a negative response from partner?
	//
	if (nPartnersBid == BID_2NT) 
	{
		status << "2S2Rb0! After our strong " & bidState.szPVB & 
			" opening bid, partner's 2NT bid is a negative response, denying slam values (less than 1 Quick Trick).\n";

		// estimate points -- 0 to 6 for now
		bidState.m_fPartnersMin = 0;
		bidState.m_fPartnersMax = 6;
		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;

		// after a negative response, bid 3NT if balanced
		// with 26+ HCPs
		if ((bBalanced) && (bidState.m_fMinTPCPoints >= PTS_NT_GAME)) 
		{
			nBid = BID_3NT;
			status << "S2RB1! With a balanced distribution and " &
					  fCardPts & " HCPs in hand, rebid " & BTS(nBid) & ".\n";
		}
		// else show a second preferred suit if available
		if (bidState.numPreferredSuits > 0) 
		{
			int nSuit = bidState.GetRebidSuit(nPreviousSuit);
			nBid = bidState.GetCheapestShiftBid(nSuit);
			status << "S2RB4! With a good second suit in " &
					  STS(nSuit) & ", show it in a rebid of " & BTS(nBid) & ".\n";
		}
		// otherwise rebid our original suit (if not 2C)
		if (bidState.nPreviousBid == BID_2C) 
		{
			nBid = bidState.GetCheapestShiftBid(nPrefSuit);
			status << "S2RB6! With no other good suits, go ahead and bid our " &
					  bidState.szPrefS & " suit at " & BTS(nBid) & ".\n";
		} 
		else 
		{
			nBid = bidState.GetCheapestShiftBid(nPreviousSuit);
			status << "B3E32! With no other good suits, go ahead and rebid our " &
					  bidState.szPVSS & " suit at " & BTS(nBid) & ".\n";
		}
		//
		bidState.SetBid(nBid);
		return TRUE;
	}
	
	//
	// otherwise, got a positive response, and partner has shown 
	// his long suit -- so either raise partner's suit, bid NT, or
	// rebid our own suit
	//
	status << "2S2Rb20! After our strong " & bidState.szPVB &
			  " opening bid, partner's " & bidState.szPB & 
			  " bid was a positive response, indicating 1+ Quick Tricks.\n";

	// estimate points -- 3+ pts for now
	bidState.m_fPartnersMin = 3;
	bidState.m_fPartnersMax = MIN(22, 40 - fCardPts);
	bidState.m_fMinTPPoints = fAdjPts + bidState.m_fPartnersMin;
	bidState.m_fMaxTPPoints = fAdjPts + bidState.m_fPartnersMax;
	bidState.m_fMinTPCPoints = fCardPts + bidState.m_fPartnersMin;
	bidState.m_fMaxTPCPoints = fCardPts + bidState.m_fPartnersMax;

	// bid No Trump if balanced
	if (bBalanced) 
	{
		nBid = BID_3NT;
		status << "With a balanced hand, bid game at " & BTS(nBid) & ".\n";
	} 
	// see if there's a suit agreement from a strong 2 bid
	if ((nPreviousSuit == nPartnersSuit) && (bidState.nLastBid != BID_2C)) 
	{
		// try for a slam; use Blackwood
		status << "S2RB24! Partner's encouraging raise to " & bidState.szPB & 
				  " indicates 1+ Quick Tricks and slam possibilities.\n";
		bidState.InvokeBlackwood(nPartnersSuit);
		return TRUE;
	}
	// raise partner's suit if possible
	if (nPartnersSuitSupport >= SS_GOOD_SUPPORT) 
	{
		// double raise partner if major, or go directly to Blackwood
		// if minor (double raise from 3C or 3D would exceed 4NT
		if (ISMAJOR(nPartnersSuit))
		{
			bidState.m_nAgreedSuit = nPartnersSuit;
			nBid = MAKEBID(nPartnersSuit,nPartnersBidLevel+2);
			status << "S2RB28! With " & bidState.SLTS(nPartnersSuit) & 
					  " support for partner's " & bidState.szPS & 
					  " (holding " & bidState.szHP & 
					  "), go ahead and jump raise to " & BTS(nBid) & ".\n";
		}
		else
		{
			status << "S2RB32! We have " & bidState.SLTS(nPartnersSuit) & 
					  " support for partner's " & bidState.szPS & 
					  " (holding " & bidState.szHP & 
					  ").\n";
			bidState.InvokeBlackwood(nPartnersSuit);
			return TRUE;
		}
	}

	// else show a second preferred suit if available
	if (bidState.numPreferredSuits > 1) 
	{
		int nSuit = bidState.GetRebidSuit(nPreviousSuit);
		nBid = bidState.GetCheapestShiftBid(nSuit);
		status << "S2RB36! But we don't like partner's " & bidState.szPSS & 
				  " suit (holding " & bidState.szHP & 
				  "), and we hold a good second suit in " & STS(nSuit) & 
				  ", so show it in a rebid of " & BTS(nBid) & ".\n";
	}
	// otherwise rebid our original suit (if not 2C)
	if (bidState.nPreviousBid == BID_2C) 
	{
		nBid = bidState.GetCheapestShiftBid(nPrefSuit);
		status << "S2RB44! But we don't like partner's " &
				  bidState.szPSS & " suit (holding " & bidState.szHP & 
				  "), so bid our own " & bidState.szPrefS & 
				  " suit at " & BTS(nBid) & ".\n";
	} 
	else 
	{
		nBid = bidState.GetCheapestShiftBid(nPreviousSuit);
		status << "S2RB50! But we don't like partner's " &
				  bidState.szPSS & " suit (holding " & bidState.szHP & 
				  "), so rebid our own " & bidState.szPVSS & 
				  " suit at " & BTS(nBid) & ".\n";
	}
	//
	bidState.SetBid(nBid);
	return TRUE;
}
//
//==========================================================
//
// 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;
}