/***
 *
 * Scum-O-Matic Poker Strategy.
 *
 * Written By John Hoover (Pond Scum) @ 7/25/90.
 *
 * Updated By Michael Simone (Shanker) @ 7/26/90
 *
 ***/

#include "cards.h"
#include "5draw.h"
#include "standard.h"
# include	"strategy_protos.h"

/*
 * Evaluation return statuses.
 */

#define NOTHING		0
#define FOUR_OF_A_SUIT	1
#define PAIR		2
#define TWO_PAIR	3
#define THREE_OF_A_KIND	4
#define STRAIGHT	5
#define FULL_HOUSE	6
#define FOUR_OF_A_KIND	7
#define FLUSH		8
#define STRAIGHT_FLUSH	9
#define ROYAL_FLUSH	10

#define ACE		12
#define KING		11

int	bluffing = FALSE;

extern int
strategy_init()

{
return TRUE;
}


/*
 ***********************************************************************
 *
 * FUNCTION NAME:	computer_bet
 *
 * DESCRIPTION:		Make a bet.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *		knowledge	 I		Everything we know about the current hand.
 *		me			 I		Index in knowledge[] of this robot.
 *		required	 I		Total $$ this hand to bet to stay in.
 *
 * RETURN CODES: 
 *	(int)		Amount of additional cash to bet.
 *	(-1)		Fold.
 *
 * COMMENTS:
 *
 **********************************************************************
 */

int		computer_bet( KNOWLEDGE knowledge[], int me, int required )

{
	int	dcards[5];
	int	bet;

	if (is_new_hand)
		if (rand() % 10 == 0)
			bluffing = TRUE;
		else
			bluffing = FALSE;

	switch (my_eval(hand, dcards))
	{
		case ROYAL_FLUSH:
		case FLUSH:
		case STRAIGHT:
		case FULL_HOUSE:
		case FOUR_OF_A_KIND:
			if (is_new_hand)
				bet = (required - knowledge[me].bet + 10);
			else
				bet = (required - knowledge[me].bet + 50);
			break;
		case THREE_OF_A_KIND:
			if (is_new_hand)
				bet = (required - knowledge[me].bet + 10);
			else
				if (required - knowledge[me].bet > 20)
					bet = (required - knowledge[me].bet);
				else
					bet = (50);
			break;
		case TWO_PAIR:
			if (is_new_hand)
				bet = (required - knowledge[me].bet + 10);
			else
				if (required - knowledge[me].bet > 20)
					bet = (required - knowledge[me].bet);
				else
					bet = (30);
			break;
		case PAIR:
			if (required - knowledge[me].bet > 10)
				bet = (required - knowledge[me].bet);
			else
				if (bluffing)
					bet = 30;
				else
					bet = (10);
			break;
		default:
			if (!bluffing && required - knowledge[me].bet > 10)
				bet = (-1);
			else
				if (is_new_hand && bluffing)
					bet = (required - knowledge[me].bet + 50);
				else
					if (!is_new_hand && bluffing)
						bet = (-1);
					else 
						bet = (required - knowledge[me].bet);
			break;
	}
	return (bet);
}


/*
 ***********************************************************************
 *
 * FUNCTION NAME:	computer_draw
 *
 * DESCRIPTION:		Discard some cards and draw others.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *		knowledge	 I		Everything we know about the current hand.
 *		me			 I		Index in knowledge[] of this robot.
 *		cmd			 O		Constructed "discard" command.
 *
 * RETURN CODES: none
 *
 * COMMENTS:
 *
 **********************************************************************
 */

void	computer_draw( KNOWLEDGE knowledge[], int me, char *cmd )

{
	int	dcards[5];
	int	i;
	int	n;

	my_eval(knowledge[me].cards, dcards);
	sprintf(cmd, "DISCARD");
	n = (bluffing ? 1 : 10);
	for (i = 0; i < n && dcards[i] != -1; ++i)
		sprintf (cmd, "%s:%d", cmd, dcards[i]);
	return;
}

/***
 *
 * Compare two integers.
 *
 ***/

static int
intcmp(i1, i2)

	int	*i1;
	int	*i2;

{
	return (*i1 - *i2);
}

/***
 *
 * Evaluate 'hand' and put possible discard indices in "discards'.
 *
 ***/

int
my_eval(hand, discards)

	int	hand[];
	int	discards[];

