Пример #1
0
//
// GetCheapestKingOrVoid()
//
// returns the next cheapest suit with a king or void
//
int CCueBidConvention::GetCheapestKingOrVoid(CHandHoldings& hand, int nBaseSuit, int nSecondSuit)
{
	int i;
	//
	if (nBaseSuit < CLUBS)
		return NONE;
	//
	int nSuit;
	if (nBaseSuit == NOTRUMP)
		nSuit = CLUBS;
	else
		nSuit = GetNextSuit(nBaseSuit);
	for(i=0;i<4;i++) 
	{
		// suit should be void or else have a king
		if ( ((hand.GetSuitLength(nSuit) == 0) || hand.SuitHasCard(nSuit, KING)) &&
			 (nSuit != nSecondSuit) )
			break;
		nSuit = GetNextSuit(nSuit);
	}
	//
	if (i < 4)
		return nSuit;
	else
		return nBaseSuit;
}
Пример #2
0
//
//---------------------------------------------------------------
//
// HandleConventionResponse()
//
BOOL CCueBidConvention::HandleConventionResponse(const CPlayer& player, 
												 const CConventionSet& conventions, 
												 CHandHoldings& hand, 
												 CCardLocation& cardLocation, 
												 CGuessedHandHoldings** ppGuessedHands,
												 CBidEngine& bidState,  
												 CPlayerStatusDialog& status)
{
	// check state
	int nStatus = bidState.GetConventionStatus(this);
	if (nStatus <= 0)
		return FALSE;

	//
	int nPartnersBid = bidState.nPartnersBid;
	int nPartnersBidLevel = bidState.nPartnersBidLevel;
	int nPartnersSuit = bidState.nPartnersSuit;
	int nPreviousBid = bidState.nPreviousBid;
	int nAgreedSuit = bidState.m_nAgreedSuit;
	int nBid;

	//
	// first check if partner returned to the trump suit, regardless of 
	// which cue bidding round this is 
	//
	if ( ((nStatus == CONV_INVOKED_ROUND1) || (nStatus == CONV_INVOKED_ROUND2)) &&
						(nPartnersSuit == nAgreedSuit) )
	{
		// 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);
		}

		// first check for a direct raise to slam by partner in response to our
		// cue bid(unlikely, but hey...)
		if (nPartnersBidLevel >= 6)
		{
			status << "HRCB0! In response to our cue bid, partner returned to the agreed " & STSS(nAgreedSuit) &
					  " trump suit with a slam bid at " & BTS(nPartnersBid) & ".\n";
			// raise to a grand slam if possible
			if ((nPartnersBidLevel == 6) && (bidState.m_fMinTPPoints >= 37))
			{
				nBid = MAKEBID(nAgreedSuit,7);
				status << "HRCB1! And with " &
						  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
						  " points in the partnership, go ahead and raise to " &
						  BTS(nBid) & ".\n";
			}
			else
			{
				// sign off on the slam
				nBid = BID_PASS;
				status << "HRCB2! And with " &
						  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
						  " points in the partnership, sign off on the slam bid and pass.\n";
			}
			//
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		}

		//
		// otherwise partner returned to the agreed suit below slam, 
		// a discouraging sign
		//
		status << "HRCB5! Partner returned to the agreed " & STSS(nAgreedSuit) &
				  " trump suit in response to our cue bid of " & BTS(nPreviousBid) &
				  ", which is a discouraging sign.\n";
		// pass with < 33 team points
		if (bidState.m_fMinTPPoints < 33)
		{
			//
			nBid = BID_PASS;
			status << "HRCB6! And with only " & 
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership, we have to forget about slam and pass.\n" &
					  BTS(nBid) & ".\n";
		}
		else if (bidState.m_fMinTPPoints < 37)
		{
			// with 33-36 pts, bid small slam anyway
			nBid = MAKEBID(nAgreedSuit, 6);
			status << "HRCB7! But with " & 
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership, go ahead and bid a small slam anyway at " &
					  BTS(nBid) & ".\n";
		}
		else
		{
			// with 33-37 pts, bid a grand slam anyway
			nBid = MAKEBID(nAgreedSuit, 7);
			status << "HRCB8! But with " & 
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership, go ahead and bid a grand slam anyway at " &
					  BTS(nBid) & ".\n";
		}
		//
		bidState.SetBid(nBid);
		bidState.SetConventionStatus(this, CONV_FINISHED);
		return TRUE;
	}



	//
	//-----------------------------------------------------------------
	//
	// else partner made a responding cue bid, an encouraging sign
	// now see what stage we're at
	//
	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);
		}

		//
		status << "HRCB40! Partner responded with a cue bid of " & BTS(nPartnersBid) &
				  ", showing an Ace in " & STS(nPartnersSuit) & ".\n";
		//
		// see if we want to proceed to a second round of cue bidding
		// we need 36+ pts and controls in all four suits
		//
		BOOL bAllFourControls;
		if ((bidState.numAces + 1) == 4)
		{
			status << "HRCB42! And with partner's " & STSS(nPartnersSuit) & 
					  ", we have all four Aces for full first-round control.\n";
			bAllFourControls = TRUE;
		}
		else
		{
			status << "HRCB43! But even with partner's " & STSS(nPartnersSuit) & 
					  ", it's not clear we have all four Aces for full first-round control.\n";
			bAllFourControls = FALSE;
		}

		//
		if ((bidState.m_fMinTPPoints < PTS_SLAM) || (!bAllFourControls))
		{
			// gotta stop below slam
			nBid = bidState.GetCheapestShiftBid(nAgreedSuit);
			status << "HRCB46! With only " & 
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership" &
					  ((bAllFourControls)? "," : "and without clear first round controls,") &
					  " we can't afford to bid slam, so settle for a contract of " & 
					  BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		}
		// else we have >= 33 pts and all four controls
		else if (bidState.m_fMinTPPoints < 36)
		{
			// can only make a small slam
			nBid = MAKEBID(nAgreedSuit, 6);
			status << "HRCB46! But with only " & 
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership, we have to stop at a small with a contract of " &
					  BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		}

		//
		// at this point, we have 36+ points, so trigger another round of cue bidding
		// find cheapest king or void suit
		//
		int nSuit = GetCheapestKingOrVoid(hand, bidState.m_nAgreedSuit);
		if (nSuit != nAgreedSuit) 
		{
			// found a suit to cue bid for second round
			nBid = bidState.GetCheapestShiftBid(nSuit);
			status << "HRCB60! Make a second-round cue bid, showing the cheapest " &
					  ((hand.GetSuitLength(nSuit) == 0)? "void suit" : "king") &
					  " (in " & STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n";
		}
		else
		{
			// either we don't have any second-round control to show, or the
			// second round card is in the trump
			// so stop cue bidding and return to the trump suit at a small slam
			nBid = MAKEBID(nAgreedSuit, 6);
			status << "HRCB80! With no second-round controls to cue bid, we have to return to the trump suit with a small slam at " &
					  BTS(nBid) & ".\n";
		}
		//
		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);
		}

		//
		// both we and partner have shown first and second-round controls, 
		// so now it's time to put up or shut up
		//
		// if we like the controls and have enough points, bid grand slam;
		// else bid a small slam or game
		//
		//
		// see if we want to proceed to a second round of cue bidding
		// we need 36+ pts and controls in all four suits
		//
		BOOL bAllFourSecondRoundControls;
		if ((bidState.numKings + 1) == 4)
		{
			status << "HRCBS10! And with partner's " & STSS(nPartnersBid) & 
					  " bid showing a King or void, in " & STS(nPartnersSuit) &
					  ", we have scond-round control of all four suits.\n";
			bAllFourSecondRoundControls = TRUE;
		}
		else
		{
			status << "HRCBS12! But even with partner's " & STSS(nPartnersBid) & 
					  ", it's not clear we have all full second-round control.\n";
			bAllFourSecondRoundControls = FALSE;
		}

		//
		if ((bidState.m_fMinTPPoints < 32) || (!bAllFourSecondRoundControls))
		{
			// gotta stop below slam
			nBid = bidState.GetCheapestShiftBid(nAgreedSuit);
			status << "HRCBS20! With only " & 
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership " &
					  ((bAllFourSecondRoundControls)? "," : "and without clear second round controls,") &
					  " we can't afford to bid slam, so settle for a contract of " & 
					  BTS(nBid) & ".\n";
		}
		// else we have >= 32 pts and all four controls
		else if (bidState.m_fMinTPPoints < 36)
		{
			// can only make a small slam
			nBid = MAKEBID(nAgreedSuit, 6);
			status << "HRCBS24! But with only " & 
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership, we have to stop at a small with a contract of " &
					  BTS(nBid) & ".\n";
		}
		else
		{
			//
			// else we have 36+ points, so go ahead and bid a grand slam
			// 
			int nBid = MAKEBID(nAgreedSuit, 7);
			status << "HRCBS40! With a total of " &
					  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
					  " points in the partnership and full first and second-round controls, go head and bid a grand slam at " &
					  BTS(nBid) & ".\n";
		}
		//
		bidState.SetBid(nBid);
		bidState.SetConventionStatus(this, CONV_FINISHED);
		return TRUE;

	}
	else
	{	

		// N/A
		return FALSE;

	}
	//
	return TRUE;
}
Пример #3
0
//
//---------------------------------------------------------------
//
// TryCueBid()
//
BOOL CCueBidConvention::TryCueBid(CHandHoldings& hand, CBidEngine& bidState,  CPlayerStatusDialog& status)
{
	// check basic requirements
	if (bidState.m_nAgreedSuit == NONE)
		return FALSE;

	// don't make a cue bid if we're already done with it 
	int nStatus = bidState.GetConventionStatus(this);
	if (nStatus != CONV_INACTIVE)
		return FALSE;

	// get adjusted point count as declarer
	// NCR BIG PROBLEM HERE - This changes a global variable. The changes are now always wanted ???
	bidState.fAdjPts = hand.RevalueHand(REVALUE_DECLARER, bidState.m_nAgreedSuit, TRUE);
	bidState.m_fMinTPPoints = bidState.fAdjPts + bidState.m_fPartnersMin;
	bidState.m_fMaxTPPoints = bidState.fAdjPts + bidState.m_fPartnersMax;
	bidState.m_fMinTPCPoints = bidState.fCardPts + bidState.m_fPartnersMin;
	bidState.m_fMaxTPCPoints = bidState.fCardPts + bidState.m_fPartnersMax;

	//
	// try a cue bid only if we have an interest in slam 
	// 
	if (bidState.m_fMinTPPoints < 30)
		return FALSE;

	// also, we shouldn't use cue bid if we have all four aces
	if (bidState.numAces == 4)
		return FALSE;

	// or if we're already at a slam level
	if (bidState.nPartnersBidLevel >= 6)
		return FALSE;
	int nLastBid = pDOC->GetLastValidBid();
	if (nLastBid >= bidState.GetGameBid(BID_SUIT(nLastBid)))
		return FALSE;

	// special test -- dont' cue bid if partner just raised a suit that we
	// shifted to artificially
	if ((bidState.nPartnersSuit == bidState.nPreviousSuit) && 
				( (ISSUIT(bidState.m_nAgreedSuit) && (bidState.nPreviousSuit != bidState.m_nAgreedSuit)) ||
				  (ISSUIT(bidState.m_nIntendedSuit) && (bidState.nPreviousSuit != bidState.m_nIntendedSuit)) ) )
		return FALSE;


	//
	// see what stage we're at
	//
	if (nStatus == CONV_INACTIVE)
	{
		//
		// showing first round controls 
		//
//		bidState.SetConventionStatus(this, CONV_INVOKED_ROUND1);
		// find cheapest ace
		int nBid;
		int nAgreedSuit = bidState.m_nAgreedSuit;
		int nSuit = GetCheapestAce(hand, nAgreedSuit);

		// 
		if ((nSuit != bidState.m_nAgreedSuit) && (nSuit != bidState.nPartnersSuit))
		{
			// found a suit to cue bid
			// the bid must be at a level that commits the partnership to game
			// i.e., for a major, it must be > 3 of the suit; for a minor, > 4
			nBid = bidState.GetCheapestShiftBid(nSuit);
			int nBidLevel = BID_LEVEL(nBid);
			// see if the bid is too high to qualify as a cue bid
		    if ( (ISMAJOR(nAgreedSuit) && (nBidLevel >= 5)) ||
			     (ISMINOR(nAgreedSuit) && (nBidLevel >= 6)) )
				return FALSE;
			// else if it's too low, adjust it upwards
		    if ( (ISMAJOR(nAgreedSuit) && (nBid < MAKEBID(nAgreedSuit,3))) ||
			     (ISMINOR(nAgreedSuit) && (nBid < MAKEBID(nAgreedSuit,4))) )
				nBid += 5;
			// alternatively, see if the bid is too high
			if (nBid > bidState.GetGameBid(nAgreedSuit))
				return FALSE;
			status << "CUET10! With " & bidState.m_fMinTPPoints & 
					  "+ pts and possible slam aspirations, make a cue bid, showing the cheapest ace (" & 
					  STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_INVOKED_ROUND1);
			return TRUE;
		}
		else
		{
			// either we don't have any aces, or the ace is in the trump suit
			// either way, we can't make a cue bid with this holding
			return FALSE;
		}
	}
	else if (nStatus == CONV_INVOKED_ROUND1)
	{
		//
		// showing second round controls, necesary if we want to proceed to a grand slam
		//
		bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2);
		// find cheapest king or void suit
		int nSuit = GetCheapestKingOrVoid(hand, bidState.m_nAgreedSuit);
		int nPartnersBid = bidState.nPartnersBid;
		// 
		if (nSuit != bidState.m_nAgreedSuit) 
		{
			// found a suit to cue bid
			int nBid = bidState.GetCheapestShiftBid(nSuit);
			status << "CUET20! Make a second-round cue bid, showing the cheapest " &
					  ((hand.GetSuitLength(nSuit) == 0)? "void suit" : "king") &
					  " (in " & STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2);
			return TRUE;
		}
		else
		{
			// either we don't have any second-round control to show,
			// so stop cue bidding and return to the trump suit
			int nBid = bidState.GetCheapestShiftBid(bidState.m_nAgreedSuit);
			status << "CUET24! With no second-round controls to cue bid, we have to return to the trump suit at a bid of " &
					  BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_INVOKED_ROUND2);
			return TRUE;
		}
	}
	else if (nStatus == CONV_INVOKED_ROUND2)
	{
		// both we and partner have shown first and second-round controls, so
		// it;s time to put up or shut up
	}
	else
	{	
		// error!
		AfxMessageBox("Error while attempting cue bid!");
		bidState.SetConventionStatus(this, CONV_ERROR);
	}
	//
	return TRUE;
}
Пример #4
0
//
//---------------------------------------------------------------
//
// RespondToConvention()
//
BOOL CCueBidConvention::RespondToConvention(const CPlayer& player, 
											const CConventionSet& conventions, 
											CHandHoldings& hand, 
											CCardLocation& cardLocation, 
											CGuessedHandHoldings** ppGuessedHands,
											CBidEngine& bidState,  
											CPlayerStatusDialog& status)
{
	// first see if another convention is active
	if (bidState.GetActiveConvention() &&
							(bidState.GetActiveConvention() != this))
		return FALSE;

	// basic test -- see if we had agreed on a suit last time
	if (bidState.m_nAgreedSuit == NONE)
		return FALSE;

	// get status
	int nStatus = bidState.GetConventionStatus(this);

	//
	int nPartnersBid = bidState.nPartnersBid;
	int nPartnersBidLevel = bidState.nPartnersBidLevel;
	int nPartnersSuit = bidState.nPartnersSuit;
	int nPartnersPrevSuit = bidState.nPartnersPrevSuit;
	int nAgreedSuit = bidState.m_nAgreedSuit;
	int nSupportLevel = bidState.nPartnersSuitSupport;
	int nBid;

	// see if partner made a cue bid
	// it needs to be a bid that commits the partnership to game, 
	// after a suit has been agreed upon
	if ((nAgreedSuit != NONE) && (nPartnersSuit != NOTRUMP) && (nPartnersSuit != nAgreedSuit) &&
		((nPartnersBid > MAKEBID(nAgreedSuit,3)) && (nPartnersBid < bidState.GetGameBid(nAgreedSuit))))
	{
		//NCR what if suit was previously bid by this player???
		// EG: N->1H, S->2C, N->3C, S->3H  3H is NOT a cue bid, it's a response to this player's  previous bid
		// NCR how to test if partner's current bid was in suit previously bid ???
		// NCR what about a game bid???
		int nSuit =  BID_SUIT(nPartnersBid);
		for(int i=0; i < player.GetNumBidsMade(); i++) { // NCR had to add const to this function def
			int nSuitBid = pDOC->GetBidByPlayer(player.GetPosition(), i);
			if(BID_SUIT(nSuitBid) == nSuit)
				return FALSE;  // NCR not cue if partner bid before ???
		}
                                            // NCR-295 game bid in agreed suit???
		if(bidState.IsGameBid(nPartnersBid) && (nSuit == nAgreedSuit) ) // || CheckIfSuitBid(player, BID_SUIT(nPartnersBid))) 
		{
			return FALSE;  //NCR don't treat Game bid as cue bid
		}
		// met the requirements
		status << "CUR0! Partner made a cue bid of " & BTS(nPartnersBid) &
				  ", hinting at slam prospects.\n";
	}
	else
	{
		// this is not a cue bid
		return FALSE;
	}

	//
	// respond to a cue bid only if we have an interest in slam 
	// 
	// only qualify if we have 30+ team points, _OR_
	// strong trump support and 28+ poitns
	//
	if (bidState.m_fMinTPPoints >= 30)
	{
		// 30+ team points
		status << "2CUR1! And since we have " & 
				  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
				  "+ points in the partnership, we want to respond favorably.\n";
	}
	else if ((nSupportLevel >= SS_GOOD_SUPPORT) && 
								(bidState.m_fMinTPPoints >= 28))
	{
		// good support (4 good or 5 moderate cards)
		status << "2CUR2! And since we have " & bidState.SLTS(nPartnersSuit) &
				   " trump support, " & 
				   ((bidState.m_fMinTPPoints >= 30)? " as well as " : " albeit only with ") &
				   bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
				   " points in the partnership, we want to respond favorably.\n";
	}
	else
	{
		// insufficient strength for slam -- correct back to the agreed suit
		nBid = bidState.GetCheapestShiftBid(nAgreedSuit);
		status << "CUR4! But we don't have the points (only " & 
				  bidState.m_fMinTPPoints & "-" & bidState.m_fMaxTPPoints &
				  " pts in the partnership) or the excellent trump support needed for a marginal slam, so we decline by returning to the agreed suit at a bid of " &
				  BTS(nBid) & ".\n";
		bidState.SetBid(nBid);
		bidState.SetConventionStatus(this, CONV_FINISHED);
		return TRUE;
	}

	//
	// else we're playing along -- find the cheapest response
	//
	if (nStatus == CONV_INACTIVE)
	{
		// first invocation -- find the cheapest Ace
		int nSuit = GetCheapestAce(hand, nPartnersSuit, bidState.m_nAgreedSuit);
		// found a suit with an ace?
		if ((nSuit != nPartnersSuit) && (nSuit != nAgreedSuit)) 
		{
			// found a suit to cue bid
			nBid = bidState.GetCheapestShiftBid(nSuit);
			status << "CUR20! Respond to partner's cue bid, showing our cheapest ace (" &
					  STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND1);
			return TRUE;
		} 
		else 
		{
			// found no ace, or else it's in the trump suit, so either way
			// just sign off at the agreed suit
			nBid = bidState.GetCheapestShiftBid(nAgreedSuit);
			if (hand.SuitHasCard(nSuit, ACE))
				status << "CUR22! But our only Ace is in the trump suit of " &
						  STSS(nAgreedSuit) & ", so sign off at a bid of " & BTS(nBid) & ".\n";
			else
				status << "CUR24! We have no other Aces to offer, so sign off with the agreed " &
						  STSS(nAgreedSuit) & " suit at a bid of " & BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		}
	}
	else if (nStatus == CONV_RESPONDED_ROUND1)
	{
		// second invocation -- find cheapest King or void
		// first invocation -- find teh cheapest Ace
		int nSuit = GetCheapestKingOrVoid(hand, nPartnersSuit, bidState.m_nAgreedSuit);
		// found an appropriate suit?
		if ((nSuit != nPartnersSuit) && (nSuit != nAgreedSuit)) 
		{
			// found a suit to cue bid
			nBid = bidState.GetCheapestShiftBid(nSuit);
			status << "CUR30! Respond to partner's cue bid, showing our cheapest " &
					  ((hand.GetSuitLength(nSuit) > 0)? "King" : "void suit") &
					  " (in " & STS(nSuit) & ") with a bid of " & BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
//			bidState.SetConventionStatus(this, CONV_RESPONDED_ROUND2);
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		} 
		else 
		{
			// found no king or void, or else found a king in the trump suit, 
			// so either way, just sign off at the agreed suit
			nBid = bidState.GetCheapestShiftBid(nAgreedSuit);
			if (hand.SuitHasCard(nSuit, KING))
				status << "CUR32! But our only Ace is in the trump suit of " &
						  STSS(nAgreedSuit) & ", so sign off at a bid of " & BTS(nBid) & ".\n";
			else
				status << "CUR34 We have no other Kings or void suits to offer, so sign off with the agreed " &
						  STSS(nAgreedSuit) & " suit at a bid of " & BTS(nBid) & ".\n";
			bidState.SetBid(nBid);
			bidState.SetConventionStatus(this, CONV_FINISHED);
			return TRUE;
		}
	}
	else
	{
		// error!
		bidState.SetConventionStatus(this, CONV_ERROR);
		return FALSE;
	}
}