
#import "Simulator.h"
#import "RanGen.h"
#import <appkit/appkit.h>
#import <appkit/Application.h>

@implementation Simulator

+ new
{
  self = [super new];
	theRanGen = [RanGen new];
	
	monthNr = 0;
	capital = 5000.0;
	inflationLoss = 0;
	inflation = 0.31;
	profit = 0;
	profitSum = 0;
	meanProfit = 0;
	percentProfitSum = 0;
	meanPercentProfit = 0;
	return self;
}


- out:sender
{
  int i;
  actionNumber = 0;
	for (i=1; i<=4; i++)
	{
	  if (eval[i] > eval[actionNumber]) actionNumber = i;
	}
	[self month];
	return self;
}


- setRandomValues
{
  int i,min,max;
	double r1,r2,r3;
	
	r1 = [theRanGen lowInt:20 highInt:40] / 100.0;
	r2 = [theRanGen lowInt:20 highInt:40] / 100.0;
	r3 = [theRanGen lowInt:20 highInt:40] / 100.0;
	inflation = (r1 + r2 + r3) / 3; // 0.2% to 0.4% per month
	
  for (i=0; i<5; i++)
	{
	  min = (int)(0.05*capital + 0.5);
	  max = (int)(0.20*capital + 0.5);
	  cost[i] = [theRanGen lowInt:(min*100) highInt:(max*100)] / 100.0;
	  probability[i] = [theRanGen lowInt:670 highInt:995] / 10.0; // %
		r1 = (double)([theRanGen lowInt:170 highInt:250]) / 200.0; //0.9 to 1.1
		expProfit[i] = r1*cost[i];
		eval[i] = (probability[i]/100)*expProfit[i] - cost[i];

  	[costForm setDoubleValue:cost[i] at:i];
	  [succProbForm setDoubleValue:probability[i] at:i];
  	[expProfitForm setDoubleValue:expProfit[i] at:i];
  	[evalForm setDoubleValue:eval[i] at:i];
	};
	return self;
}


- aPressed:sender
{
  actionNumber = 0;
	[self month];
  return self;
}


- bPressed:sender
{
  actionNumber = 1;
	[self month];
  return self;
}


- cPressed:sender
{
  actionNumber = 2;
	[self month];
  return self;
}


- dPressed:sender
{
  actionNumber = 3;
	[self month];
  return self;
}


- ePressed:sender
{
  actionNumber = 4;
	[self month];
  return self;
}


- month
{
  double oldCapital, percentProfit, r;
	
  chosenCost = cost[actionNumber];
	chosenProbab = probability[actionNumber];
	chosenProfit = expProfit[actionNumber];
	oldCapital = capital;
	
	// inflation loss:
	capital -= chosenCost; // the invested money
	inflationLoss = capital * (inflation / 100.0);
	capital -= inflationLoss;
	
	// profit:
	r = [theRanGen ran01];
	if (r <= chosenProbab/100.0) // success!
	{
	  capital += chosenProfit; // the return
		profit = chosenProfit - chosenCost; // the true profit
	}
	else // no success:
	{
	  profit = -chosenCost;
	};
	percentProfit = (profit / oldCapital) * 100;
	percentProfitSum += percentProfit;
  profitSum += profit;
	monthNr++;
	meanProfit = profitSum / monthNr;
	meanPercentProfit = percentProfitSum / monthNr;
	
	[self output];
	return self;
}


- output
{
	// output of last month`s result:
	[monthNrField setIntValue:monthNr];
	[inflationField setDoubleValue:inflation];
	[inflationLossField setDoubleValue:inflationLoss];
	[profitField setDoubleValue:profit];
	[capitalField setDoubleValue:capital];
	[meanProfitField setDoubleValue:meanProfit];
	[meanPercentProfitField setDoubleValue:meanPercentProfit];
	
	// new actions:
	[self setRandomValues];
	
	return self;
}


@end