 <!-- Begin
/**************************************************************************
  Arrays used + plus indexes into them. Xrand is a random number.
**************************************************************************/
var deal = new Array;
var Xdeal = 0;

var selected = new Array;
var Xsel = 0;

var Xrand = 0;				/* Working area for random numbers */
/***********************************************************************
  Various working variables. 
***********************************************************************/
var handnum = 0;            /* Hand number 0 -> 3  */
var Ahand = 0;              /* North, South, East, or West.          */


/*********************************************************************
  This routine deals a 52 cd deck into the 4 hands.
*********************************************************************/
function NewDeal()
	{
	/******************************************************************
	  Initialize for a new hand. Use the ClearIt method to blank all the
	  working fields of the hands. Initialize the "leftover" index
	******************************************************************/
	for (Xdeal = 0; Xdeal < 52; Xdeal++)
		deal[Xdeal] = deck[Xdeal];

	North.ClearIt();
	South.ClearIt();
	East.ClearIt();
	West.ClearIt();


	/**************************************************************** 
	 Pick a card at random from "deal." Add it to a hand and to the
	 "selected" Array and then delete it from "deal."
	****************************************************************/
	handnum = Xsel = 0;
	for ( Xdeal = 51; Xdeal >= 0; Xdeal-- )
		{
		if ( Xdeal == 0)
			Xrand = 0
		else
			Xrand = GetRand(Xdeal+1);

		Sethand("A", handnum);
		PostHandInfo( deal, Xrand );
		selected[Xsel] = deal[Xrand];
		selected[Xsel++].hand = handnum;
		deal.splice(Xrand,1);
		
		handnum++;
		if (handnum == 4)
			handnum = 0;
		}  /* End of ( Xdeal = 51; Xdeal >= 0; Xdeal-- ) */


	/******************************************************
	 Check to see that all HCP minimums are satisfied;
	 if not, look for a card to swap.
	******************************************************/
	swaps();
	PrettySuits();
	return;

	}/* This is the end of NewDeal. */

