Exemple #1
0
int main(int argc, const char * argv[])
{
    Point pos1 = {2, 4};
    Point pos2 = {5, 7};
    
    ShowPoint (&pos1);
    ShowPoint (&pos2);
    SwapPoints (&pos1, &pos2);
    ShowPoint (&pos1);
    ShowPoint (&pos2);
    
    
    return 0;
}
Exemple #2
0
void DrawTriangle (HDC hDc, POINT p0, POINT p1, POINT p2, COLORREF color)
{
	int i, j;
	BOOL left;

	points [0] = p0;
	points [1] = p1;
	points [2] = p2;

	for (j = 0; j < NUM_POINTS; j++)
	{
		for (i = 0; i < NUM_POINTS - 1; i++)
		{
			if (points [i].y > points [i + 1].y)    // Sort y values in ascending order
			{
				SwapPoints (&points [i], &points [i + 1]);
			}
		}
	}

	longEdge->dx	= points [HIGH_POINT].x - points [LOW_POINT].x;
	longEdge->dy    = points [HIGH_POINT].y - points [LOW_POINT].y;

	topEdge->dx     = points [HIGH_POINT].x - points [MID_POINT].x;
	topEdge->dy     = points [HIGH_POINT].y - points [MID_POINT].y;

	lowEdge->dx     = points [MID_POINT].x  - points [LOW_POINT].x;
	lowEdge->dy     = points [MID_POINT].y  - points [LOW_POINT].y;

	triangle.color  = color;

	if (!topEdge->dx && !lowEdge->dx)	// Degenerate case
	{
		WriteColumn (hDc, points [LOW_POINT].x, points [LOW_POINT].y, points [HIGH_POINT].y);
		return;
	}

	if (!longEdge->dy)					// Degenerate case
	{
		WriteRow (hDc, points [LOW_POINT].x, points [HIGH_POINT].x, points [LOW_POINT].y);
		return;
	}

	left = topEdge->dx * lowEdge->dy > lowEdge->dx * topEdge->dy;
	// Find common denominator and compare inverse slopes

	(left ? FillLeftOrientedTriangle : FillRightOrientedTriangle) (hDc);
}
Exemple #3
0
//
// DealSpecial()
//
// Possible codes:
// ---------------
// Game Code: 0 = Any (Random)
// 			  1 = Game
// 			  2 = Slam
// Suit Code: 0 = Any
// 			  1 = Minor
// 			  2 = Major
// 			  3 = NoTrump
// Slam Code: 0 = Any
//			  1 = Small Slam
//			  2 = Grand Slam
//
void CEasyBDoc::DealSpecial(int nGameCode, int nSuitCode, int nSlamCode, int nTeam, int nDealNumber) 
{
	CString strFeedback;

	//
	CMainFrame::SetStatusMessage("Performing deal...");

	// validate inputs
	if ((nGameCode < 0 ) || (nGameCode > 2) ||
				(nSuitCode < 0 ) || (nSuitCode > 3) ||
				(nSlamCode < 0 ) || (nSlamCode > 2) )
		return;

	// first clear all hands
	InitNewHand();

	// delete document info
	if (!m_bReviewingGame)
		DeleteContents();

	// save special deal code
	m_nSpecialDealCode = (nGameCode << 6) | (nSuitCode << 4) | (nSlamCode << 2) | nTeam;

	// perform the initial shuffle
	m_nDealNumber = deck.Shuffle(nDealNumber);

	// set busy cursor
	pVIEW->SetCurrentMode(CEasyBView::MODE_WAITSPECIALDEAL);

	// first set target points
	int nMin, nMax;
	double fScoreTarget;
	//
	switch (nGameCode) 
	{

		case 0:
			// any random deal
			break;

		case 1:
			// game deal
			nMin = theApp.GetValue(tnRequiredPointsForGame,nSuitCode,0);
			nMax = theApp.GetValue(tnRequiredPointsForGame,nSuitCode,1);
			fScoreTarget = nMin + GetRandomValue(nMax - nMin);
			switch(nSuitCode) 
			{
				case 0:
					// game hand, any suit
					strFeedback.Format("Dealt game hand\n");
					break;
				case 1:
					// game hand, minor suit
					strFeedback.Format("Dealt Minor game hand\n");
					break;
				case 2:
					// game hand, major suit
					strFeedback.Format("Dealt Major game hand\n");
					break;
				case 3:
					// game hand, notrumps
					strFeedback.Format("Dealt NoTrump game hand\n");
					break;
			}
			break;

		case 2:
			// slam deal
			nMin = theApp.GetValue(tnRequiredPointsForSlam,nSlamCode,0);
			nMax = theApp.GetValue(tnRequiredPointsForSlam,nSlamCode,1);
			fScoreTarget = nMin + GetRandomValue(nMax - nMin);
			switch(nSlamCode) 
			{
				case 0:
					// any slam
					strFeedback.Format("Dealt slam hand\n");
					break;
				case 1: 
					// small slam
					strFeedback.Format("Dealt small slam hand\n");
					break;
				case 2: 
					// grand slam
					strFeedback.Format("Dealt grand slam hand\n");
					break;
			}
			break;
	}

	// declare loop counters
	int i;
	int nOuterLoopCount = 0;
	int nAceLoopCount1, nAceLoopCount2;
	int nKingLoopCount1, nKingLoopCount2;
	int nPointSwapLoopCount, nFailCount;

shuffle:
	nOuterLoopCount++;
	// check if we've exceeded the limit on iterations
	if (nOuterLoopCount >= MAX_SPECIAL_DEAL_ITERATIONS) 
	{
		AfxMessageBox("Failed to meet hand requirements.  Try again.");
		pVIEW->ClearMode();
		return;
	}

/*
	// every 100 count, reseed the random # generator
	if (((nOuterLoopCount % 100) == 0) && (nOuterLoopCount > 0))
		srand((unsigned)time(NULL));
*/

	// assign new hands
	DealCards();


	//
	//----------------------------------------------------------
	//
	// Now check the strength of N/S's hands
	//
	double fSouthPoints, fNorthPoints;
	if (nSuitCode != 3) 
	{
		fSouthPoints = PLAYER(SOUTH).GetTotalPoints();
		fNorthPoints = PLAYER(NORTH).GetTotalPoints();
	} 
	else 
	{
		// No Trumps; count high card points only
		fSouthPoints = PLAYER(SOUTH).GetHCPoints();
		fNorthPoints = PLAYER(NORTH).GetHCPoints();
	}
	double fTotalPoints = fSouthPoints + fNorthPoints;
	double fDiff, fSwapped;
	int nSource,nDest;

	// at this point, check cards' distribution
	int numInSuit[4];
	BOOL bSuitFit[4];
	for(i=0;i<4;i++) 
	{
		numInSuit[i] = PLAYER(SOUTH).GetNumCardsInSuit(i) +
						PLAYER(NORTH).GetNumCardsInSuit(i);
		// check for a proper card distribution (min 4/3)
		int nDistIndex = theApp.GetValue(tnMinSuitDistributions,nSuitCode-1);
		int nDistVal[2];
		nDistVal[0] = theApp.GetValue(tnMinSuitDistributions,nSuitCode-1,nDistIndex,0);
		nDistVal[1] = theApp.GetValue(tnMinSuitDistributions,nSuitCode-1,nDistIndex,1);
		if ((nSuitCode == 1) || (nSuitCode == 2)) 
		{
			if ( ((PLAYER(SOUTH).GetNumCardsInSuit(i) >= nDistVal[0]) &&
						  (PLAYER(NORTH).GetNumCardsInSuit(i) >= nDistVal[1])) ||
			     ((PLAYER(NORTH).GetNumCardsInSuit(i) >= nDistVal[0]) &&
						  (PLAYER(SOUTH).GetNumCardsInSuit(i) >= nDistVal[1])) )
				bSuitFit[i] = TRUE;
			else
				bSuitFit[i] = FALSE;
		}
		else 
		{
			// generic suit or no trumps specified; default to
			// 4/3 for fit determination
			if ( ((PLAYER(SOUTH).GetNumCardsInSuit(i) >= 3) &&
				  (PLAYER(NORTH).GetNumCardsInSuit(i) >= 4)) ||
			     ((PLAYER(NORTH).GetNumCardsInSuit(i) >= 3) &&
				  (PLAYER(SOUTH).GetNumCardsInSuit(i) >= 4)) )
				bSuitFit[i] = TRUE;
			else
				bSuitFit[i] = FALSE;
		}
	}

	//
	if (nSuitCode == 3) 
	{

		// No Trump contract -- check hand balance
		int nMaxImbalance = theApp.GetValue(tnMaxImbalanceForNT);
		if (theApp.GetValue(tbNeedTwoBalancedTrumpHands)) 
		{
			// both players need balanced hands
			if ((PLAYER(SOUTH).GetBalanceValue() > nMaxImbalance) ||
					(PLAYER(NORTH).GetBalanceValue() > nMaxImbalance))
				goto shuffle;
		} 
		else 
		{
			// at least one player has balanced hand
			if ((PLAYER(SOUTH).GetBalanceValue() > nMaxImbalance) && 
					(PLAYER(NORTH).GetBalanceValue() > nMaxImbalance))
				goto shuffle;
		}

	} 
	else if (nSuitCode == 2) 
	{

		// major suit game -- need at least one major suit
		// that has >= min cards
		int nCardsInMajor = theApp.GetValue(tnMinCardsInMajor);	
		if ((numInSuit[HEARTS] < nCardsInMajor) &&
					(numInSuit[SPADES] < nCardsInMajor))
			goto shuffle;
		// also need a minimum 4-3 fit in a major suit
		if ((!bSuitFit[HEARTS]) && (!bSuitFit[SPADES]))
			goto shuffle;
		// and also check that the suit is adequately topped
		BOOL bTopped = FALSE;
		int nMinTopMajorCard = theApp.GetValue(tnMinTopMajorCard);
		if ((bSuitFit[HEARTS]) && (PLAYER(SOUTH).GetNumCardsInSuit(HEARTS) >= 4) &&
			(PLAYER(SOUTH).GetCardInSuit(HEARTS,0)->GetFaceValue() >= nMinTopMajorCard))
			bTopped = TRUE;
		if ((bSuitFit[SPADES]) && (PLAYER(SOUTH).GetNumCardsInSuit(SPADES) >= 4) &&
			(PLAYER(SOUTH).GetCardInSuit(SPADES,0)->GetFaceValue() >= nMinTopMajorCard))
			bTopped = TRUE;
		if ((bSuitFit[HEARTS]) && (PLAYER(NORTH).GetNumCardsInSuit(HEARTS) >= 4) &&
			(PLAYER(NORTH).GetCardInSuit(HEARTS,0)->GetFaceValue() >= nMinTopMajorCard))
			bTopped = TRUE;
		if ((bSuitFit[SPADES]) && (PLAYER(NORTH).GetNumCardsInSuit(SPADES) >= 4) &&
			(PLAYER(NORTH).GetCardInSuit(SPADES,0)->GetFaceValue() >= nMinTopMajorCard))
			bTopped = TRUE;
		if (!bTopped)
			goto shuffle;

	} 
	else if (nSuitCode == 1) 
	{

		// minor suit game -- need at least one major suit
		// that has >= min cards
		int nCardsInMinor = theApp.GetValue(tnMinCardsInMinor);	
		if ((numInSuit[CLUBS] < nCardsInMinor) &&
					(numInSuit[DIAMONDS] < nCardsInMinor))
			goto shuffle;
		// also need a minimum 4-3 fit in a minor suit
		if ((!bSuitFit[CLUBS]) && (!bSuitFit[DIAMONDS]))
			goto shuffle;
		// and also check that the suit is adequately topped
		BOOL bTopped = FALSE;
		int nMinTopMinorCard = theApp.GetValue(tnMinTopMinorCard);
		if ((bSuitFit[CLUBS]) && (PLAYER(SOUTH).GetNumCardsInSuit(CLUBS) >= 4) &&
			(PLAYER(SOUTH).GetCardInSuit(CLUBS,0)->GetFaceValue() >= nMinTopMinorCard))
			bTopped = TRUE;
		if ((bSuitFit[DIAMONDS]) && (PLAYER(SOUTH).GetNumCardsInSuit(DIAMONDS) >= 4) &&
			(PLAYER(SOUTH).GetCardInSuit(DIAMONDS,0)->GetFaceValue() >= nMinTopMinorCard))
			bTopped = TRUE;
		if ((bSuitFit[CLUBS]) && (PLAYER(NORTH).GetNumCardsInSuit(CLUBS) >= 4) &&
			(PLAYER(NORTH).GetCardInSuit(CLUBS,0)->GetFaceValue() >= nMinTopMinorCard))
			bTopped = TRUE;
		if ((bSuitFit[DIAMONDS]) && (PLAYER(NORTH).GetNumCardsInSuit(DIAMONDS) >= 4) &&
			(PLAYER(NORTH).GetCardInSuit(DIAMONDS,0)->GetFaceValue() >= nMinTopMinorCard))
			bTopped = TRUE;
		if (!bTopped)
			goto shuffle;

	}

	//
	//----------------------------------------------------------
	//
	// Fudging time --
	//
	// for a grand slam hand, check to make sure there are some 
	// non-ace, non-king honors in the N/S suits.  This will make
	// it easier to trade down points later on
	if ((nGameCode == 2) && (nSlamCode == 2)) 
	{
		double fDiff1 = m_pPlayer[SOUTH]->GetHCPoints() - (m_pPlayer[SOUTH]->GetNumCardsOf(ACE)*4 + m_pPlayer[SOUTH]->GetNumCardsOf(KING)*3);
		double fDiff2 = m_pPlayer[NORTH]->GetHCPoints() - (m_pPlayer[NORTH]->GetNumCardsOf(ACE)*4 + m_pPlayer[NORTH]->GetNumCardsOf(KING)*3);
		// #### TEMP ####
		double fHC1 = m_pPlayer[SOUTH]->GetHCPoints();
		int nAces1 = m_pPlayer[SOUTH]->GetNumCardsOf(ACE);
		int nKings1 = m_pPlayer[SOUTH]->GetNumCardsOf(KING);
		double fHC2 = m_pPlayer[NORTH]->GetHCPoints();
		int nAces2 = m_pPlayer[NORTH]->GetNumCardsOf(ACE);
		int nKings2 = m_pPlayer[NORTH]->GetNumCardsOf(KING);
		ASSERT((fDiff1 >= 0) && (fDiff2 >= 0));
		//
		if ((fDiff1 < 2) || (fDiff2 < 2))
			goto shuffle;
	}

	//
	//----------------------------------------------------------
	//
	// slam hand -- check for aces if necessary
	//
	int numAcesRequired;
	int numAcesHeld;
	if (nGameCode == 2) 
	{
		numAcesRequired = theApp.GetValue(tnumAcesForSlam,nSlamCode);
		numAcesHeld = PLAYER(SOUTH).GetNumCardsOf(ACE) + PLAYER(NORTH).GetNumCardsOf(ACE);
		int numCards,nSrcPlayer,nDestPlayer,nSuit1,nSuit2,nDestCard;
		int fDiff = numAcesRequired - numAcesHeld;
		// trade aces with opponents
		if (fDiff > 0) 
		{
			for(i=0;i<fDiff;i++) 
			{
				// first pick a source opponent, semi-randomly
				// 0 or 1; 0 means west, unless west has zero aces
				if ( ((GetRandomValue(1) == 0) &&
					  		(PLAYER(WEST).GetNumCardsOf(ACE) > 0)) ||
					 (PLAYER(EAST).GetNumCardsOf(ACE) == 0) )
					nSrcPlayer = WEST;
				else
					nSrcPlayer = EAST;
				ASSERT(PLAYER(nSrcPlayer).GetNumCardsOf(ACE) != 0);
				// and likewise pick a dest player; 0=South
				int nVal = GetRandomValue(1);
				if ( ((nVal == 0) && (PLAYER(SOUTH).GetNumCardsOf(ACE) < 4)) ||
					 (PLAYER(NORTH).GetNumCardsOf(ACE) == 4) )
					nDestPlayer = SOUTH;
				else
					nDestPlayer = NORTH;
				// now pick a source suit and a dest suit
				nAceLoopCount1 = 0;
				do 
				{
					// search for a source suit with an ace
					nSuit1 = GetRandomValue(3);
					if ((PLAYER(nSrcPlayer).GetNumCardsInSuit(nSuit1) > 0) &&
						(PLAYER(nSrcPlayer).GetCardInSuit(nSuit1,0)->GetFaceValue() == ACE)) {
						break;
					}
					nAceLoopCount1++;
				} 
				while (nAceLoopCount1 < 100);
				if (nAceLoopCount1 >= 100) 
				{
					AfxMessageBox("Failed to meet deal constraints (Ace search stage 1 failure).");
					break;
				}
				//
				nAceLoopCount2 = 0;
				do 
				{
					nSuit2 = GetRandomValue(3);
					// make sure the dest suit has > 1 cards in it,
					// or if it has only one card, that it's not an ace
					if ((PLAYER(nDestPlayer).GetNumCardsInSuit(nSuit2) > 1) ||
					    ((PLAYER(nDestPlayer).GetNumCardsInSuit(nSuit2) == 1) &&
						 (PLAYER(nDestPlayer).GetCardInSuit(nSuit2,0)->GetFaceValue() != ACE)) ) {
						break;
					}
					nAceLoopCount2++;
				} while (nAceLoopCount2 < 100);
				if (nAceLoopCount2 >= 100) 
				{
					AfxMessageBox("Failed to meet deal constraints (Ace search stage 2 failure).");
					break;
				}
				// and then pick a nonace card from the dest suit
				numCards = PLAYER(nDestPlayer).GetNumCardsInSuit(nSuit2);
				do 
				{
					nDestCard = GetRandomValue(numCards-1);
				} while (PLAYER(nDestPlayer).GetCardInSuit(nSuit2,nDestCard)->GetFaceValue() == ACE);
				// and finally, then swap cards
				SwapPlayersCards(nSrcPlayer,nDestPlayer, nSuit1, nSuit2, 0, nDestCard, TRUE);
			}
		}		
	}

	//
	//----------------------------------------------------------
	//
	// likewise, check for kings if necessary
	//
	int numKingsRequired;
	int numKingsHeld;
	if (nGameCode == 2) 
	{
		numKingsRequired = theApp.GetValue(tnumKingsForSlam,nSlamCode);
		numKingsHeld = PLAYER(SOUTH).GetNumCardsOf(KING) + PLAYER(NORTH).GetNumCardsOf(KING);
		int numCards,nSrcPlayer,nDestPlayer,nSuit1,nSuit2,nDestCard,nSrcCard;
		int fDiff = numKingsRequired - numKingsHeld;

		// trade kings with opponents
		if (fDiff > 0) 
		{
			for(i=0;i<fDiff;i++) 
			{
				// first pick a source opponent, semi-randomly
				// 0 or 1; 0 means west, unless west has zero kings
				if ( ((GetRandomValue(1) == 0) &&
					  		(PLAYER(WEST).GetNumCardsOf(KING) > 0)) ||
					 (PLAYER(EAST).GetNumCardsOf(KING) == 0) )
					nSrcPlayer = WEST;
				else
					nSrcPlayer = EAST;
				// and likewise pick a dest player; 0=South
				if ( ((GetRandomValue(1) == 0) &&
					  		(PLAYER(SOUTH).GetNumCardsOf(KING) < 4)) ||
					 (PLAYER(NORTH).GetNumCardsOf(KING) == 4) )
					nDestPlayer = SOUTH;
				else
					nDestPlayer = NORTH;
				// now pick a source suit and a dest suit
				nKingLoopCount1 = 0;
				do 
				{
					// search for a source suit with a king
					nSuit1 = GetRandomValue(3);
					if ((PLAYER(nSrcPlayer).GetNumCardsInSuit(nSuit1) >= 1) &&
 						(PLAYER(nSrcPlayer).GetCardInSuit(nSuit1,0)->GetFaceValue() == KING)) 
					{
						nSrcCard = 0;
						break;
					}
					if ((PLAYER(nSrcPlayer).GetNumCardsInSuit(nSuit1) >= 2) &&
					    (PLAYER(nSrcPlayer).GetCardInSuit(nSuit1,1)->GetFaceValue() == KING)) 
					{
						nSrcCard = 1;
						break;
					}
					nKingLoopCount1++;
				} 
				while (nKingLoopCount1 < 100);
				if (nKingLoopCount1 >= 100) 
				{
					AfxMessageBox("Failed to meet deal constraints (King search stage 1 failure).");
					break;
				}
				//
				nKingLoopCount2 = 0;
				do 
				{
					nSuit2 = GetRandomValue(3);
					// make sure the dest suit has > 1 cards in it, including a 
					// card lower than a king which can be swapped out 
					int nNum = PLAYER(nDestPlayer).GetNumCardsInSuit(nSuit2);
					if ((nNum >= 1) &&
						(PLAYER(nDestPlayer).GetCardInSuit(nSuit2,nNum-1)->GetFaceValue() < KING)) {
						break;
					}
					nKingLoopCount2++;
				} while (nKingLoopCount2 < 100);
				if (nKingLoopCount2 >= 100) 
				{
					AfxMessageBox("Failed to meet deal constraints (King search stage 2 failure).");
					break;
				}
				// and then pick a non-king, non-ace card from the dest suit
				numCards = PLAYER(nDestPlayer).GetNumCardsInSuit(nSuit2);
				do 
				{
					nDestCard = GetRandomValue(numCards-1);
				} while ((PLAYER(nDestPlayer).GetCardInSuit(nSuit2,nDestCard)->GetFaceValue() == KING) ||
						 (PLAYER(nDestPlayer).GetCardInSuit(nSuit2,nDestCard)->GetFaceValue() == ACE));
				// and finally, then swap cards
				SwapPlayersCards(nSrcPlayer,nDestPlayer,nSuit1,nSuit2,nSrcCard,nDestCard,TRUE);
			}
		}	
	}

	//
	//----------------------------------------------------------
	//
	// now, adjust hand points if necessary
	// note that we must maintain card topping requirements
	//
	fDiff = fTotalPoints - fScoreTarget;
//	srand((unsigned)time(NULL));
	BOOL bSouthHoldsExtraHonors,bNorthHoldsExtraHonors;
	nPointSwapLoopCount = 0;
	nFailCount = 0;
	//
	while (fDiff != 0) 
	{
		// check some hand parameters to ensure success of swap routine
		// see if N/S have high cards available to swap down
		int nSouthAces = m_pPlayer[SOUTH]->GetNumCardsOf(ACE);
		int nSouthKings = m_pPlayer[SOUTH]->GetNumCardsOf(KING);
		if ((m_pPlayer[SOUTH]->GetHCPoints() > nSouthAces*4 + nSouthKings*3) ||
			((nSouthAces > 0) && (numAcesHeld > numAcesRequired)) ||
			((nSouthKings > 0) && (numKingsHeld > numKingsRequired))	)
			bSouthHoldsExtraHonors = TRUE;
		else
			bSouthHoldsExtraHonors = FALSE;
		int nNorthAces = m_pPlayer[NORTH]->GetNumCardsOf(ACE);
		int nNorthKings = m_pPlayer[NORTH]->GetNumCardsOf(KING);
		if ((m_pPlayer[NORTH]->GetHCPoints() > nNorthAces*4 + nNorthKings*3) ||
			((nNorthAces > 0) && (numAcesHeld > numAcesRequired)) ||
			((nNorthKings > 0) && (numKingsHeld > numKingsRequired)) )
			bNorthHoldsExtraHonors = TRUE;
		else
			bNorthHoldsExtraHonors = FALSE;
		//
 		nDest = (GetRandomValue(1)==0)? EAST: WEST;
		if (fDiff < 0) 
		{
			// adjust hand upwards
			if ((theApp.GetValue(tbBalanceTeamHands)) &&
				((fSouthPoints >= 13) || (fNorthPoints >= 13)) ) 
			{
				if (fSouthPoints < fNorthPoints)
					nSource = SOUTH;
				else
					nSource = NORTH;
			} 
			else 
			{
				nSource = (GetRandomValue(1)==0)? NORTH: SOUTH;
			}
			fSwapped = SwapPoints(nSource, nDest, Abs(fDiff), nGameCode, nSuitCode, nSlamCode);
		} 
		else 
		{
			// adjust hand down
			if ((numAcesHeld <= numAcesRequired) &&
				(numKingsHeld <= numKingsRequired) &&
				(!bSouthHoldsExtraHonors) && (!bNorthHoldsExtraHonors)) 
			{
				// neither hand has a high card to trade down while
				// meeting Aces/Kings requirement, just give up
				break;
			}
			// else proceed
			if ((theApp.GetValue(tbBalanceTeamHands))  &&
				((fSouthPoints >= 13) || (fNorthPoints >= 13)) ) 
			{
				// deduct points from hand with the most points, unless that hand
				// lacks honors below a king (which must be held)
				if ( ((fSouthPoints > fNorthPoints) && (bSouthHoldsExtraHonors)) ||
					 ((bSouthHoldsExtraHonors) && (!bNorthHoldsExtraHonors)) )
					nSource = SOUTH;
				else
					nSource = NORTH;
			} 
			else 
			{
				nSource = (GetRandomValue(1)==0)? NORTH: SOUTH;
			}
			fSwapped = SwapPoints(nDest, nSource, Abs(fDiff), nGameCode, nSuitCode, nSlamCode);
		}
		//
		if (fSwapped == 0) 
		{
			nFailCount++;
			if (nFailCount > 40)
				break;	// could've run out of high cards
		}
		// and re-evaluate
		PLAYER(SOUTH).CountCardPoints(TRUE);
		PLAYER(NORTH).CountCardPoints(TRUE);
		if (nSuitCode != 3) 
		{
			fSouthPoints = PLAYER(SOUTH).GetTotalPoints();
			fNorthPoints = PLAYER(NORTH).GetTotalPoints();
		} 
		else 
		{
			// No Trumps; count high card points only
			fSouthPoints = PLAYER(SOUTH).GetHCPoints();
			fNorthPoints = PLAYER(NORTH).GetHCPoints();
		}
		fTotalPoints = fSouthPoints + fNorthPoints;
		fDiff = fTotalPoints - fScoreTarget;
		nPointSwapLoopCount++;
	}

	//
	//----------------------------------------------------------------
	// now report on success of the special deal
	//
	CString strTemp;
/*
	strTemp.Format("Iterations: O=%d, A1=%d, A2=%d, K1=%d, K2=%d, PS=%d, FL=%d\n",
							nOuterLoopCount,nAceLoopCount1,nAceLoopCount2,
							nKingLoopCount1, nKingLoopCount2,
							nPointSwapLoopCount,nFailCount);
	strFeedback += strTemp;
*/

	for(i=0;i<4;i++)
		PLAYER(i).CountCardPoints(TRUE);
	//
	strTemp.Format("S: %d/%d pts;  N: %d/%d pts (Total: %d/%d/%d)\nEast: %d/%d pts;  West: %d/%d pts (Total E/W: %d)",
					PLAYER(SOUTH).GetHCPoints(),
					PLAYER(SOUTH).GetTotalPoints(),
					PLAYER(NORTH).GetHCPoints(),
					PLAYER(NORTH).GetTotalPoints(),
					PLAYER(SOUTH).GetHCPoints() + PLAYER(NORTH).GetHCPoints(),
					fTotalPoints,fScoreTarget,
					PLAYER(EAST).GetHCPoints(),
					PLAYER(EAST).GetTotalPoints(),
					PLAYER(WEST).GetHCPoints(),
					PLAYER(WEST).GetTotalPoints(),
					PLAYER(EAST).GetTotalPoints() + PLAYER(WEST).GetTotalPoints());
	strFeedback += strTemp;
	strTemp.Format("\nQT's: N: %3.1f S: %3.1f;   Stoppers: N: %d S: %d",
					PLAYER(NORTH).GetNumQuickTricks(),
					PLAYER(SOUTH).GetNumQuickTricks(),
					PLAYER(NORTH).GetNumSuitsStopped(),
					PLAYER(SOUTH).GetNumSuitsStopped());
	strFeedback += strTemp;
	if (nGameCode == 2) 
	{
		int numAcesRequired = theApp.GetValue(tnumAcesForSlam,nSlamCode);
		int numAcesHeld = PLAYER(SOUTH).GetNumCardsOf(ACE) + PLAYER(NORTH).GetNumCardsOf(ACE);
		int numKingsRequired = theApp.GetValue(tnumKingsForSlam,nSlamCode);
		int numKingsHeld = PLAYER(SOUTH).GetNumCardsOf(KING) + PLAYER(NORTH).GetNumCardsOf(KING);
		strTemp.Format("\nAces, Kings held by team = %d/%d, %d/%d",
						numAcesHeld,numAcesRequired,
						numKingsHeld,numKingsRequired);
		strFeedback += strTemp;
	}
	FEEDBACK(strFeedback);

	// swap hands if desired
	if (nTeam == EAST_WEST)
		RotatePlayersHands(0, FALSE, FALSE);

	// copy hands to the initial hands
	for(i=0;i<4;i++)
		PLAYER(i).InitializeHand();

	// turn off game auto-play
	if ((theApp.GetValue(tnCardPlayMode) == CEasyBApp::PLAY_FULL_AUTO) || (theApp.GetValue(tnCardPlayMode) == CEasyBApp::PLAY_FULL_AUTO_EXPRESS))
		theApp.SetValue(tnCardPlayMode, CEasyBApp::PLAY_NORMAL);

	// done dealing
	CMainFrame::ResetStatusMessage();
	
	// mark that the deal # is available
	m_bDealNumberAvailable = TRUE;

	// reset view mode
	pVIEW->ClearMode();

	// and begin play
	InitPlay();
}