コード例 #1
0
//
//===============================================================================
//
// TryConvention()
//
// check if we can use a Michaels Cue Bid here
//
BOOL CMichaelsCueBidConvention::TryConvention(const CPlayer& player, 
											  const CConventionSet& conventions, 
											  CHandHoldings& hand, 
											  CCardLocation& cardLocation, 
											  CGuessedHandHoldings** ppGuessedHands,
											  CBidEngine& bidState,  
											  CPlayerStatusDialog& status)
{
	//
	// the requirements for a Michaels Cue Bid are:
	// 1: RHO must have opened a suit (not NT) at the 1-level
	// 2: this must be our first bidding opportunity
	// 3: need a 2-suited hand; i.e., 
	//    - if RHO bid a minor, need 5/5 or 5/(good)4 in the majors
	//    - if RHO bid a major, need 5 in the other major, plus 5 in a minor
	//    the two suits should also be rather comparable
	// 4: need either 6-11 pts or 17+ pts
	//    (with 12-16 pts, we generally overcall or double for takeout)
	// 5: if we have 12+ pts and playing takeout doubles, cannot have a 
	//    hand suitable for a takeout (???)

	// test conditions 1, 2, & 4
	if ( ((bidState.nRHOBid >= BID_1C) && (bidState.nRHOBid <= BID_1S)) &&
		 ( ((bidState.fPts >= OPEN_PTS(6)) && (bidState.fPts <= OPEN_PTS(11))) || ((bidState.fPts >= OPEN_PTS(17))/*&& (bidState.fPts <= 18)*/) ) &&
 		  (bidState.m_numBidTurns == 0) && (bidState.m_numPartnerBidTurns == 0) )
	{
		 // passed
	}
	else
	{
		return FALSE;
	}

	// test condition #3
	int nOppSuit = bidState.nRHOSuit;
	BOOL bEnoughLength = FALSE;
	//
	if (ISMINOR(nOppSuit))
	{
		// need 5/5 in the majors, or 5 + good 4
		int numHearts = hand.GetNumCardsInSuit(HEARTS);
		int numSpades = hand.GetNumCardsInSuit(SPADES);
		if ((hand.GetSuitStrength(HEARTS) < SS_MARGINAL_OPENER) || (hand.GetSuitStrength(SPADES) < SS_MARGINAL_OPENER) ||
			(Abs(hand.GetSuitStrength(HEARTS) - hand.GetSuitStrength(SPADES)) > 1) )
			return FALSE;
		//
		if ((numHearts >= 5) && (numSpades >= 5))
		{
			bEnoughLength = TRUE;
			status << "2MCL1! We have at least 5/5 in the majors, so we can make a Michaels cue bid.\n";
		}
		else if ((numHearts >= 5) && (numSpades == 4) && 
						(hand.GetSuitStrength(SPADES) >= SS_STRONG))
		{
			bEnoughLength = TRUE;
			status << "2MCL2! We have 5/4 in the majors, but the 4 Spades are strong, so we can make a Michaels cue bid.\n";
		}
		else if ((numHearts == 4) && (numSpades >= 5) && (hand.GetSuitStrength(HEARTS) >= SS_STRONG))
		{
			bEnoughLength = TRUE;
			status << "2MCL3! We have 5/4 in the majors, but the 4 Hearts are strong, so we can make a Michaels cue bid.\n";
		}
	}
	else
	{
		// need 5 in the unbid major, and 5 in a minor
		int nOtherMajor = (nOppSuit == HEARTS)? SPADES : HEARTS;
		int numMajors = hand.GetNumCardsInSuit(nOtherMajor);
		int numClubs = hand.GetNumCardsInSuit(CLUBS);
		int numDiamonds = hand.GetNumCardsInSuit(CLUBS);

		// check that the major suit is OK
		if ((numMajors < 5) || (hand.GetSuitStrength(nOtherMajor) < SS_MARGINAL_OPENER))
			return FALSE;

		// then check the minor & compare the suits
		if ((numClubs >= 5) && (hand.GetSuitStrength(CLUBS) >= SS_MARGINAL_OPENER) &&
			(Abs(hand.GetSuitStrength(nOtherMajor) - hand.GetSuitStrength(CLUBS)) <= 1) )
		{
			bEnoughLength = TRUE;
			status << "2MCL5! We have 5+ cards in " & STS(nOtherMajor) & 
					  " and 5+ cards in a minor (Clubs), so we can make a Michaels cue bid.\n";
		}
		else if ((numDiamonds >= 5) && (hand.GetSuitStrength(DIAMONDS) >= SS_MARGINAL_OPENER) &&
				(Abs(hand.GetSuitStrength(nOtherMajor) - hand.GetSuitStrength(DIAMONDS)) <= 1) )
		{
			bEnoughLength = TRUE;
			status << "2MCL5! We have 5+ cards in " & STS(nOtherMajor) & 
					  " and 5+ cards in a minor (Diamonds), so we can make a Michaels cue bid.\n";
		}
	}

	// check condition
	if (!bEnoughLength)
		return FALSE;

	// OK, go ahead and cue-bid the enemy suit
	int nBid = MAKEBID(nOppSuit, 2);
	status << "MCL9! With a 2-suited hand, make a Michaels cue bid over RHO's " & STS(nOppSuit) & 
			  " with a bid of " & BTS(nBid) & ".\n";
	bidState.SetBid(nBid);
	bidState.SetConventionStatus(this, CONV_INVOKED);
	return TRUE;
}
コード例 #2
0
//
//-----------------------------------------------------
//
// 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;
}