

import java.util.*;

public class comet {

    private static final int num_players = 12;

    private static final int num_runs = 3;

    private static final int max_num_in_run = 5;

    private static final int ideal_num_in_run = 4;

    //first, only one chromosome
    static ArrayList chromosome;
    static ArrayList altchrom;
    static int chromeval;
    static int alteval;
    
    static String[] names = {"0", "1", "2", "3", "4", "5", "6",
			     "7", "8", "9", "10", "11"};
    
    static boolean[][] allowed_runs =
    {
	{true, false, true},
	{true, true, true},
	{false, true, true},
	{true, false, true},
	{true, true, true},
	{false, true, true},
	{true, false, true},
	{true, true, true},
	{false, true, true},
	{true, false, true},
	{true, true, true},
	{false, true, true}
    }; //initialize this appropriately

    static Random r = new Random();
    

    private static void evaluate(){
	//evaluate chromosome
	chromeval = 0;
	int[] runs = new int[num_runs];
	for(int i=0; i<num_runs; i++)
	    runs[i] = 0;
	for(int i=0; i<num_players; i++){
	    Integer run = (Integer)chromosome.get(i);
	    int runval = run.intValue();
	    if(allowed_runs[i][runval] == false){
		chromeval -= 10;  //someone coming to a bad run is -10
	    }
	    else
		runs[runval]++;
	}
	for(int i=0; i<num_runs; i++){
	    if(runs[i] != ideal_num_in_run){
		chromeval -= 1; //deviance from ideal is -1
	    }
	}

	//evaluate altchrom
	alteval = 0;
	for(int i=0; i<num_runs; i++)
	    runs[i] = 0;
	for(int i=0; i<num_players; i++){
	    Integer run = (Integer)altchrom.get(i);
	    int runval = run.intValue();
	    if(allowed_runs[i][runval] == false){
		alteval -= 10;
	    }
	    else
		runs[runval]++;
	}
	for(int i=0; i<num_runs; i++) {
	    if(runs[i] != ideal_num_in_run) {
		alteval -= 1;
	    }
	}

    }

    private static void replace(){
	if(alteval > chromeval) {
	    chromosome = altchrom;
	    chromeval = alteval;
	}
    }

    private static void mutate(){
	int which = r.nextInt(10);
	altchrom = new ArrayList();
	altchrom.addAll(chromosome);
	if(which == 0){ //reverse mutation
	    Collections.reverse(altchrom);
	}
	else if (which == 1){ //shuffle mutation
	    Collections.shuffle(altchrom, r);
	}
	else { //swap mutation, most likely

	    int a = r.nextInt(num_runs * max_num_in_run);
	    int b = r.nextInt(num_runs * max_num_in_run);
	    Integer at_a = (Integer)altchrom.get(a);
	    Integer at_b = (Integer)altchrom.get(b);

	    altchrom.set(b, at_a);
	    altchrom.set(a, at_b);
	}
    }

    private static void printit(){
	System.out.println(" ");
	System.out.println("Evaluation is: " + chromeval);
	for(int i=0; i<num_runs; i++){
	    System.out.print("Run " + i + " : ");
	    for(int j=0; j<num_players; j++){
		Integer run = (Integer)chromosome.get(j);
		if((run.intValue() == i) &&
		   (allowed_runs[j][i] == true))//if they're in this run
		    System.out.print(names[j] + " " );
	    }
	    System.out.println(" "); //end the line
	}
    }

    public static void main(String[] args){

	chromosome = new ArrayList();
	altchrom = new ArrayList();

	for(int i=0; i< num_runs; i++){
	    for(int j=0; j < max_num_in_run; j++){
		chromosome.add(new Integer(i));
	    }
	}

	Collections.shuffle(chromosome, r);

	//while(true){
	for(int i=0; i<10; i++){
	        
	    mutate();
	    evaluate();
	    replace();
	    printit();

	}

    }

}

