// AdvUtil.cpp : Utility functions
//
//    chance
//    getScore
//    random


#include "stdafx.h"
#include "sys/timeb.h"

#include "AdvUtil.h"

bool chance
  (long nProbability)   // probability
//
//  Returns true with the specified probability.
//
{
  return (random(100) < nProbability);
}

void getScore
  (AdvGlobalContext& gc)
//
//  Computes the player's score and updates gc.m_nScore and gc.m_nMaxScore.
//  Uses the following algorithm to compute the score:
//
//  Condition                                       Max possible score
//  ---------                                       ------------------
//  Visited building                                9
//  Able to enter cave (thru debris room or Y2)     20
//  Delivered magazines to Witt's End               1
//  2 points for locating each of 27 treasures      54
//  13 points for keeping each in building          351
//  Visited lair                                    10
//  Visited beach                                   10
//  Visited faces                                   10
//  20 points for each phase of closure             100
//  -10 points for each of 3 allowed deaths         0
//  -5  points for each clue/penalty                0
//                                                  ---
//                                                  565 (Total)
//
{
long  nScore;       // current score
long  nMaxScore;    // maximum possible score

  // Visited building?
  nScore = gc.m_visited [building] ? 9 : 0;
  nMaxScore = 9;

  // Entered cave?
  if (gc.m_bSaidXyzzyPlugh)
     nScore += 20;
  nMaxScore += 20;

  // Delivered magazines to Witt's End?
  if (gc.m_nWhereIs [magazines] == wittsend)
     nScore++;
  nMaxScore++;

  // Tally up treasures seen or transported to well house
  for (long nObject=MINTREASURES; (nObject <= MAXTREASURES); nObject++)
      if ((gc.m_nWhereIs [nObject] == building) || (gc.m_nClosure > 2))
         nScore += 15;
      else
         if (gc.m_seen [nObject])
            nScore += 2;
  nMaxScore += 15 * (MAXTREASURES - MINTREASURES + 1);

  // Visited lair?
  if (gc.m_visited [lair])
     nScore += 10;
  nMaxScore += 10;

  // Visited beach?
  if (gc.m_visited [beach])
     nScore += 10;
  nMaxScore += 10;

  // Visited valley of Faces?
  if (gc.m_visited [faces])
     nScore += 10;
  nMaxScore += 10;

  // 20 points for each phase of closure
  nScore += gc.m_nClosure * 20;
  nMaxScore += 100;

  // Subtract points for dying and penalties
  nScore -= (gc.m_nDeaths*10 + gc.m_nPenalties);

  // Set score
  if (nScore < 0)
     nScore = 0;
  gc.m_nScore = nScore;
  gc.m_nMaxScore = nMaxScore;
}

long random
  (long nLimit) // upper limit
//
//  Returns a random number in the range 0..nLimit-1.
//
{
struct timeb  tbuff;    // time buffer

  // Ensure nLimit is between 1 and 1000
  if (nLimit <= 0)
     nLimit = 0;
  else
     if (nLimit >= 1000)
        nLimit = nLimit % 1000;

  // Return random number
  ftime (&tbuff);
	if (nLimit > 0)
     return ((tbuff.millitm / 10) % nLimit);
  return (0);
}
