#include "geo.h"
#include "util.h"


#define FM 1
#define FD 1

/**********************************************************************

	These functions are all similar, differing only in the number
	of arguments they take.

	SYNOPSIS:

		All values are averaged, then modified by a random factor, in
		order to determine a midpoint which reflects some variation.

	EXAMPLE:

		Two points, (a) and (b).  We want to calculate the midpoint.
		It must vary up or down by a small random amount (say 0.7).

		1.	Find the average
		2.	Determine the upper and lower limits of variation
		3.	Determine actual range
		4.	Adjust range for roughness factor

	DIAGRAM:
							 (b)-------
							 /
							/
						 + /  actual midpoint selected
						  /
						 X	calculated average vertical elevation
						/					between (a) and (b)
					   /
					  /
					 /
				---(a)

**********************************************************************/

CELL map_ave2 (CELL a, CELL b)
{
	CELL2	average=0;				// average of all values
	CELL	rMin;					// range maximum
	CELL	rMax;					// range minimum
	CELL 	range;					// range
	CELL2 	modifier;				// modifier (+/-) to average
	CELL2	midpoint;


	// CELL2 arithmetic
	average  = a;
	average += b;

	average >>= 1;

	rMin = MAX_EL;
	rMax = MIN_EL;

	if (rMin > a) rMin = a; if (rMax < a) rMax = a;
	if (rMin > b) rMin = b; if (rMax < b) rMax = b;

	range = rMax - rMin;

		//		(((rolls * sides) - rolls) / 2) + rolls = average
		//-----------------------------------------------------------
		//      (((  2   *   6  ) -   2  ) / 2) + 2 =
		//      ((          12    -   2  ) / 2) + 2 =
		//      (                    10    / 2) + 2 = 7.0
		//-----------------------------------------------------------
		//      (((  3   *   6  ) -   3  ) / 2) + 3 =
		//      ((          18    -   3  ) / 2) + 3 = 
		//		(                    15    / 2) + 3 = 10.5
		//-----------------------------------------------------------

	modifier = dice (1, range) - (range/2);

	modifier *= R;						// adjust for roughness factor
	modifier /= 100;					// poor man's floating point...

	if (modifier<(range>>2))
	{
		modifier *= FM;						// reduce by factor
		modifier /= FD;
	}

	midpoint = average + modifier;		// modify average by random factor

	// range-check

	if		(midpoint > MAX_EL) midpoint = MAX_EL;
	else if (midpoint < MIN_EL) midpoint = MIN_EL;

	return midpoint;
}

CELL map_ave4 (CELL a, CELL b, CELL c, CELL d)
{
	CELL2	average=0;				// average of all values
	CELL	rMin;					// range maximum
	CELL	rMax;					// range minimum
	CELL	range;					// range
	CELL2	modifier;				// modifier (+/-) to average
	CELL2	midpoint;

	// CELL2 arithmetic
	average  = a;
	average += b;
	average += c;
	average += d;
	average >>= 2;

	rMin = MAX_EL;
	rMax = MIN_EL;

	if (rMin > a) rMin = a; if (rMax < a) rMax = a;
	if (rMin > b) rMin = b; if (rMax < b) rMax = b;
	if (rMin > c) rMin = c; if (rMax < c) rMax = c;
	if (rMin > d) rMin = d; if (rMax < d) rMax = d;

	range = rMax - rMin;

	modifier = dice (1, range) - (range/2);

	modifier *= R;						// adjust for roughness factor
	modifier /= 100;					// poor man's floating point...

	if (modifier<(range>>2))
	{
		modifier *= FM;						// reduce by factor
		modifier /= FD;
	}

	midpoint = average + modifier;		// modify average by random factor

	if		(midpoint > MAX_EL) midpoint = MAX_EL;
	else if (midpoint < MIN_EL) midpoint = MIN_EL;

	return midpoint;
}


CELL map_ave5 (CELL a, CELL b, CELL c, CELL d, CELL e)
{
	CELL2	average=0;				// average of all values
	CELL	rMin;					// range maximum
	CELL	rMax;					// range minimum
	CELL	range;					// range
	CELL2	modifier;				// modifier (+/-) to average
	CELL2	midpoint;

	// CELL2 arithmetic
	average  = a;
	average += b;
	average += c;
	average += d;
	average += e;
	average /= 5;

	rMin = MAX_EL;
	rMax = MIN_EL;

	if (rMin > a) rMin = a; if (rMax < a) rMax = a;
	if (rMin > b) rMin = b; if (rMax < b) rMax = b;
	if (rMin > c) rMin = c; if (rMax < c) rMax = c;
	if (rMin > d) rMin = d; if (rMax < d) rMax = d;
	if (rMin > e) rMin = e; if (rMax < e) rMax = e;

	range = rMax - rMin;

	modifier = dice (1,range) - (range/2);

	modifier *= R;						// adjust for roughness factor
	modifier /= 100;					// poor man's floating point...

	if (modifier<(range>>2))
	{
		modifier *= FM;						// reduce by factor
		modifier /= FD;
	}

	midpoint = average + modifier;		// modify average by random factor

	if		(midpoint > MAX_EL) midpoint = MAX_EL;
	else if (midpoint < MIN_EL) midpoint = MIN_EL;

	return midpoint;
}

CELL map_ave8 (CELL a,CELL b,CELL c, CELL d, CELL e, CELL f, CELL g, CELL h)
{
	CELL2	average=0;				// average of all values
	CELL	rMin;					// range maximum
	CELL	rMax;					// range minimum
	CELL	range;					// range
	CELL2	modifier;				// modifier (+/-) to average
	CELL2	midpoint;

	// CELL2 arithmetic
	average  = a;
	average += b;
	average += c;
	average += d;
	average += e;
	average += f;
	average += g;
	average += h;
	average >>= 3;

	rMin = MAX_EL;
	rMax = MIN_EL;

	if (rMin > a) rMin = a; if (rMax < a) rMax = a;
	if (rMin > b) rMin = b; if (rMax < b) rMax = b;
	if (rMin > c) rMin = c; if (rMax < c) rMax = c;
	if (rMin > d) rMin = d; if (rMax < d) rMax = d;
	if (rMin > e) rMin = e; if (rMax < e) rMax = e;
	if (rMin > f) rMin = f; if (rMax < f) rMax = f;
	if (rMin > g) rMin = g; if (rMax < g) rMax = g;
	if (rMin > h) rMin = h; if (rMax < h) rMax = h;

	range = rMax - rMin;

	modifier = dice (1,range) - (range/2);

	modifier *= R;						// adjust for roughness factor
	modifier /= 100;					// poor man's floating point...

	if (modifier<(range>>2))
	{
		modifier *= FM;						// reduce by factor
		modifier /= FD;
	}

	midpoint = average + modifier;		// modify average by random factor

	if		(midpoint > MAX_EL) midpoint = MAX_EL;
	else if (midpoint < MIN_EL) midpoint = MIN_EL;

	return midpoint;
}