/*************************************************************************
*************************************************************************/
function swaps()
{
var needy = new Array;		/* Array of cards for "needy" hand */
var Nlen = 0;				/* length of the "needy" Array */
var Ncd = 0;				/* Index of a card in the "needy" Array */
var Nsuit = 0;				/* Suit of the card selected */
var Nnum = 0;				/* Suit index of the card selected */
var Nhcp = 0;				/* HCP of the card selected */
var Nface = 0;				/* Ascii representation of the card */

var others = new Array;		/* Array of cards for the "other" 3 hands */
var Olen = 0;				/* length of the "others" Array */
var Ocd = 0;				/* Index of a card in the "others" Array */
var Osuit = 0;				/* Suit of the card selected */
var Onum = 0;				/* Suit index of the card selected */
var Ohcp = 0;				/* HCP of the card selected */
var Oface = 0;				/* Ascii representation of the card */

var HCPdiff = 0;			/* For swaps. HCP diff between two cards. */

var loops = 0;				/*	Catches processing loops. */
var swapped = false;		/*	Switch. A card was swapped. */
var badhand = true;			/*	Switch. On = at least one unsatisfied min*/
var ruthless = false;		/*	Switch. Allows steals/swaps that put other
								hands under their minimums. */
var HorS = "H";				/* Honors or Spot cards.*/
var ok = 0;					/* A little general purpose switch.*/

/**************************************************************************
  Continue until minimums for all hands have been satisfied, or we go
  through the loop 1000 times.
**************************************************************************/
HorS = "H";
badhand = true;
swapped = false;
ruthless = false;

for( loops = 0; (loops < 1000) && (badhand == true); loops++)
	{
	for ( pick = swapped = 0; (pick < 4) && (swapped == false); pick++ )
		{
		Sethand( "A", pick );

		/******************************************************************
		  See if this hand needs any cards. If not, go on to the next.
		******************************************************************/
		if ( HorS == "H")
			{
			if ((Ahand.hcp >= Ahand.hcpmin)	&& (Ahand.hcp <= Ahand.hcpmax))
				continue;
			}
		else
			if ((Ahand.hcp >= Ahand.hcpmin)		   && (Ahand.hcp <= Ahand.hcpmax)
			&&	(Ahand.counts[S] >= Ahand.mins[S]) && (Ahand.counts[S] <= Ahand.maxs[S])
			&&	(Ahand.counts[H] >= Ahand.mins[H]) && (Ahand.counts[H] <= Ahand.maxs[H])
			&&	(Ahand.counts[D] >= Ahand.mins[D]) && (Ahand.counts[D] <= Ahand.maxs[D])
			&&	(Ahand.counts[C] >= Ahand.mins[C]) && (Ahand.counts[C] <= Ahand.maxs[C]) )
				continue;

		/******************************************************
		  Put cards for Ahand into an Array called "needy" and
		  cards for the other 3 hands into an array called 
		  "others"
		******************************************************/
		for ( zz = Olen = Nlen = 0; zz < Xsel; zz++ )
			if ( selected[zz].hand != pick )
				others[Olen++] = selected[zz]
			else
				needy[Nlen++] = selected[zz];

		/***********************************************************
		  Pick a card from the others array. Set OHand to its suit
		  and try to swap it to the needy hand. 
		***********************************************************/
		for ( Ocd = 0; (Ocd < Olen) && (swapped == false); Ocd++ )
			{
			Sethand( "O", others[Ocd].hand );
			Osuit = others[Ocd].suit;
			Onum = others[Ocd].num;
			Ohcp = others[Ocd].hcp;
			Oface = others[Ocd].face;

			/**********************************************************************
			  Got a card from "others", now go through the "needy" Array (the
			  receiving hand's cards) to find a card to swap with it.
			**********************************************************************/
			for ( Ncd = 0; (Ncd < Nlen) && (swapped == false); Ncd++ )
				{
				Nsuit = needy[Ncd].suit;
				Nnum = needy[Ncd].num;
				Nhcp = needy[Ncd].hcp;
				Nface = needy[Ncd].face;

				/***********************************************************************
				  See if the "others" card and the "needy" card can be subtracted from
				  the hand they're in and added to the other hand. If not, on to the
				  next. "ruthless" is the mode using for escaping from undealable hands.
				***********************************************************************/
				HCPdiff = Ohcp - Nhcp;
				
				if ( (Nsuit != Osuit) && (HorS != "H") && !ruthless )
					{
					if ((Ahand.counts[Nsuit] - 1 < Ahand.mins[Nsuit])
					||	(Ahand.counts[Osuit] + 1 > Ahand.maxs[Osuit])
					||	(Ahand.hcp + HCPdiff > Ahand.hcpmax)
					||	(Ahand.hcp + HCPdiff < Ahand.hcpmin) )
						continue;


					if ((OHand.counts[Osuit] - 1 < OHand.mins[Osuit])
					||	(OHand.counts[Nsuit] + 1 > OHand.maxs[Nsuit])
					||	(OHand.hcp - HCPdiff > OHand.hcpmax)
					||	(OHand.hcp - HCPdiff < OHand.hcpmin) )
						continue;
					}

				/***************************************************************
				  We have two cards we can swap; let's see if it will help us
				  satisfy our criteria. ok = true means that it will.
				***************************************************************/
				ok = false;
				if ((Ahand.hcp < Ahand.hcpmin)
				&& 	(HCPdiff > 0)
				&&	(Ahand.hcp + HCPdiff <= Ahand.hcpmax) )
					ok = true;

				if ((Ahand.hcp > Ahand.hcpmax)
				&&	(HCPdiff < 0)
				&&	(Ahand.hcp + HCPdiff >= Ahand.hcpmin) )
					ok = true;

				if ( (Osuit != Nsuit) && (HorS != "H") )
					{
					if ((Ahand.counts[Osuit] < Ahand.mins[Osuit])
					||	(Ahand.counts[Nsuit] > Ahand.maxs[Nsuit]) )
						ok = true;
					}

				/***********************************************************************
				  We've found two cards that fit the criteria. Now perform the swap.
				***********************************************************************/
				if (ok)
					{
					Ahand.suits[Osuit][Onum] = Oface;
					Ahand.suits[Nsuit][Nnum] = " ";

					OHand.suits[Nsuit][Nnum] = Nface;
					OHand.suits[Osuit][Onum] = " ";

					OHand.counts[Osuit]--;
					OHand.counts[Nsuit]++;
					Ahand.counts[Osuit]++;
					Ahand.counts[Nsuit]--;

					needy[Ncd].hand = others[Ocd].hand;
					others[Ocd].hand = pick;

					OHand.hcp -= HCPdiff;
					Ahand.hcp += HCPdiff;

					swapped = true;
					}

				} /* for ( Ncd = 0; (Ncd < Nlen) && !swapped; Ncd++ ) */

			}  /* for ( Ocd = 0; (Ocd < Olen) && !swapped; Ocd++ ) */


 		/******************************************************************
		  This routine restores the "selected" Array from others + needy.
		  Necessary because steal and swap may have changed some of the
		  hand numbers. Re-randomizing the selected array.
		******************************************************************/
		zz = 0;
		for (qq = --Olen; qq >= 0; qq--)
			{
			if (qq == 0)
				 Xrand = 0
			else Xrand = GetRand(qq+1);

			selected[zz++] = others[Xrand];
			others.splice(Xrand,1);
			}

		for (qq = --Nlen; qq >= 0; qq--)
			{
			if (qq == 0)
				 Xrand = 0
			else Xrand = GetRand(qq+1);

			selected[zz++] = needy[Xrand];
			needy.splice(Xrand,1);
			}

		}  /* for ( pick = swapped = 0; pick < 4; pick++ ) */

		/**********************************************************************
		  We've now gone through all four hands. Check to see what happened.
		    1. If all mins/maxs have been satisfied, we're done.
			2. If honor card min/max not satisfied turn on HorS.
			3. If no card has been dealt, turn on ruthless.
			4. If a card has been dealt, turn off ruthless.
		**********************************************************************/
		qq = HorS;
		HorS = "S";
		badhand = false;
		for (zz = 0; zz < 4; zz++)
			{
			Sethand("A", zz);

			if ((Ahand.hcp < Ahand.hcpmin)
			||	(Ahand.hcp > Ahand.hcpmax))
				{
				HorS = "H";
				badhand = true;
				}

			if ((Ahand.counts[S] < Ahand.mins[S]) || (Ahand.counts[S] > Ahand.maxs[S])
			||	(Ahand.counts[H] < Ahand.mins[H]) || (Ahand.counts[H] > Ahand.maxs[H])
			||	(Ahand.counts[D] < Ahand.mins[D]) || (Ahand.counts[D] > Ahand.maxs[D])
			||	(Ahand.counts[C] < Ahand.mins[C]) || (Ahand.counts[C] > Ahand.maxs[C]) )
				badhand = true;
			}

		if ( (badhand == true) && (swapped == false) )
			{
			if (ruthless == true)
				loops = 1000;

			ruthless = true;
			}
		else ruthless = false;

	}  /* for( loops = 0; loops < 1000; loops++) */
	
	if (loops == 1000)
		{
		alert("Couldn't do it. May be an impossible set of criteria.\n" +
			  "When you clear this message, you'll see the incorrect hand.");

/*
		alert( "loops == 1000");
		alert( "HorS = " + HorS);
		alert( "ruthless = " + ruthless);
		North.criteria();
		North.working();

		East.criteria();
		East.working();

		South.criteria();
		South.working();

		West.criteria();
		West.working();
*/
		}

} /* End swaps() */