{
	int		HOSER;
	int		match[2];
	int		values[2];
	int		temp[5];
	int		is_straight;
	int		flush;
	int		i;
	int		st;
	int		index;
	int		last;
	int		next;
	int		matched;
	int		sts[4];

	match[0] = match[1] = 1;
	values[0] = values[1] = -1;
	for (i = 0; i < 5; ++i)
		discards[i] = -1;

	/*
	 * First, sort cards in FACE VALUE order.
	 */

	for (i = 0, flush = TRUE, st = suit(hand[0]); i < 5; ++i)
	{
		temp[i] = card(hand[i]);
		if (flush && st != suit(hand[i]))
			flush = FALSE;
	}

	qsort((char *)temp, 5, sizeof(int), intcmp);

	/*
	 * Next, go through ``temp'' and check out the hand.
	 */

	for (i = 0, last = -1, next = temp[0], index = 0, is_straight = TRUE, matched = FALSE; 
	  i < 5; ++i)
	{
		next = temp[i];
		if (last == next)
		{
			values[index] = last;
			++match[index];
			matched = TRUE;
			is_straight = FALSE;
		}
		else
		{
			last = next;
			if (matched)
			{
				++index;
				matched = FALSE;
			}
			if (is_straight && i > 0 && next != temp[i-1] + 1)
				is_straight = FALSE;
		}
	}

	/*
	 * Put all we know together.
	 */

	if (is_straight && flush)
	{
		if (temp[4] == ACE)
			return (ROYAL_FLUSH);
		else
			return (STRAIGHT_FLUSH);
	}

	if (is_straight)
		return (STRAIGHT);

	if (flush)
		return (FLUSH);

	if ((match[0] == 3 && match[1] == 2) || (match[0] == 2 && match[1] == 3))
		return (FULL_HOUSE);

	/*
	 * The rest may allow discards.
	 */

	if (match[0] == 4 || match [1] == 4)
	{
		for (i = 0; i < 5; ++i)
		{
			if (card(hand[i]) == values[0] || card(hand[i]) == values[1])
				continue;
			else
			{
				discards[0] = i;
				break;
			}
		}
		return (FOUR_OF_A_KIND);
	}

	if (match[0] == 3 || match[1] == 3)
	{
		int	j;

		for (i = 0, j = 0; i < 5; ++i)
		{
			if (card(hand[i]) == values[0] || card(hand[i]) == values[1])
				continue;
			else
				discards[j++] = i;
		}
		return (THREE_OF_A_KIND);
	}

	if (match[0] == 2 && match[1] == 2)
	{
		for (i = 0; i < 5; ++i)
		{
			if (card(hand[i]) == values[0] || card(hand[i]) == values[1])
				continue;
			else
				discards[0] = i;
		}
		return (TWO_PAIR);
	}

	if (match[0] == 2 || match[1] == 2)
	{
		int	j;

		for (i = 0, j = 0; i < 5; ++i)
		{
			if (card(hand[i]) == values[0] || card(hand[i]) == values[1])
				continue;
			else
				discards[j++] = i;
		}
		return (PAIR);
	}

	for (i = 0; i < 4; ++i)
		sts[i] = 0;
	for (i = 0; i < 5; ++i)
		++(sts[suit(hand[i])]);
	for (i = 0; i < 4; ++i)
		if (sts[i] >= 4)
		{
			int	k = 0;
			int	j;

			for (j = 0; j < 5; ++j)
			{
				if (suit(hand[j]) != i)
					discards[k++] = j;
			}
			return (FOUR_OF_A_SUIT);
		}
/*
 *
 *  keep high card 
 *
 */

	for (HOSER = 0,i = 0; i < 5; ++i)
		if (card(hand[i]) < 9)
			discards[HOSER++] = i;
	return (NOTHING);

}

/*
 ****************************************************************************
 *	FUNCTION:	strategy_exit
 *
 *	PURPOSE:	Called as this program exits.
 *
 *	INPUT PARAMETERS:
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *
 *	RETURNS: none
 *
 *	COMMENTS:
 *
 *	HISTORY:
 *		1.	13 Mar 93/JVE		Created.
 *
 ****************************************************************************
 */

void strategy_exit(void)

{
}

/*
 ****************************************************************************
 *	FUNCTION:	computer_hear
 *
 *	PURPOSE:	Called when someone at the table speaks.
 *
 *	INPUT PARAMETERS:
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *
 *	RETURNS: none
 *
 *	COMMENTS:
 *
 *	HISTORY:
 *		1.	13 Mar 93/JVE		Created.
 *
 ****************************************************************************
 */

void computer_hear(KNOWLEDGE knowledge[], char *from, char *text)

{
}

/*
 ****************************************************************************
 *	FUNCTION:	computer_outcome
 *
 *	PURPOSE:	Tells us the result of the hand.
 *
 *	INPUT PARAMETERS:
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *
 *	RETURNS: none
 *
 *	COMMENTS:
 *
 *	HISTORY:
 *		1.	13 Mar 93/JVE		Created.
 *
 ****************************************************************************
 */

void computer_outcome(KNOWLEDGE knowledge[], int me, int winner)

{
}
