/*
 *	File name:			strategy_stats.c
 *	Purpose:			Defines a robot strategy for playing poker.
 *	Functions:			computer_bet, computer_draw, strategy_init,
 *						strategy_exit, computer_outcome, computer_hear.
 *	Created:			21 Nov 91
 *	Last Modified:		21 Nov 91
 *	Comments:
 *		"Strategy" files must contain six externally visible functions:
 *
 *		strategy_init - called once during startup.
 *		strategy_exit - called once upon orderly exit.
 *		computer_bet - called whenever a bet is needed.
 *		computer_draw - called whenever a draw of cards is needed.
 *		computer_outcome - called at the end of each hand.
 *		computer_hear - called whenever anyone sends a text message.
 *
 *		The interfaces to these six functions are well-defined and should 
 *		remain stable.  You can use this file to entirely alter the playing 
 *		methods of a robot player without being concerned with server 
 *		communication or anything else.
 *
 *	History:
 *		21 Nov 91/JVE	Created.
 */

# include	<stdio.h>
# include	<stdlib.h>
# include	<string.h>
# include	"standard.h"
# include	"cards.h"		/* for crandom, suit, card macros */
# include	"5draw.h"		/* for MAX_PLAYERS */
# include	"knowledge.h"
# include	"robot.h"
# include	"robot_main_protos.h"
# include	"strategy_protos.h"

typedef struct statsrec
	{
	char			*name;				/* player name */
	int				hands;				/* # hands played */
	int				winnings;			/* total winnings (losings) */
	struct statsrec	*next;
	} STATS;

STATS	*stats = NULLP( STATS );

int		Pot(KNOWLEDGE k[]);
STATS	*FindRecord(char *name);


/*
 ***********************************************************************
 *
 * FUNCTION NAME:	strategy_init
 *
 * DESCRIPTION:		Any initialization needed.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *
 * RETURN CODES: 
 *		TRUE		I am ready to play.
 *		FALSE		I'm not playing, just watching.
 *
 * COMMENTS:
 *
 **********************************************************************
 */

int		strategy_init()

	{
	return FALSE;
	}

/*
 ***********************************************************************
 *
 * FUNCTION NAME:	strategy_exit
 *
 * DESCRIPTION:		Actions to be performed on shutdown.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *
 * RETURN CODES: none
 *
 * COMMENTS:
 *
 **********************************************************************
 */

void	strategy_exit()

	{
	talk( "Gotta go.  Bye." );
	}


/*
 ***********************************************************************
 *
 * 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		Minimum bet required to remain in this hand.
 *
 * RETURN CODES: 
 *	(int)		Amount of additional cash to bet.
 *	(-1)		Fold.
 *
 * COMMENTS:
 *
 **********************************************************************
 */

int		computer_bet( knowledge, me, required )

KNOWLEDGE		knowledge[];
int				me;
int				required;

	{
	talk( "What, me bet?  I don't bet." );
	return -1;
	}


/*
 ***********************************************************************
 *
 * 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, me, cmd )

KNOWLEDGE		knowledge[];
int				me;
char			*cmd;

	{
	talk( "What, me discard?  I don't discard." );
	}


/*
 ***********************************************************************
 *
 * FUNCTION NAME:	computer_outcome
 *
 * DESCRIPTION:		Is informed of the outcome of each hand.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *		knowledge	 I		Everything we know about the current hand.
 *		me			 I		Index in knowledge[] of this robot.
 *		winner		 I		Index in knowledge[] winning player.
 *
 * RETURN CODES: none
 *
 * COMMENTS:
 *
 **********************************************************************
 */

void	computer_outcome( knowledge, me, winner )

KNOWLEDGE		knowledge[];
int				me;
int				winner;

	{
	STATS		*p;

	if ( ( p = FindRecord( knowledge[winner].name ) ) == NULLP( STATS ) )
		{
		p = (STATS *) malloc( sizeof( STATS ) );
		p -> name = strdup( knowledge[winner].name );
		p -> next = stats;
		stats = p;
		}
	p -> hands++;
	p -> winnings += Pot( knowledge ) - knowledge[winner].bet;
	}


/*
 ***********************************************************************
 *
 * FUNCTION NAME:	computer_hear
 *
 * DESCRIPTION:		Listen to incoming text message.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *		knowledge	 I		Everything we know about the current hand.
 *		from		 I		Who is message from?
 *		text		 I		Text of message.
 *
 * RETURN CODES: none
 *
 * COMMENTS:
 *
 **********************************************************************
 */

void	computer_hear( knowledge, from, text )

KNOWLEDGE		knowledge[];
char				*from;
char			*text;

	{
	STATS		*p;
	char		temp[MAXLINE];

	if ( strstr( text, myname ) == 0 )
		if ( strstr( text, "EXIT" ) != NULL )
			{
			strategy_exit();
			robot_exit();
			/*NOTREACHED*/
			}
		else if ( strstr( text, "DUMP" ) != NULL )
			{
			sprintf( temp, "%-20s %7s %8s", "PLAYER", "HANDS", "WINNINGS" );
			talk( temp );
			talk( "" );
			for ( p = stats; p != NULLP( STATS ); p = p -> next )
				{
				sprintf( temp, "%s %7d %8d", p -> name, p -> hands, p -> winnings );
				talk( temp );
				}
			}
	}


/*
 ***********************************************************************
 *
 * FUNCTION NAME:	FindRecord
 *
 * DESCRIPTION:		Find stats record for given player name.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *		name		 I		Name of player.
 *
 * RETURN CODES: 
 *
 * COMMENTS:
 *
 **********************************************************************
 */

STATS	*FindRecord( char *name )

	{
	STATS		*p;

	for ( p = stats; p != NULLP( STATS ); p = p -> next )
		if ( strcmp( name, p -> name ) == 0 )
			return p;
	return NULLP( STATS );
	}


/*
 ***********************************************************************
 *
 * FUNCTION NAME:	Pot
 *
 * DESCRIPTION:		Compute total pot for hand.
 *
 * PARAMETERS: 
 *		NAME		I/O		DESCRIPTION
 *		----		---		-----------
 *		k			 I		knowledge of this hand.
 *
 * RETURN CODES: 
 *		(int)		The total pot.
 *
 * COMMENTS:
 *
 **********************************************************************
 */

int			Pot( KNOWLEDGE k[] )

	{
	int		i;
	int		pot = 0;

	for ( i = 0; i < MAX_PLAYERS; i++ )
		{
		if ( k[i].valid )
			{
			pot += k[i].bet;
			}
		}
	return pot;
	}