/*************************************************************
  The cards have all been dealt. Now turn the suit arrays to
  strings so we can put them on the screen.
*************************************************************/
function PrettySuits()
	{
	North.arrayTOstring();
	East.arrayTOstring();
	South.arrayTOstring();
	West.arrayTOstring();
	}

/***************************************************************************
	This routine puts a card into the Hand array . The hand to use is Ahand,
	the card array is which, and the index into it is dd.
***************************************************************************/
function PostHandInfo( which, dd )
	{
	Ahand.suits[ which[dd].suit ][ which[dd].num ] = which[dd].face;
	Ahand.counts[ which[dd].suit ]++;
	Ahand.hcp += which[dd].hcp;
	}

/*************************************************************************
  Return an integer between 0 and div.
*************************************************************************/
function GetRand (div)
	{
	var RR = Math.round(Math.random() * 100000);
	RR %= div;

	return RR;
	}

/*************************************************************************
  Convert a passed number between 0 and 3 into an array name and put it in
  "Ahand" or "OHand", depending on TheLetter.
*************************************************************************/
function Sethand (TheLetter, TheNum)
	{
	if (TheNum == 0)
		if (TheLetter == "A")
			Ahand = North
		else OHand = North

	else if (TheNum == 1)
		if (TheLetter == "A")
			Ahand = East
		else OHand = East

	else if (TheNum == 2)
		if (TheLetter == "A")
			Ahand = South
		else OHand = South

	else
		if (TheLetter == "A")
			Ahand = West
		else OHand = West;
	}
-->

