Ejemplo n.º 1
0
//
// PlayFourth()
//
// default implementation
//
CCard* CPlayEngine::PlayFourth()
{
	CPlayerStatusDialog& status = *m_pStatusDlg;
	status << "5PLAY4! Playing fourth, using default player logic.\n";

	// use common code
	CCard* pCard = PlayBestCard(4);
	//
	ASSERT(pCard->IsValid());
	return pCard;
}
Ejemplo n.º 2
0
/* takes top card from the slot and movies it (if possible) to the foundation */
void CTable::Wizard()
{

	CBuffer buffer;
	CCard	tmp;

	CSlot* slot = NULL;

	if( hand.GetCardsStored() ) return;


	unsigned char prev_slot = act_slot;

	switch( act_slot )
	{
	case BLOCK : this->DoAction(); break;
	case WASTEPILE : slot = &wastepile;	break;
	case FOUNDATION1 :  slot = &foundation[0]; break;
	case FOUNDATION2 :  slot = &foundation[1]; break;
	case FOUNDATION3 :  slot = &foundation[2]; break;
	case FOUNDATION4 :  slot = &foundation[3]; break;
	case TABLEAU1 :	slot = &tableau[0]; break;
	case TABLEAU2 :	slot = &tableau[1]; break;
	case TABLEAU3 :	slot = &tableau[2]; break;
	case TABLEAU4 :	slot = &tableau[3]; break;
	case TABLEAU5 :	slot = &tableau[4]; break;
	case TABLEAU6 :	slot = &tableau[5]; break;
	case TABLEAU7 :	slot = &tableau[6]; break;
	}

	if( slot )
	{
		tmp = slot->PeekCard();

		if( false == tmp.IsValid() ) return;

		for( unsigned char i = 0; i < 4; i++ )
		{
			if( foundation[i].PushCard( tmp ) )
			{
				changed[ FOUNDATION1 + i ] = true;
				changed[ prev_slot ] = true;

				slot->PopCard();

				CheckWin( true );

				return;
			}
		}
	}
}
Ejemplo n.º 3
0
//
// PlayCard()
//
// default implementation
//
CCard* CPlayEngine::PlayCard()
{
	int nOrdinal = pDOC->GetNumCardsPlayedInRound();
	CCard* pCard = NULL;
	switch(nOrdinal)
	{
		case 0:
			pCard =  PlayFirst();
			break;
		case 1:
			pCard =  PlaySecond();
			break;
		case 2:
			pCard =  PlayThird();
			break;
		case 3:
			pCard =  PlayFourth();
			break;
		default:
			pCard = NULL;
	}
	// do some sanity checks
	ASSERT(pCard->IsValid());
	if (!m_pPlayer->IsDeclarer())
	{
		// playing as defender (or dummy, potentially)
		ASSERT(m_pHand->HasCard(pCard));
	}
	else
	{
		// declarer  -- may be playing for dummy or self
		if (pDOC->GetCurrentPlayer() == m_pPartner)
			ASSERT(m_pPartnersHand->HasCard(pCard));
		else
			ASSERT(m_pHand->HasCard(pCard));
	}
	//
	return pCard;
}
Ejemplo n.º 4
0
//
// PlayBestCard()
//
// called on the third and fourth hand plays to try to win the trick
//
CCard* CPlayEngine::PlayBestCard(int nPosition)
{
	CPlayerStatusDialog& status = *m_pStatusDlg;
//	status << "2PLAY3! Playing best card.\n";

	// get play info
	CCard* pCurrentCard = pDOC->GetCurrentTrickCardLed();
	int nSuitLed = pCurrentCard->GetSuit();
	int nTopPos;
	CCard* pCurrTopCard = pDOC->GetCurrentTrickHighCard(&nTopPos);
	CString strTopCardPos = PositionToString(nTopPos);
	BOOL bPartnerHigh = FALSE;
	int nCurrentRound = pDOC->GetPlayRound();
	int nCurrentSeat = pDOC->GetNumCardsPlayedInRound() + 1;
	CCard* pPartnersCard = pDOC->GetCurrentTrickCard(m_pPartner->GetPosition());
	if (pPartnersCard == pCurrTopCard)
		bPartnerHigh = TRUE;
	// 
	int nTrumpSuit = pDOC->GetTrumpSuit();
	int numCardsInSuitLed = m_pHand->GetNumCardsInSuit(nSuitLed);
	// card to play
	CCard* pCard = NULL;

	// 
	// first see if somebody trumped in this hand
	//
	if ((pDOC->WasTrumpPlayed()) && (nTrumpSuit != nSuitLed))
	{
		// a trump has been played 
		// see whether it was played by partner or by an opponent
		if (bPartnerHigh)
		{
			// partner trumped -- leave it alone for now
			pCard = GetDiscard();
			status << "PLAYB10! We let partner's " & pCurrTopCard->GetName() & " trump ride and discard the " &
					  pCard->GetName() & ".\n";
		}
		else
		{
			// it was an opponent that did the trumping
			// see if we can overtrump
			CSuitHoldings& trumpSuit = m_pHand->GetSuit(nTrumpSuit);
			CCard* pTopTrump = NULL;
			if (trumpSuit.GetNumCards() > 0)
				pTopTrump = trumpSuit.GetTopCard();
			if ((numCardsInSuitLed == 0) && (pTopTrump) && (*pTopTrump > *pCurrTopCard))
			{
				// get the lowest trump that wil top the current top trump
				int numTopCards = trumpSuit.GetNumCardsAbove(pCurrTopCard);
				pCard = trumpSuit[numTopCards-1];
				status << "PLAYB20! We can overtrump " & strTopCardPos & "'s " & pCurrTopCard->GetName() &
						  " with the " & pCard->GetFaceName() & ".\n";
			}
			else
			{
				// no chance to win, so discard
				pCard = GetDiscard();
				if ((numCardsInSuitLed == 0) && (trumpSuit.GetNumCards() > 0))
					status << "PLAYB22! We can't overtrump " & strTopCardPos & "'s " & 
							  pCurrTopCard->GetFaceName() & ", so discard the " & pCard->GetName() & ".\n";
				else
					status << "PLAYB23! We can't beat the opponent's " & pCurrTopCard->GetFaceName() & 
							  " of trumps, so discard the " & pCard->GetName() & ".\n";
			}							
		}
	}
	else
	{
		// else nobody has played a trump this round, _or_ a trump was led
		// see if we can play trumps
		if (numCardsInSuitLed > 0)
		{
			// nope, gotta follow the suit that was led, trumps or otherwise
			// if we can beat the current top card, do so with the cheapest card
			CSuitHoldings& suit = m_pHand->GetSuit(nSuitLed);
			if (*(suit.GetTopCard()) > *pCurrTopCard)
			{
				// but see if the top card is partner's
				if (bPartnerHigh) 
				{
					// see if we should unblock here
					if (ISSUIT(nTrumpSuit) && (nCurrentRound == 0) &&
						(suit.GetNumHonors() == 1))
					{
						// first round in an NT contract, with one honor 
						// in the suit -- unblock
						pCard = suit.GetTopCard();
						if (suit.GetNumCards() > 1)
							status << "PLAYB30! Drop the " & pCard->GetFaceName() & 
									  " here to unblock the suit for partner.\n";
					}
					else
					{
						// else this is not an unblocking situation
						if (nCurrentSeat == 4)
						{
							// playing in 4th seat, high card is partner, so discard
							pCard = GetDiscard();
							status << "PLAYB34! Partner's " & pCurrTopCard->GetFaceName() & 
									  " is high, so discard the " & pCard->GetName() & ".\n";
						}
						else
						{
							// playing in third position -- decide whether to 
							// let partner's card ride
							// do so if if partner's card beats all outstanding cards
							CCard* pTopOutstandingCard = GetHighestOutstandingCard(nSuitLed);
							if ((pTopOutstandingCard == NULL) || (*pCurrTopCard > *pTopOutstandingCard))
							{
								// let partner's card ride
								pCard = GetDiscard();
								status << "PLAYB36! Partner's " & pCurrTopCard->GetFaceName() & 
										  " is higher than any outstanding card, so discard the " & 
										  pCard->GetName() & ".\n";
							}
							else
							{
								// partner's card is not necessarily highest, so top it
								pCard = suit.GetTopSequence().GetBottomCard();
								status << "PLAYB37! Partner's " & pCurrTopCard->GetFaceName() & 
										  " might not win the round, so top it with the " & pCard->GetFaceName() & ".\n";
							}
						}
					}
				}
				else
				{
					// else high card is opponent's, so beat it w/ highest card affordable
					// although, if playing in 3rd pos ahead of dummy, just play
					// high enuff to beat dummy
					if ((nCurrentSeat == 3) && (m_bLHDefender))
					{
						CSuitHoldings& dummySuit = GetDummySuit(nSuitLed);
						int nDummyTopCard = 0;
						if (dummySuit.GetNumCards() > 0)
							nDummyTopCard = dummySuit[0]->GetFaceValue();
						int nTopVal = Max(nDummyTopCard, pCurrTopCard->GetFaceValue());
						pCard = suit.GetLowestCardAbove(nTopVal);
						// see if we can beat the top card or dummy's top card
						if (pCard)
						{
							if (nTopVal == nDummyTopCard)
							{
								// dummy has the top card and we can beat it
								status << "PLAYB38A! Playing third ahead of dummy, need to beat dummy's " & 
										  CardValToString(nDummyTopCard) & ".\n";
							}
							else
							{
								// the top card is declarer's
								status << "PLAYB38B! Play high to win with the " & pCard->GetFaceName() & ".\n";
							}
						}
						else
						{
							// else we can't beat dummy's top card, but play
							// high anyway to force out his winner
							pCard = suit.GetLowestCardAbove(pCurrTopCard);
							status << "PLAYB38C! We top declarer's " & pCurrTopCard->GetFaceName() &
								      " to force a winner from dummy.\n";
						}
					}
					else if (nCurrentSeat == 3) 
					{
						// else we're playing 3rd, so play the lowest card from the top sequence
						pCard = suit.GetTopSequence().GetBottomCard();
						status << "PLAYB40! Play high to win with the " & pCard->GetFaceName() & ".\n";
					}
					else
					{
						// else we're playing last (4th)
						// play the cheapest card that will beat the top card
						pCard = suit.GetLowestCardAbove(pCurrTopCard);
						status << "PLAYB41! Play the " & pCard->GetFaceName() & " to win the trick.\n";
					}
				}
			}
			else
			{
				// we don't have a card to top the current high card
				if (bPartnerHigh)
				{
					// but partner's card is high, so we're OK
					pCard = GetDiscard();
					status << "PLAYB47! Partner's " & pCurrTopCard->GetFaceName() & 
							  " can win the trick, so discard the " & pCard->GetName() & ".\n";
				}
				else
				{
					// else we're screwed
					pCard = GetDiscard();
					status << "PLAYB48! We can't beat " & strTopCardPos & "'s " & pCurrTopCard->GetFaceName() & 
							  ", so discard the " & pCard->GetName() & ".\n";
				}
			}
		}
		else if (ISSUIT(nTrumpSuit) && (nSuitLed != nTrumpSuit) &&
							(m_pHand->GetNumCardsInSuit(nTrumpSuit) > 0))
		{
			// here, we can play a trump, so do so if appropriate 
			// see who has the top card in this round
			if (bPartnerHigh)
			{
				// let partner's card ride
				pCard = GetDiscard();
				status << "PLAYB52! Although we could trump this hand, partner's " & pCurrTopCard->GetName() & 
						  " is high, so discard the " & pCard->GetName() & ".\n";
			}
			else
			{
				// opponents have the high card (non-trump) -- so slam 'em
				pCard = m_pHand->GetSuit(nTrumpSuit).GetBottomCard();
				status << "PLAYB55! With no cards in " & SuitToString(nSuitLed) & 
						  ", trump with the " & pCard->GetName() & ".\n";
			}
		}
		else
		{
			// here we have zero cards in the suit and in trumps, so we're hosed
			pCard = GetDiscard();
			status << "PLAYB52! With no cards in the suit led and no trumps, we discard the " & pCard->GetName() & ".\n";
		}
	}
	//
	ASSERT(pCard->IsValid());
	ASSERT(m_pHand->HasCard(pCard));
	//
	return pCard;
}
Ejemplo n.º 5
0
//
// PlaySecond()
//
// default implementation, generally should be overridden in derived classes
//
CCard* CPlayEngine::PlaySecond()
{
	CPlayerStatusDialog& status = *m_pStatusDlg;
	status << "5PLAY2! Playing second, using default player logic.\n";

	// get play info
	int nDummyPos = pDOC->GetDummyPosition();
	CCard* pCardLed = pDOC->GetCurrentTrickCardLed();
	int nSuitLed = pCardLed->GetSuit();
	int nFaceValue = pCardLed->GetFaceValue();
	CCard* pCurrTopCard = pDOC->GetCurrentTrickHighCard();
	int nTrumpSuit = pDOC->GetTrumpSuit();
	CSuitHoldings& suit = m_pHand->GetSuit(nSuitLed);
	// card to play
	CCard* pCard = NULL;

	// second hand low
	int numCardsInSuit = suit.GetNumCards();
	if (numCardsInSuit > 0)
	{
		// default behavior -- just play the low card
		pCard = m_pHand->GetSuit(nSuitLed).GetBottomCard();
		if (numCardsInSuit > 1)
		{
			if (*pCard < *pCurrTopCard)
				status << "PLY2C1! Play second hand low with the " & pCard->GetFaceName() & ".\n";
			else
				status << "PLY2C2! As second hand, we play the lowest card we have in the suit, the " & pCard->GetFaceName() & ".\n";
		}
		else
		{
			status << "PLY2C4! Play our only " & STSS(nSuitLed) & ", the " & pCard->GetFaceName() & ".\n";
		}
	}
	else
	{
		// no cards in the suit led
		// trump here if possible
		if (m_pHand->GetNumTrumps() > 0)
		{
			//
			CSuitHoldings& trumpSuit = m_pHand->GetSuit(nTrumpSuit);

			// see if partner would win the suit otherwise
			CGuessedSuitHoldings& partnerSuit = m_pPlayer->GetGuessedHand(m_nPartnerPosition)->GetSuit(nSuitLed);
			CCardList outstandingCards;
			GetOutstandingCards(nSuitLed, outstandingCards);
			if (partnerSuit.AreAllCardsIdentified() && partnerSuit.HasCard(outstandingCards[0]->GetFaceValue()))
			{
				// partner may win the trick, so discard
				status << "PLY2K1! We could trump here, but we know partner holds the " & outstandingCards[0]->GetName() &
						  " and can win the trick, so discard the " & pCard->GetName() & ".\n";
			}
			else
			{
				// trump here if possible
				// but first see if we're playing ahead of dummy (dummy is to our left), 
				// and dummy is also void in the suit
				CGuessedHandHoldings* pDummyHand = m_pPlayer->GetGuessedHand(nDummyPos);
				if ((m_pLHOpponent == pDOC->GetDummyPlayer()) &&
					(pDummyHand->GetSuit(nSuitLed).GetNumRemainingCards() == 0) &&
					(pDummyHand->GetSuit(nTrumpSuit).GetNumRemainingCards() > 0))
				{
					// dummy is also void, so trump if we have a trump higher than dummy's
					CGuessedCard* pDummyTopTrump = pDummyHand->GetSuit(nTrumpSuit).GetAt(0);
					if (trumpSuit.GetNumCardsAbove(pDummyTopTrump->GetFaceValue()) > 0)
					{
						// go ahead and ruff
						pCard = trumpSuit.GetLowestCardAbove(pDummyTopTrump->GetFaceValue());
						status << "PLY2M1! Trump here, making sure to thwart dummy's " & pDummyTopTrump->GetFaceName() &
								  " of trumps by playing the " & pCard->GetFaceName() & ".\n";
					}
					else
					{
						// dummy would overtrump
						pCard = GetDiscard();
						status << "PLY2M2! We'd like to trump here, but Dummy may overruff, so discard the " & pCard->GetName() & ".\n";
					}
				}
				else
				{
					// safe to trump -- play the lowest trump
					pCard = trumpSuit.GetBottomCard();
					status << "PLY2P1! Trump with the " & pCard->GetFaceName() & ".\n";
				}
			}
		}
		else
		{
			// discard
			pCard = GetDiscard();
			status << "PLY2Y! We have no " & SuitToString(nSuitLed) & ", so discard the " & pCard->GetName() & ".\n";
		}
	}
	//
	ASSERT(pCard->IsValid());
	return pCard;
}
Ejemplo n.º 6
0
void CTable::DoAction()
{

	CBuffer buffer;
	CCard	tmp;

	CSlot* fnd = NULL;
	CSlot* tab = NULL;

	switch( act_slot )
	{
	case BLOCK :
		/* move 3 cards to wastepile */

		//check IncreaseSelection and DecreaseSelection
		//regarding increaseSelection (all) or (+1)

		if( 0 != hand.GetCardsStored() ) return;

		buffer.RemoveAll();

		if( block.GetCardsStored() != 0 )
		{
			tmp = block.PopCard();
			tmp.Flip();
			wastepile.PushCard( tmp );

			if( 3 == ShowCards )
			{
				tmp = block.PopCard();
				tmp.Flip();
				wastepile.PushCard( tmp );

				tmp = block.PopCard();
				tmp.Flip();
				wastepile.PushCard( tmp );
			}

			act_slot = WASTEPILE;

		}
		else
		{
			if( wastepile.GetCardsStored() )
			{
				tmp = wastepile.PopCard();

				while( tmp.IsValid() )
				{
					tmp.Flip();
					block.PushCard( tmp, true );
					tmp = wastepile.PopCard();
				}

			}
		}
		changed[ WASTEPILE ] = true;
		changed[ BLOCK ] = true;

		ChangeSelection( );

		return;

	case WASTEPILE :
		/* put one card to hand */
		/* or put back from the hand */

		if( hand.GetCardsStored() )
		{
			if( hand.GetSource() == &wastepile )
			{
				tmp = hand.PopCard();
				wastepile.PushCard( tmp, true );

				hand.SetSource( NULL );
			}

		}
		else
		{
			tmp = wastepile.PopCard();
			if( false == tmp.IsValid() ) break;

			if( false == hand.PushCard( tmp ) )
			{
				wastepile.PushCard( tmp, true );
			}

			hand.SetSource( &wastepile );
		}

		changed[ WASTEPILE ] = true;
		changed[ HAND ] = true;

		return;

	case FOUNDATION1 :
	case FOUNDATION2 :
	case FOUNDATION3 :
	case FOUNDATION4 :  fnd = &foundation[act_slot - FOUNDATION1];	break;
	case TABLEAU1 :
	case TABLEAU2 :
	case TABLEAU3 :
	case TABLEAU4 :
	case TABLEAU5 :
	case TABLEAU6 :
	case TABLEAU7 :		tab = &tableau[act_slot - TABLEAU1]; break;
	}

	if( fnd )
	{
		if( 0 == hand.GetCardsStored() )
		{

			tmp = fnd->PopCard();

			if( false == tmp.IsValid() ) return;

			hand.PushCard( tmp );

			hand.SetSource( fnd );
			changed[ act_slot ] = true;
			changed[ HAND ] = true;

			CheckWin( false );

			ChangeSelection( );

			return;
		}
		else
		{
			if( fnd == hand.GetSource() )
			{
				tmp = hand.PopCard();

				fnd->PushCard( tmp, true );

				changed[ act_slot ] = true;
				changed[ HAND ] = true;

				CheckWin( true );

				ChangeSelection( );

				return;
			}
			else
			{
				tmp = hand.PeekCard();


				if( false == fnd->PushCard( tmp ) ) return;

				hand.RemoveAll();

				changed[HAND] = true;
				changed[act_slot] = true;

				CheckWin( true );


				ChangeSelection();

				return;
			}
		}

	}

	if( tab )
	{
		if( 0 == hand.GetCardsStored() )
		{
			tmp = tab->PeekCard();

			if( tmp.IsValid() && tmp.IsFaceDown() )
			{
				tmp = tab->PopCard();
				tmp.Flip();
				tab->PushCard( tmp, true );
				changed[ act_slot ] = true;
				ChangeSelection();
				return;
			}

			tab->GetSelectedCards( &buffer );

			tmp = buffer.PopCard();

			while( tmp.IsValid() )
			{
				hand.PushCard( tmp );
				tmp = buffer.PopCard();
			}

			hand.SetSource( tab );
			changed[ act_slot ] = true;
			changed[ HAND ] = true;

			ChangeSelection( );

			return;
		}
		else
		{

			if( tab == hand.GetSource() )
			{


				hand.PeekAllCards( &buffer );

				hand.RemoveAll();


				tmp = buffer.PopCard();

				while( tmp.IsValid() )
				{

					tab->PushCard( tmp, true );

					tmp = buffer.PopCard();
				}
				changed[ act_slot ] = true;
				changed[ HAND ] = true;


				ChangeSelection( );


				return;
			}
			else
			{


				hand.PeekAllCards( &buffer );


				tmp = buffer.PopCard();


				if( false == tab->PushCard( tmp ) ) return;


				tmp = buffer.PopCard();

				while( tmp.IsValid() )
				{

					tab->PushCard( tmp );

					tmp = buffer.PopCard();
				}


				hand.RemoveAll();

				changed[HAND] = true;
				changed[act_slot] = true;

				ChangeSelection();

				return;
			}
		}
	}

}