/
Sapphire/bin/
Sapphire/db/
Sapphire/db/OLC_rooms/
Sapphire/db/abi/
Sapphire/db/em_src/
Sapphire/db/helps/
Sapphire/db/helps/emman/ifunc/
Sapphire/db/npcs/Tatt/
Sapphire/db/objects/Tatt/
Sapphire/db/q_data/
Sapphire/db/rooms/Tatt/
Sapphire/doc/
Sapphire/doc/em/
Sapphire/etc/
Sapphire/src/abic/
Sapphire/src/areacon/
Sapphire/src/client/
Sapphire/src/embc/
Sapphire/src/emi/
Sapphire/src/emi/test/
Sapphire/src/include/
Sapphire/src/sapphire/em/
Sapphire/src/tcon/
/*
 * Copyright (C) 1995-1997 Christopher D. Granz
 *
 * This header may not be removed.
 *
 * Refer to the file "License" included in this package for further
 * information and before using any of the following.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

#include "sapphire.h"


/*
 * Globals
 */
static int                                             rgiState[2 + 55];


/*
 * Functions
 */
void init_random( void )
{
    int *piState;
    int iState;

    piState             = &rgiState[2];

    piState[-2]         = 55 - 55;
    piState[-1]         = 55 - 24;

    piState[0]          = ( (int) tCurrentTime ) & ( ( 1 << 30 ) - 1 );
    piState[1]          = 1;

    for ( iState = 2; iState < 55; iState++ )
    {
        piState[iState] = ( piState[iState-1] + piState[iState-2] )
                          & ( ( 1 << 30 ) - 1 );
    }
}


int random_number( void )
{
    int *piState;
    int iState1;
    int iState2;
    int iRand;

    piState             = &rgiState[2];
    iState1             = piState[-2];
    iState2             = piState[-1];
    iRand               = ( piState[iState1] + piState[iState2] )
                          & ( ( 1 << 30 ) - 1 );
    piState[iState1]    = iRand;

    if ( ++iState1 == 55 )
        iState1         = 0;

    if ( ++iState2 == 55 )
        iState2         = 0;

    piState[-2]         = iState1;
    piState[-1]         = iState2;

    return ( iRand >> 6 );
}


/*
 * Create a rondom number.
 */
int random_range( int iFrom, int iTo )
{
    int iPower;
    int iNumber;

    if ( iFrom == 0 && iTo == 0 )
        return ( 0 );

    if ( ( iTo = ( iTo - iFrom + 1 ) ) <= 1 )
        return ( iFrom );

    for ( iPower = 2; iPower < iTo; iPower <<= 1 );

    while ( ( iNumber = random_number( ) & ( iPower - 1 ) ) >= iTo );

    return ( iFrom + iNumber );
}


/*
 * Create a random percent.
 */
int random_percent( void )
{
    int iPercent;

    while ( ( iPercent = random_number( ) & 127 ) > 99 );

    return ( iPercent + 1 );
}


int random_bits( int iWidth )
{
    return ( random_number( ) & ( ( 1 << iWidth ) - 1 ) );
}


/*
 * Generate a random door.
 */
int random_door( void )
{
    int iDoor;

    while ( ( iDoor = random_number( ) & 7 ) > 9 );

    return ( iDoor );
}


/*
 * Roll some dice.
 */
int roll_dice( int iNumber, int iSize )
{
    int iDice;
    int iSum;

    switch ( iSize )
    {
      case 0: return ( 0 );
      case 1: return ( iNumber );
    }

    for ( iDice = 0, iSum = 0; iDice < iNumber; iDice++ )
        iSum += random_range( 1, iSize );

    return ( iSum );
}


/*
 * Round off a number.
 *
 * Fusion's (Developer of MUD++) version.
 */
long round( register long rlNumber, register int riRoundBy )
{
    register int riRemainder = ( rlNumber % riRoundBy );

    if ( riRemainder > ( riRoundBy >> 1 ) )
        return ( rlNumber + ( riRoundBy - riRemainder ) );

    return ( rlNumber - riRemainder );
}

#if 0
/*
 * My version.
 */
long round( register long rlNumber, register int riRoundBy )
{
    register long rlNewNumber = 0;
    register int riDiff;

    if ( rlNumber <= 0 || riRoundBy <= 1 )
        return ( rlNumber );

    while ( rlNewNumber < rlNumber )
        rlNewNumber          += riRoundBy;

    if ( ( riDiff = ( rlNewNumber - rlNumber ) ) == 0 )
        return ( rlNumber );

    if ( riDiff >= ( riRoundBy >> 1 ) )
        return ( rlNewNumber - riRoundBy );

    return ( rlNewNumber );
}
#endif

/*
 * End of random.c
 */