/* Ars Brute Squad EPGP Simulator. www.arsbrutesquad.com
(c) Andrew Brennan 2008 - Andyfb on Chromaggus US
Feel free to distribute, modify and improve this widget I have built. Just gimme some credit!
*/

import java.util.*;

class epgp {
	
	
public static float EP[] = new float[35]; //effort points
public static float GP[] = new float[35]; //gear points
public static float PR[] = new float[35]; //priority rating
public static int rank[] = new int[35]; //RP rank
public static int loot[] = new int[35]; //amount of loot received
public static int raids[] = new int[35]; //amount of raids attended
public static int attending[] = new int[35]; //is the player attending the current raid?

//***Here is what you modify to change how the sim works***
public static int basegp = 300; //The GP a new player gets when entering the system
public static int decay = 5; //The decay rate. Percentage values. 10% is very high. 
public static int itemcost = 350; //The average cost of an item. Using the default values in the EPGP mod, 350 is average for T5
public static int bossep = 1000; //The average EP rewarded for a boss kill. Reward the hardcore players by making this number higher. Keep it low to keep a good balance.
public static int bossloot = 3; //The average number of items dropped per boss. 4 might actually be right here considering Tier tokens and patterns.
public static int attendep = 300; //EP awarded for turning up on time, repaired and prepared.
public static int numraids = 10; //The number of raids the simulator will run before giving the final standings.
public static int bossperraid = 3; //The average number of bosses killed per raid. We do short raids, so 3 or 4 is right for us.

public static Random random = new Random();


	public static void main(String[] args) {

	int i, j;

	//1. Create a raid. 0-14 attend. 10 random players from 15-24 attend. Each attendee gets 500EP. Everyone is docked 5%EP 
	//2. Kill a boss. Each player gets 1000EP.
	//3. Boss drops loot. The top 3 ranked players are given items.
	//4. GOTO 2 for 2 more boss kills.
	//5. GOTO 1 for a new raid.


	System.out.println("Assuming 35 players. Players 1-15 raid every night. Players 16-35 raid occasionally.");
	System.out.println("Players are sorted by rating. Loot is assigned to the top ranked player");
	System.out.println("Each attending player gets " +attendep +"EP for turning up.");
	System.out.println("Decay is " +decay +"%. Base GP is " +basegp);
	System.out.println("One raid = " +bossperraid +" bosses. One boss = " + bossep +"EP.");
	System.out.println("Each boss drops " +bossloot +" pieces of loot. Each piece costs " +itemcost +" GP.");
	System.out.println("Number of raids = " +numraids);

	System.out.println();

	//intialise all EP to 0, all GP to basegp, all rank to 0, all loot to 0, all raid to 0;
	for(i=0;i<35;i++)
		{
		EP[i]=0;
		GP[i]=basegp;
		rank[i]=0;
		loot[i]=0;
		raids[i]=0;
		}

	for(i=0;i<numraids;i++)
		{
		//generate a raid lineup
		createraid();

		//report the raid lineup and initial points
		System.out.println("Raid created, lineup is:");
		reportstandings();

		for(j=0;j<bossperraid;j++)
			{
			//kill a boss, assign EP and loot, rereport standings
			killboss();
			reportstandings();
			}
		
		//at the end of every raid, decay.
		System.out.println("Decaying!");
		decayall();
		}

	System.out.println("\nFinal Standings:");
	reportstandings();
	}


	public static void decayall()
		{
		//reduce each GP and EP by decay%. PR's stay the same.
		int i;
		
		for(i=0;i<35;i++)
			{
			EP[i] = EP[i] * (100-decay)/100;
			GP[i] = GP[i] * (100-decay)/100;
			}
		}

	
	public static void reportstandings()
		{
		int i;

		for(i=0;i<35;i++)
			{
			if( attending[i]==1 )
				System.out.println("#"+(i+1) +" is in. EP = " +EP[i] + ". GP = " + GP[i] + ". PR = " +PR[i] +". RA = " +raids[i] +". LR = " +loot[i]);
			else
				System.out.println("#"+(i+1) +" is out. EP = " +EP[i] + ". GP = " + GP[i] + ". PR = " +PR[i] +". RA = " +raids[i] +". LR = " +loot[i]);
			}
		System.out.println();
		}


	public static void createraid()
		{
		//procedure to create a raid, decide attendees, decay scores, assign attendance EP and calculate current rankings
		int i;

		//set all players = not attending
		for(i=0;i<35;i++)
			attending[i]=0;

		//set the first 10 players = attending (the hardcore)
		for(i=0;i<10;i++)
			{
			attending[i]=1;
			raids[i]+=1;
			}

		//pick 10 random players from 10-25 to attend (the mediumcore)
		i=0;
		while( i<10 )
			{
			int x = random.nextInt(15) +10;
			
			if( attending[x]==0)
				{
				attending[x]=1;
				raids[x]+=1;
				i++;
				}
			}

		//pick 5 random players from 25-35 to attend (the mediumcore)
		i=0;
		while( i<5 )
			{
			int x = random.nextInt(10) +25;
			
			if( attending[x]==0)
				{
				attending[x]=1;
				raids[x]+=1;
				i++;
				}
			}

		//award each attendee their EP for turning up
		for(i=0;i<35;i++)
			if(attending[i]==1)
				EP[i]+=attendep;

		//calculate all rankings
		calcrank();
		}


	public static void calcrank()
		{
		//calculate priority ranking
		int i;

		//calculate each PR
		for(i=0;i<35;i++)
			if(attending[i]==1)
				PR[i] = EP[i]/GP[i];
		}


	public static int toprank()
		{
		//funtion to find the attendee with the highest PR. If there's a tie, pick one of those high players at random.

		int i;
		int numhigh=0; //the number of highest players
		int highplayer[] = new int[35]; //the record of the highest players
		int numwinner; //the position in highplayer of the winning player
		int winner; //the player number of the player who wins
		float highest = 0;

		//search for highest PR player(s)
		for(i=0;i<35;i++)
			{
			if( attending[i] == 1 && PR[i] > highest )
				{
				//found a new highest player
				numhigh = 1;
				highplayer[0] = i;
				highest = PR[i];
				}
			else if ( attending[i] == 1 && PR[i] == highest )
				{
				//found a new player with same PR as highest
				numhigh+=1;
				highplayer[numhigh-1] = i;
				}
			}
		
		//test code for random winner
		System.out.println( "Found " +numhigh +" players eligible for loot: ");
		for(i=0;i<numhigh;i++)
			System.out.print(" #" +(highplayer[i]+1) );
		System.out.println();

		numwinner = random.nextInt(numhigh); //if there's only 1 high player, this will always return 0
		winner = highplayer[numwinner];
		System.out.println("Player #" +(winner+1) +" wins loot!\n");

		return winner;
		}
				
	
	public static void killboss()
		{
		//procedure to award EP and assign loot for killing a boss.
		int i;
		int top;

		System.out.println("Boss killed! Assigning " +bossloot +" pieces of loot:");

		for (i=0;i<bossloot;i++)
			{
			//assign GP to top ranked player and recalculate their PR
			top = toprank();
			GP[top] += itemcost;
			loot[top]+=1;
			PR[top] = EP[top] / GP[top];
			}

		//assign EP to all players and recalculate their PR
		for(i=0;i<35;i++)
			if(attending[i]==1)
				{
				EP[i]+=bossep;
				PR[i] = EP[i]/GP[i];
				}
		}
}
