/*===========================================================================
 *
 * DICE.CPP - 30 March 1999, Dave Humphrey
 *
 *=========================================================================*/

	/* Include Files */
#include "Dice.h"


#undef  __FUNC__
#define __FUNC__ "RollDice()"
/*===========================================================================
 *
 * Function - int RollDice (pString);
 *
 * Parses the given string to a die roll and returns a number based on the
 * random roll.  The string is of the general form.
 *		#d#+#-#
 * All elements are optional and can appear in any order.  On any error the
 * function will return 0.
 *
 *=========================================================================*/
int RollDice (const char* pString) {
  boolean ParsingString;
  boolean ReadDice;
  char*   pDiceString;	
  char*   pDiceChar;
  char*   pNumber;
  int     LastNumber;
  int     NewNumber;
  int	  Negative;
  int     DiceSum;

	/* Ensure the input string is valid */
  if (pString == NULL) return (0);

	/* Copy the given string so we can modify it */
  pDiceString = CreateString(pString);
  pDiceChar = pDiceString;
  pNumber = pDiceString;

	/* Initialize parsing and loop variables */
  ParsingString = TRUE;
  ReadDice = FALSE;
  LastNumber = 0;
  NewNumber = 0;
  Negative = 1;
  DiceSum = 0;

	/* The main parsing loop */
  while (ParsingString) {

		/* Determine action by the character type */
    switch (tolower(*pDiceChar)) {

		/* A dice count character */
      case 'd': 
        *pDiceChar = NULL_CHAR;

	if (*pNumber == NULL_CHAR)
	  LastNumber = Negative;
	else
	  LastNumber = Negative * atoi(pNumber);

	pNumber = pDiceChar + 1;
	ReadDice = TRUE;
	break;

		/* A negative modifier */
      case '-':
	*pDiceChar = NULL_CHAR;
	NewNumber = Negative * atoi(pNumber);
	pNumber = pDiceChar + 1;

	if (ReadDice)
	  DiceSum += RollDice(LastNumber, NewNumber);
	else
	  DiceSum += NewNumber;

	Negative = -1;
        ReadDice = FALSE;
	break;

		/* A positive modifier */
      case '+':
        *pDiceChar = 0;
	NewNumber = Negative * atoi(pNumber);
	pNumber = pDiceChar + 1;

	if (ReadDice) 
	  DiceSum += RollDice(LastNumber, NewNumber);
	else
	  DiceSum += NewNumber;

	ReadDice = FALSE;
	Negative = 1;
	break;

		/* End of string */
      case NULL_CHAR: 
        NewNumber = Negative * atoi(pNumber);

	if (ReadDice) 
	  DiceSum += RollDice(LastNumber, NewNumber);
	else
	  DiceSum += NewNumber;

	ParsingString = FALSE;
	break;
      default:
	break;
     }
 
    pDiceChar++;
   }

	/* Unallocate the temporary parsing string and return result */
  DestroyPointer(pDiceString);
  return (DiceSum);
 }
/*===========================================================================
 *		End of Function RollDice()
 *=========================================================================*/


#undef  __FUNC__
#define __FUNC__ "RollDice()"
/*===========================================================================
 *
 * Function - int RollDice (RollCount, NumSides);
 *
 * Rolls a dice in the form (RollCount d NumSides) and returns the numeric 
 * result of the random roll.
 *
 *=========================================================================*/
int RollDice (const int RollCount, const int NumSides) {
  float Factor;
  int   DiceSum;
  int   SideCount;

	/* Initialize loop variables */
  Factor = (float)NumSides;
  DiceSum = 0;

  for (SideCount = 0; SideCount < NumSides; SideCount++) {
    DiceSum += (int)(rand()*Factor/RAND_MAX) + 1;
   }

  return (DiceSum);
 }
/*===========================================================================
 *		End of Function RollDice()
 *=========================================================================*/