Welcome to my Website!

This is a paragraph! Here's how you make a link: Neocities.

Here's how you can make bold and italic text.

Here's how you can add an image:

Here's how to make a list:

    
    Version 1:  
    
    import java.util.Scanner;

public class KeyChains{
    
    public static void main(String[] args){
        
        Scanner k = new Scanner(System.in);
        double price = 10;
        int keyNum = 0;
        double tax = .0825;
        double shipping = 5;
        double addedShipping = 0;
        
        int i = 0;
    
        while(i != 4){
            
            System.out.println("");
            System.out.println("Keychain shop");
            System.out.println("");
            System.out.println("1) Add Keychains to your order");
            System.out.println("2) Remove Keychains from your order");
            System.out.println("3) View your current order");
            System.out.println("4) Checkout");
            System.out.println("");
            System.out.print("Please enter your choice: ");
            
            i = k.nextInt();
            System.out.println("");
            
            switch(i){
                case 1: keyNum = addKeychains(keyNum);
                    break;
                case 2: keyNum = removeKeychains(keyNum);
                    break;
                case 3: viewOrder(price, keyNum);
                    break;
                case 4: checkout(price, keyNum);
                    break;
                default: System.out.println("That's not a valid choice."); break;
            }
        }
        
    }
    
    public static int addKeychains(int currentNum){
        Scanner k = new Scanner(System.in);
        System.out.print("You currently have " + currentNum + " keychains in your order. How many do you want to add? ");
        int added = k.nextInt();
        return currentNum + added;
    }
    public static int removeKeychains(int currentNum){
        Scanner k = new Scanner(System.in);
        System.out.println("You currently have " + currentNum + " keychains in your order. How many do you want to remove? ");
        int removed = k.nextInt();
        if(currentNum - removed >= 0){
            return currentNum - removed;
        }
        else{
            System.out.println("You can't have negative keychains...");
            return currentNum;
        }
    }
    public static void viewOrder(double kPrice, int currentNum, double tax, double dShip, double ship){
        Scanner k = new Scanner(System.in);
        System.out.println("Keychains: " + currentNum);
        System.out.println("Price: $" + kPrice);
        System.out.println("Shipping Costs: $" + (dShip + currentNum * ship));
        System.out.println("Taxes: $" + (tax * (dShip + currentNum * ship) + tax * (kPrice * currentNum)));
        System.out.println("Total Price: $" + (kPrice * currentNum));
    }
    public static void checkout(int kPrice, int currentNum){
        Scanner k = new Scanner(System.in);
        System.out.print("What's your name? ");
        String name = k.next();
        System.out.println("Keychain: " + currentNum);
        System.out.println("Price: $" + kPrice);
        System.out.println("Total Cost: " + (kPrice * currentNum));
        System.out.println("Thanks for your order, " + name + "!");
        
    }

}
    
    package NeuralNetwork2;

import java.util.Scanner;
import java.util.Random;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.*;
import java.awt.*;

import javax.swing.BorderFactory; 
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.awt.event.MouseEvent;

public class ReccurentNeuralNet extends JPanel{

	Timer timer;
	int speed = 2;
    
	String symbols = "abcdefghijklmnopqrstuvwxyz;:',!?.()\"123456789 ";
	
    int screenCordX = 0;
    int screenCordY = 0;
    
    public JScrollPane scroller;
    public JScrollPane scroller2;
    public JTextArea display;
    public JTextField inputLine;
    
	public static Circle[] foodArray;
	public static Circle base;
    
    int xTransform = 0;
    int yTransform = 0;
    
    int switchType = 0;
    
    CompBrain[] brainList;
    int[][] weightTypes;
    int[][] inputWeightTypes;
        
	public static int rNum = 1;
	public static int cNum = 1000;
	public static int inNum = 46;
	public static int outNum = 46;
    
    public Brain first;
    public CompBrain comp;
    
    public static int keepBrainNum = 0;
    
	public static int foodNum = 20;
	public static int brainNum = 0;
    
    public static double mutationPercent = .10;

	static CompBrain[] brains;
	static String[] brainFileLoc;
	static Neuron[] inputs;

	int count = 0;
	int maxCount = 10000;

	int genNum = 2;

	public void paintComponent(Graphics g){

		super.paintComponent(g);

	}
    
    // Checklist: -Check the getOutputValueAt() function and where it is used. It might be wrong.
    
    
    // Done:      -Find and set each target value.
    //            -Finish adding the new neurons to the list of active neurons.
    //            -At each point I need to make each neuron store the value it has when it activates. The net value and the value after being passed through
    //             the activation function. DONE
    //            -Create a function that does this: If an output neuron is activated that isn't the correct one, and the other desired output neuron has a value of
    //             zero, randomly connect that neuron to other neurons that are activated at that time to make sure it will have some way of working. Because if it
    //             isn't connected to any neurons that are activated at that time, it won't ever be able to work, no matter what. Do this by looping through every neuron
    //             and check every time on each neuron. If one of them is the right time, form a connection between the two of them.
    
    public Brain backPropagate(Brain b){
        
        Neuron[] activeNeurons = new Neuron[rNum * cNum + outNum];
        int activeNeuronCount = outNum;
        double learningRate = .5;
        //Sets all of the active neurons to the outputs because they are the first ones that need to be checked.
        for(int i = 0; i < outNum; i++){
            activeNeurons[i] = b.getNeuron(i + rNum * cNum);
        }

        boolean first = true;
        
        //Loop through all of the time the brain was active.
        for(int i = b.getTotalTime(); i >= 0; i--){
            
            //Loops through all of the active neurons.
            for(int u = 0; u < activeNeuronCount; u++){
                //Loops through all of the inputs into the certain neuron.
                for(int y = 0; y < activeNeurons[u].getInputCount(); y++){
                    
                    Neuron n = activeNeurons[u];
                    Neuron iN;
                    //This will return a negative number if it is an input neuron.
                    if(n.getInputs(y) > 0){
                        iN = b.getNeuron(n.getInputs(y));
                    }
                    else{
                        iN = b.getInputNeurons(n.getInputs(y));
                    }
                    
                    //This is the value holds all of the various partial derivatives that the next weight will depend on.
                    double keepValue;
                    
                    //The value that the neuron is supposed to have at a certai point in time.
                    double targetValue = activeNeurons[u].getTargetValueAt(i);
                    
                    for(int z = 0; z < iN.getTimeCount(); z++){
                        if(iN.getTimes(z) == i){
                            if(first == true){
                                
                                double outputValue = n.getOutputValueAt(iN.getTimes(z));
                                if(targetValue > 0 && outputValue == 0){
                                    for(int a = 0; a < rNum * cNum; a++){
                                        Neuron test = b.getNeuron(a);
                                        for(int c = 0; c < test.getTimeCount(); c++){
                                            if(test.getTimes(c) == i){
                                                if(Math.random() < .5){
                                                    b.createWeights(test.getNum(), iN.getNum(), Math.random() * 16);
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                double dError = -(targetValue - outputValue) * (outputValue * (1 - outputValue)) * iN.getOutputValues(z);
                                
                                //This value will be passed to the next layer the is backpropagated.
                                keepValue = -(targetValue - outputValue); // * (outputValue * (1 - outputValue));
                                b.setKeepValue(n.getInputs(y) - (rNum * cNum), u, keepValue /* + iN.getValuePassed() I don't remember why I put this here...*/, i);
                                
                                //Next, mutiply by the learning rate and subtract that value from the weight.
                                double newWeight = Brain.toDecimal(b.getWeights(iN.getNum(), n.getNum())) - dError * learningRate;
                                b.setWeights(iN.getNum(), n.getNum(), Brain.toBinary(newWeight));

                            }
                            else{
                                double outputValue = n.getOutputValueAt(iN.getTimes(z));
                                double outErrors[] = new double[outNum];
                                double totalError = 0;
                                for(int x = 0; x < outNum; x++){
                                    if(n.getKeepValue(x) != 0){
                                        outputValue = n.getOutputValueAt(iN.getTimes(z));
                                        double newKeepValue;
                                        if(n.getInputs(y) > 0){ //Have to add another part for input weights
                                            
                                            //This could be wrong, the ending part.
                                            newKeepValue = n.getKeepValue(x) * (outputValue * (1 - outputValue)) * (outputValue * Brain.toDecimal(b.getWeights(n.getNum(), iN.getNum())));
                                            b.setKeepValue(n.getInputs(y) - (rNum * cNum), u, newKeepValue, i);
                                        }
                                        else{
                                            newKeepValue = n.getKeepValue(x) * (outputValue * (1 - outputValue)) * (outputValue * Brain.toDecimal(b.getInputWeights(n.getNum(), iN.getNum())));
                                            b.setKeepValue(n.getInputs(y) - (rNum * cNum), u, newKeepValue, i);
                                        }
                                        totalError += newKeepValue * iN.getOutputValueAt(iN.getTimes(z));
                                    }
                                }
                                //Next, mutiply by the learning rate and subtract that value from the weight.
                                if(n.getInputs(y) > 0){  //Have to add another part for input weights.
                                    double newWeight = Brain.toDecimal(b.getWeights(iN.getNum(), n.getNum())) - totalError * learningRate;
                                    b.setWeights(iN.getNum(), n.getNum(), Brain.toBinary(newWeight));
                                    activeNeuronCount++;
                                    activeNeurons[activeNeuronCount] = iN;
                                    n.addActivated();
                                }
                                else{
                                    double newWeight = Brain.toDecimal(b.getWeights(iN.getNum(), n.getNum())) - totalError * learningRate;
                                    b.setInputWeights(iN.getNum(), n.getNum(), Brain.toBinary(newWeight));
                                }
                            }
                        }
                        else if(iN.getTimes(z) < u){
                            break;
                        }
                        
                    }
                    
                }
                
            }
            first = false;

        }
        return b;
    }
    
    // This function will call itself inside it to keep digginf deeper into the network. Once it digs as deep as it can, it will begin to go back out then in. It will
    // repeat this process until it climbs back out to the original function. This is called a recursive function. Just an idea.

    public void checkBackPropagate(Brain b, int timeLeft, Neuron n){
        
    }
	
    public CompBrain[] shiftArray(int num, CompBrain[] brainArray){
    
        CompBrain[] tempBrain = new CompBrain[brainArray.length];
        tempBrain = (CompBrain[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
            if(i == num){
                brainArray[i] = null;
            }
            else{
                brainArray[i] = tempBrain[i - 1];
            }
        }
        
        return brainArray;
    
    }

	public static void main(String[] args){

		brains = new CompBrain[brainNum];
        
		ReccurentNeuralNet content = new ReccurentNeuralNet();
        JFrame window = new JFrame();
		window.setContentPane(content);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setLocation(120,70);
		window.setSize(640,480);
		window.setVisible(true);

	}

	class Task extends TimerTask {
        
		public void run(){
            /*
			count++;
			String[] inputArray = new String[inNum];
			
			for(int i = 0; i < brainNum; i++){
				brains[i].calculateWeights(inputArray);
				brains[i].calculateMovement();
			}

			repaint();
            */
		}
        
	}
    
    public class mouseListener implements MouseMotionListener, MouseListener {
        
        boolean mouseHeld = false;
        int x1, x2, xDistance;
        int y1, y2, yDistance;
        
        public void mouseClicked(MouseEvent e){}
        public void mouseDragged(MouseEvent e){
            if(mouseHeld == true){
                x2 = e.getX();
                y2 = e.getY();
                
                xDistance = x1 - x2;
                yDistance = y1 - y2;
                
                xTransform += -xDistance;
                yTransform += -yDistance;
                
                x1 = x2;
                y1 = y2;
            }
        }
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}
        public void mouseMoved(MouseEvent e){}
        public void mousePressed(MouseEvent e){
            mouseHeld = true;
            x1 = e.getX();
            y1 = e.getY();
        }
        public void mouseReleased(MouseEvent e){
            mouseHeld = false;
        }
        public void mouseWheel(MouseEvent e){}
        
    }
    
    public class textListener implements ActionListener{
    
        public void actionPerformed(ActionEvent e){
            
            display.setText(display.getText() + inputLine.getText() + "\n");
            String[] inputs = new String[inputLine.getText().length()];
            String[] inputs2 = new String["What is Sam?".length()];
            
            for(int i = 0; i < inputLine.getText().length(); i++){
                inputs[i] = "" + inputLine.getText().charAt(i);
            }
            
            for(int i = 0; i < "What is Sam?".length(); i++){
                inputs2[i] = "" + "What is Sam?".charAt(i);
            }
            
            boolean goOn = false;
            
            String[][] emptyWeights = new String[rNum * cNum][rNum * cNum * 2 + outNum + 2];
            Brain brain =  new Brain(rNum, cNum, true, emptyWeights, 10, outNum, inNum);
            /*
            while(goOn == false){
            	
                int addNum = 0;
            	if(genNum % 2 == 1){
            		addNum = brainNum;
            	}
            	for(int i = 0; i < brainNum; i++){
            		System.out.println("Calculating...");
            		brains[i] = openBrain(brainFileLoc[i], i + addNum);
            		brains[i].calculateWeights(inputs);
            		System.out.println("Calculated.");
            		System.out.println("Calculating response...");
            		String reply = brains[i].getBrain().calculateWeights(inputs2);
            		System.out.println(reply);
            		System.out.println("Calculated...");
            		int score = calculateScore("A cat.", reply);
            		//improveBrain(brains[i], inputs, "What is Sam?", "A cat.", score);
            		//display.setText(display.getText() + reply + "\n");
            		brains[i].setScore(score);
            		saveBrain(brains[i], i + addNum);
            		CompBrain emptyBrain = new CompBrain(0, 0, 0, 0, 0, 0, false, null, 0, null);
            		emptyBrain.setScore(score);
            		brains[i] = emptyBrain;
            	}
            	createNextGen();
            	genNum++;
            }
            inputLine.setText("");
            comp.calculateWeights(inputs);
            //first.setInputs(inputs);
            //System.out.println("Generating a reply...");
            String reply = comp.getBrain().calculateWeights(inputs);
            */
            
            //I don't remember what this is...   double[][] desiredOutputs = new double[][outNum];
            String reply = null;
            while(goOn == false){
                reply = brain.calculateWeights(inputs2, inputLine.getText());
                
            }
            
            inputLine.setText("");    
            
            display.setText(display.getText() + reply + "\n");
        }
    
    }
    
    public void saveBrain(CompBrain brain, int brainNum){
    	
    	try{
    		FileOutputStream fos = new FileOutputStream("C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + brainNum + ".dat");
    		ObjectOutputStream out = new ObjectOutputStream(fos);
    		out.writeObject(brain);
    		fos.close();
    		out.close();
    	}
    	catch(IOException e){
    		
    	}
    	
    }
    
    public CompBrain openBrain(String fileLoc, int num){
    	
    	CompBrain brain = null;
    	try{
    		FileInputStream fIS = new FileInputStream("C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + num + ".dat");
    		ObjectInputStream iNS = new ObjectInputStream(fIS);
    		try{
    			brain = (CompBrain) iNS.readObject();
    		}
    		catch(ClassNotFoundException e){
    			
    		}
    		fIS.close();
    		iNS.close();
    	}
    	catch(IOException e){
    		
    	}
    	
    	return brain;
    	
    }
    
	public ReccurentNeuralNet(){

		//timer = new Timer();
		//timer.schedule(new Task(), 0, speed);
        
        //int rows, int columnNumber, boolean first, String[][] weight, int bRadius, int outputNum, int inputNum
        weightTypes = new int[rNum * cNum][rNum * cNum + rNum * cNum + outNum + inNum + 2];
        inputWeightTypes = new int[inNum][rNum * cNum];
		String[][] emptyWeights = new String[rNum * cNum][rNum * cNum * 2 + outNum + 2];
        brains = new CompBrain[brainNum];
        brainFileLoc = new String[brainNum];
        for(int i = 0; i < brainNum; i++){
        	
        	Brain f = new Brain(rNum, cNum, false, emptyWeights, 10, outNum, inNum);
        	CompBrain compBrain = new CompBrain(rNum, cNum, rNum, cNum, outNum, inNum,  true, emptyWeights, inNum, f);
        	brainFileLoc[i] = "C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + i + ".dat";
        	saveBrain(compBrain, i);

        }
        Border textBorder = BorderFactory.createEtchedBorder();
        
        display = new JTextArea(25, 55);
        display.setBorder(textBorder);
        display.setEditable(false);
        scroller = new JScrollPane( display );
        this.add(scroller);
        
        inputLine = new JTextField("", 55);
        inputLine.setBorder(textBorder);
        inputLine.addActionListener(new textListener());
        scroller2 = new JScrollPane( inputLine );
        //scroller2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        this.add(scroller2);
        
        mouseListener listener = new mouseListener();
        addMouseListener(listener);
        addMouseMotionListener(listener);

	}
	
	public int calculateScore(String expected, String returned){
		int score = 0;
		
		score = Math.abs(expected.length() - returned.length());
		if(expected.length() < returned.length()){
			for(int i = 0; i < expected.length(); i++){
				if(expected.charAt(i) == returned.charAt(i)){
					score = score - 5;
				}
				else{
					score = score + 5;
				}
			}
		}
		else{
			for(int i = 0; i < returned.length(); i++){
				if(expected.charAt(i) == returned.charAt(i)){
					score = score - 5;
				}
				else{
					score = score + 5;
				}
			}
		}
		if(score < 0){
			score = 0;
		}
		return score;
	}
	
    /*
	public CompBrain improveBrain(CompBrain brain, String[] inputArray, String inputString, String expectedOutput, int originalScore){
		
		if(switchType == 0){
			for(int i = 0; i < inNum; i++){
				
				for(int u = 0; u < brain.getInputNeurons(i).getConnectionCount(); u++){
						System.out.println("0Input: " + i);
						String orgWeight = brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u));
						double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) + 3;
						if(newWeight > 16){
							newWeight = 15.99;						
						}
						brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
						brain.calculateWeights(inputArray);
						String output = brain.getBrain().calculateWeights(inputArray);
						int score = calculateScore(expectedOutput, output);
						if(score > originalScore){
							inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] = 1;
							double diff = score - originalScore;
							brain.setInputBenefit(i, brain.getInputNeurons(i).getBenefit() + diff);
						}
						else{
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), orgWeight);
							double newWeightLower = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) - 3;
							if(newWeightLower < -16){
								newWeightLower = 15.99;						
							}
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeightLower));
							brain.calculateWeights(inputArray);
							String output2 = brain.getBrain().calculateWeights(inputArray);
							score = calculateScore(expectedOutput, output);
							if(score > originalScore){
								inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] = 2;
								double diff = score - originalScore;
								brain.setInputBenefit(i, brain.getInputNeurons(i).getBenefit() + diff);
							}
							else{
								inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] = 0;
								brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), orgWeight);
							}
						
						}
				}
			}
			
			for(int i = 0; i < rNum * cNum; i++){
				
				for(int u = 0; u < brain.getNeuron(i).getConnectionCount(); u++){
					String orgWeight = brain.getWeights(i, brain.getNeuron(i).getConnections(u));
					System.out.println("0Neuron: " + i);
						double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) + 3;
						if(newWeight > 16){
							newWeight = -15.99;						
						}
						brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
						brain.calculateWeights(inputArray);
						String output = brain.getBrain().calculateWeights(inputArray);
						int score = calculateScore(expectedOutput, output);
						if(score > originalScore){
							weightTypes[i][brain.getNeuron(i).getConnections(u)] = 1;
							double diff = score - originalScore;
							brain.setBenefit(i, brain.getNeuron(i).getBenefit() + diff);
						}
						else{
							brain.setWeights(i, brain.getNeuron(i).getConnections(u),orgWeight);
							double newWeightLower = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) - 3;
							if(newWeightLower < -16){
								newWeightLower = -15.99;						
							}
							brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeightLower));
							brain.calculateWeights(inputArray);
							String output2 = brain.getBrain().calculateWeights(inputArray);
							score = calculateScore(expectedOutput, output);
							if(score > originalScore){
								weightTypes[i][brain.getNeuron(i).getConnections(u)] = 2;
							}
							else{
								weightTypes[i][brain.getNeuron(i).getConnections(u)] = 0;
								brain.setWeights(i, brain.getNeuron(i).getConnections(u), orgWeight);
								double diff = score - originalScore;
								brain.setBenefit(i, brain.getNeuron(i).getBenefit() + diff);
							}
						
						}
				}
			}
			
			switchType = 1;
			
		}
		else{
			for(int i = 0; i < inNum; i++){
				for(int u = 0; u < brain.getNeuron(i).getConnectionCount(); u++){
					
					if(inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] == 1){
						double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) + 1;
						if(newWeight > 16){
							newWeight = 15.99;						
						}
						brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else if(inputWeightTypes[i][brain.getNeuron(i).getConnections(u)] == 2){
						double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) - 1;
						if(newWeight < 16){
							newWeight = -15.99;						
						}
						brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else{
						double random = Math.random();
						if(random > .5){
							double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) - 1;
							if(newWeight < 16){
								newWeight = -15.99;						
							}
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
						}
						else{
							double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) + 1;
							if(newWeight > 16){
								newWeight = 15.99;						
							}
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
						}
					}
				}
			}
			
			for(int i = 0; i < rNum * cNum; i++){
				for(int u = 0; u < brain.getNeuron(i).getConnectionCount(); u++){
					if(weightTypes[i][brain.getNeuron(i).getConnections(u)] == 1){
						double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) + 1;
						if(newWeight > 16){
							newWeight = 15.99;						
						}
						brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else if(weightTypes[i][brain.getNeuron(i).getConnections(u)] == 2){
						double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) - 1;
						if(newWeight < 16){
							newWeight = -15.99;						
						}
						brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else{
						double random = Math.random();
						if(random > .5){
							double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) - 1;
							if(newWeight < 16){
								newWeight = -15.99;						
							}
							brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
						}
						else{
							double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) + 1;
							if(newWeight > 16){
								newWeight = 15.99;						
							}
							brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
						}
					}
				}
			}
			
			brain.calculateWeights(inputArray);
			String output = brain.getBrain().calculateWeights(inputArray);
			int score = calculateScore(expectedOutput, output);
			if(score < originalScore){
				switchType = 0;
			}
			
		}
		double total = 0;
		for(int i = 0; i < inNum; i++){
			total += brain.getInputNeurons(i).getBenefit();
		}
		
		for(int i = 0; i < rNum * cNum; i++){
			total += brain.getNeuron(i).getBenefit();
		}
		double totalPercent = 0;
		for(int i = 0; i < inNum; i++){
			brain.setInputPercent(i, brain.getInputNeurons(i).getBenefit() / total);
			totalPercent = totalPercent + brain.getInputNeurons(i).getPercent();
			brain.setInputPercent(i, totalPercent);
		}
		for(int i = 0; i < rNum * cNum; i++){
			brain.setNeuronPercent(i, brain.getNeuron(i).getBenefit() / total);
			totalPercent = totalPercent + brain.getNeuron(i).getPercent();
			brain.setNeuronPercent(i, totalPercent);
		}
		
		double avg = total / (rNum * cNum + inNum);
		
		for(int i = 0; i < 2; i++){			
			double random = Math.random();
			for(int u = 0; u < inNum + rNum * cNum; u++){
				if(u < inNum){
					if(random < brain.getInputNeurons(u).getPercent()){
						for(int y = 0; y < brain.getInputNeurons(u).getConnectionCount(); y++){
							double newNeuron = Math.random() * (rNum * cNum);
							newNeuron = Math.round(newNeuron);
							brain.setInputNeuronConnections(y, (int)newNeuron);
							brain.setInputWeights(u, (int)newNeuron, Brain.toBinary(Math.random() * 16));
						}
						break;
					}
					
				}
				else{
					if(random < brain.getNeuron(u).getPercent()){
						for(int y = 0; y < brain.getNeuron(u).getConnectionCount(); y++){
							double newNeuron = Math.random() * (rNum * cNum + rNum * cNum + inNum + outNum + 2);
							newNeuron = Math.round(newNeuron);
							brain.setNeuronConnections(y, (int)newNeuron);
							brain.setWeights(u, (int)newNeuron, Brain.toBinary(Math.random() * 16));
						}
						break;
					}
				}
			}
		}
		
		return brain;
	}
    
    */
    
	public CompBrain breedBrains(CompBrain brain1, CompBrain brain2){
		
		String[][] emptyWeights = new String[rNum * cNum][rNum * cNum + outNum + 2];
		Brain firstBrain = new Brain(rNum, cNum, false, emptyWeights, 10, outNum, inNum);
		for(int i = 0; i < rNum * cNum; i++){
			firstBrain.setNeuronDelay(i, brain1.getBrain().getNeuron(i).getDelay());
		}
		
		CompBrain newBrain = new CompBrain(rNum, cNum, rNum, cNum, outNum, inNum, false, emptyWeights, inNum, firstBrain);
        int connectionCount = 0;
        
        for(int i = 0; i < inNum; i++){
        	int topC = 0;
        	if(brain1.getInputNeurons(i).getConnectionCount() > brain2.getInputNeurons(i).getConnectionCount()){
        		topC = brain1.getInputNeurons(i).getConnectionCount();
        	}
        	else{
        		topC = brain2.getInputNeurons(i).getConnectionCount();
        	}
            for(int u = 0; u < topC; u++){
            	double random = Math.random();
            	if(u < brain1.getInputNeurons(i).getConnectionCount() && u < brain2.getInputNeurons(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getInputNeurons(i).setConnections(brain1.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain1.getInputNeurons(i).getConnections(u), brain1.getInputWeights(i, brain1.getInputNeurons(i).getConnections(u)));
            		}
            		else{
            			newBrain.getInputNeurons(i).setConnections(brain2.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain2.getInputNeurons(i).getConnections(u), brain2.getInputWeights(i, brain2.getInputNeurons(i).getConnections(u)));
            		}
            	}
            	else if(u < brain1.getInputNeurons(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getInputNeurons(i).setConnections(brain1.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain1.getInputNeurons(i).getConnections(u), brain1.getInputWeights(i, brain1.getInputNeurons(i).getConnections(u)));
            		}
            	}
            	else{
            		if(random > .5){
            			newBrain.getInputNeurons(i).setConnections(brain2.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain2.getInputNeurons(i).getConnections(u), brain2.getInputWeights(i, brain2.getInputNeurons(i).getConnections(u)));
            		}
            	}
            }
        }
        
        for(int i = 0; i < rNum * cNum; i++){
        	int topC = 0;
        	if(brain1.getNeuron(i).getConnectionCount() > brain2.getNeuron(i).getConnectionCount()){
        		topC = brain1.getNeuron(i).getConnectionCount();
        	}
        	else{
        		topC = brain2.getNeuron(i).getConnectionCount();
        	}
            for(int u = 0; u < topC; u++){
            	double random = Math.random();
            	if(u < brain1.getNeuron(i).getConnectionCount() && u < brain2.getNeuron(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getNeuron(i).setConnections(brain1.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain1.getNeuron(i).getConnections(u), brain1.getWeights(i, brain1.getNeuron(i).getConnections(u)));
            		}
            		else{
            			newBrain.getNeuron(i).setConnections(brain2.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain2.getNeuron(i).getConnections(u), brain2.getWeights(i, brain2.getNeuron(i).getConnections(u)));
            		}
            	}
            	else if(u < brain1.getNeuron(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getNeuron(i).setConnections(brain1.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain1.getNeuron(i).getConnections(u), brain1.getWeights(i, brain1.getNeuron(i).getConnections(u)));
            		}
            	}
            	else{
            		if(random > .5){
            			newBrain.getNeuron(i).setConnections(brain2.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain2.getNeuron(i).getConnections(u), brain2.getWeights(i, brain2.getNeuron(i).getConnections(u)));
            		}
            	}
            }
        }
        
        for(int i = 0; i < rNum * cNum + rNum * cNum + inNum + outNum + 2; i++){
        	double random = Math.random();
        	if(random < .5){
        		newBrain.setNeuronDelay(i, brain1.getNeuron(i).getDelay());
        	}
        	else{
        		newBrain.setNeuronDelay(i, brain2.getNeuron(i).getDelay());
        	}
        	
        }
        
        System.out.println("ConnectionCount: " + connectionCount);
        return newBrain;
        
	}
    
	public void createNextGen(){
        
        CompBrain[] topBrains = new CompBrain[brainNum];
        /*
        for(int i = 0; i < brainNum; i++){
            for(int u = 0; u < brainNum; u++){
                
                if(i == 0){
                    topBrains[i] = brains[i];
                    break;
                }
                
                if(topBrains[Math.abs(u - brainNum) - 1] != null){
                	if(brains[i].getScore() < topBrains[Math.abs(u - brainNum) - 1].getScore()){
                    	int newPlace = Math.abs(u - brainNum);
                    	System.out.println("Array shifted");
                        topBrains = (CompBrain[]) shiftArray(newPlace, topBrains).clone();
                        topBrains[Math.abs(u - brainNum)] = brains[i];
                        break;
                    }
                    else{
                    	if(u == brainNum - 1){
                    		topBrains = (CompBrain[]) shiftArray(0, topBrains).clone();
                    		topBrains[0] = brains[i];
                        }
                    }
                }
            }
        }
        */
        
		double totalScore = 0;
		int maxScore = 0;
		for(int i = 0; i < brainNum; i++){
			if(brains[i].getScore() > maxScore){
				maxScore = brains[i].getScore();
			}
			System.out.println("Brain" + i + " score");
		}
		
		for(int i = 0; i < brainNum; i++){
			brains[i].setScore(maxScore - brains[i].getScore());
			totalScore += brains[i].getScore();
			System.out.println("Brain" + i + " percent calculated");
		}
		
		System.out.println(totalScore);
		for(int i = 0; i < brainNum; i++){
			brains[i].setPercent((brains[i].getScore() / totalScore) * 100);
			System.out.println("Brain" + i + " more percent calculated");
		}
        /*
        int lowestNum = topBrains[brainNum - 1].getScore();
        for(int i = 0; i < brainNum; i++){
            topBrains[i].setAddedScore(Math.abs(lowestNum));
        }
         */
		int comScore = 0;

		for(int i = 0; i < brainNum; i++){    		
			comScore += brains[i].getPercent();
			brains[i].setPercent(brains[i].getPercent() + comScore);
			System.out.println("Brain" + i + " even more percent calculated");
			//System.out.println(brains[i].getPercent());
		}
		
		boolean done = false;
		boolean done1 = false;
		CompBrain chosenBrain1 = null;
		CompBrain chosenBrain2 = null;

		CompBrain[] newBrainList = new CompBrain[brainNum];
		String[] newFileLoc = new String[brainNum];
        /*
        for(int i = 0; i < keepBrainNum; i++){
        
            newBrainList[i] = topBrains[i];
            System.out.println((i + 1) + ": " + topBrains[i].getScore());
        
        }
		*/
		for(int z = 0/*keepBrainNum*/; z < brainNum; z++){
			int addNum = 0;
			if(genNum % 2 == 1){
				addNum = brainNum;
			}
			done1 = false;
			done = false;
			while(done1 == false){
				double random = Math.random() * 100;
				for(int i = 0; i < brainNum; i++){
					if(i == 0){
						if(brains[i].getPercent() > random){
							chosenBrain1 = openBrain(brainFileLoc[i], i + addNum);
							System.out.println("Brain 1: " + i);
							System.out.println("Score: " + chosenBrain1.getScore());
							done1 = true;
							break;
						}
					} 	
					else if(brains[i].getPercent() >= random && brains[i - 1].getPercent() < random){						
						chosenBrain1 = openBrain(brainFileLoc[i], i + addNum);
						System.out.println("Brain 1: " + i);
						System.out.println("Score: " + chosenBrain1.getScore());
						done1 = true;
						break;
					}
					
				}
			}
			while(done == false){
				double random1 = Math.random() * 100;
				for(int i = 0; i < brainNum; i++){
					if(i == 0){
						if(brains[i].getPercent() > random1){
							if(chosenBrain1.equals(brains[i])){

							}
							else{
								chosenBrain2 = openBrain(brainFileLoc[i], i + addNum);
								System.out.println("Brain 2: " + i);
								System.out.println("Score: " + chosenBrain2.getScore());
								done = true;
								break;
							}
						}
					}
					else if(brains[i].getPercent() >= random1 && brains[i - 1].getPercent() < random1){
						if(chosenBrain1.equals(brains[i])){

						}
						else{
							chosenBrain2 = openBrain(brainFileLoc[i], i + addNum);
							System.out.println("Brain 2: " + i);
							System.out.println("Score: " + chosenBrain2.getScore());
							done = true;
							break;
						}
					}

				}

			}
			int addNum2 = 0;
			if(addNum == 0){
				addNum2 = brainNum;
			}
			newFileLoc[z] = "C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + (z + addNum2) + ".dat";
			saveBrain(breedBrains(chosenBrain1, chosenBrain2), z + addNum2);
			chosenBrain1 = null;
			chosenBrain2 = null;

		}

		for(int i = 0; i < brainNum; i++){
			brainFileLoc[i] = newFileLoc[i];
		}

	}

}


class Brain implements java.io.Serializable{

	public int radius;

	double percent = 0;

	String symbols = "abcdefghijklmnopqrstuvwxyz;:',!?.()\"123456789 ";
    
    private int totalTime;
	private int[] outputTime;
	private int outputTimeCount = 0;
    private int maxConnectionNum = 7;
    private int maxDelay = 20;
	private int divFunction = 8;
	private int divNeuron = 8;
	private int divPower = 8;
    private int divRotation = 2;
    
    Neuron[] activatedNeurons;
    int activatedCount = 0;

	private String[][] weights;
    private String[] connections1;
    private String[] connections2;
    private String[][] inputWeights;
    private String[] inputs1;
    private String[] inputs2;
	private Neuron[] neurons;
	private String[] neuronFunction;
	private String[] neuronPower;
	private Neuron[] inputs;
    
    private String[] inputString;

	double dx = Math.random() * 638 + 2;
	double dy = Math.random() * 478 + 2;

	int score = 0;

	int divideNum = 1;
	int speedReduce = 1;

	int foodCount;
	int rowNum;
	int colunmNum;

	double moveOut, rotationLeftOut, rotationRightOut;
	double[] outPuts;

	int outNum;
    int connectionNum;
    int inputConnectionNum;

	int x, y;
	double rotation = 0;

	public Brain(int rows, int columnNumber, boolean first, String[][] weight, int bRadius, int outputNum, int inputNum){
        
        inputs = new Neuron[inputNum];
		weights = new String[columnNumber * rows][columnNumber * rows + outputNum + 2];
        inputWeights = new String[inputNum][columnNumber * rows + outputNum + 2];
		outNum = outputNum;
		radius = bRadius;
		System.arraycopy(weight, 0, weights, 0, weight.length);
		rowNum = rows;
		colunmNum = columnNumber;
		neurons = new Neuron[rowNum * colunmNum + outputNum + 2];
		neuronFunction = new String[neurons.length + ReccurentNeuralNet.outNum];
		neuronPower = new String[neuronFunction.length];
		outPuts = new double[outNum];
		
		activatedNeurons = new Neuron[colunmNum * rowNum];
        activatedCount = 0;
        outputTime = new int[1000];

		if(first == true){
			generateWeights();
		}
        else{
            for(int i = 0; i < rowNum * colunmNum; i++){
                neurons[i] = new Neuron(i, maxConnectionNum);
                neurons[i].setDelay(Math.round((float)(5 + Math.random() * maxDelay)));
            }
            for(int i = 0; i < outNum + 2; i++){
                neurons[i + rowNum * colunmNum] = new Neuron(i, maxConnectionNum);
            }
            System.out.println(neurons.length);
            for(int i = 0; i < inputs.length; i++){
                inputs[i] = new Neuron(i, maxConnectionNum);
            }
        }

	}
    
    private void setInputs(String[] inputStringArray){
        inputString = (String[]) inputStringArray.clone();
    }
    
    public Neuron getInputNeurons(int neuronNum){
		return inputs[neuronNum];
	}
    
	private void generateWeights(){
		
		connectionNum = 1000 + Math.round((float)(Math.random() * (maxConnectionNum * colunmNum * rowNum) / 1.5));
		inputConnectionNum = 5 + Math.round((float)(Math.random() * (inputs.length * (maxConnectionNum - 5))));
		int usedConnections = 0;
		
		for(int i = 0; i < rowNum * colunmNum; i++){
			neurons[i] = new Neuron(i, maxConnectionNum);
            neurons[i].setDelay(Math.round((float)(5 + Math.random() * maxDelay)));
		}
		for(int i = 0; i < outNum + 2; i++){
            neurons[i + rowNum * colunmNum] = new Neuron(i, 0);
        }
        //System.out.println(neurons.length);
		for(int i = 0; i < inputs.length; i++){
            inputs[i] = new Neuron(i, maxConnectionNum);
		}
        
        for(int i = 0; i < inputConnectionNum; i++){
            
            boolean goOn = false;
            while(goOn == false){
                int inputNeuron = Math.round((float)(Math.random() * (inputs.length - 1)));
                int neuron = Math.round((float)(Math.random() * (colunmNum * rowNum - 1)));
                
                double random = (double)(Math.random() * 16);
                double negativeRan = Math.random();
                if(negativeRan < 0.5){
                    random = random * -1;
                }
                
                if(inputs[inputNeuron].getConnectionCount() < maxConnectionNum){
                
                    inputWeights[inputNeuron][neuron] = toBinary(random);
                    inputs[inputNeuron].setConnections(neuron);
                    neurons[neuron].addInput(-inputNeuron);
                    goOn = true;
                    
                }
            }
        }
		
		for(int i = 0; i < rowNum; i++){
			for(int u = 0; u < connectionNum; u++){
				
                boolean goOn = false;
                while(goOn == false){
                    int neuron1 = Math.round((float)(Math.random() * (rowNum * colunmNum - 1)));
                    int neuron2 = Math.round((float)(Math.random() * (rowNum * colunmNum + this.outNum - 1 + 2)));

                    double random = (double)(Math.random() * 16);
                    double negativeRan = Math.random();
                    if(negativeRan < 0.5){
                        random = random * -1;
                    }
                    
				    if(weights[neuron1][neuron2] == null && neurons[neuron1].getConnectionCount() < maxConnectionNum){
					   weights[neuron1][neuron2] = toBinary(random);
					   neurons[neuron1].setConnections(neuron2);
					   neurons[neuron2].addInput(neuron1);
                       goOn = true;
				    }
                }
			}
		}
		
		for(int i = 0; i < rowNum * colunmNum; i++){
			//neurons[i].shrinkArray();
		}

		for(int i = 0; i < neuronFunction.length; i++){

			double random = (double)(Math.random() * 16);
			double negativeRan = Math.random();
			if(negativeRan < 0.5){
				random = random * -1;
			}
			neuronFunction[i] = toBinary(random);

		}

		for(int i = 0; i < neuronFunction.length; i++){

			double random = Math.random() * 16;
			neuronPower[i] = toBinary(random);

		}

	}

	public static String toBinary(double num){

		double dNum = Math.abs(num);
		String sNum = "" + dNum;
		String bNum = "";
		char ch = sNum.charAt(1);
		int nu = Character.getNumericValue(ch);

		if(nu == -1){

			for(int i = 0; i < sNum.length(); i++){

				char c = sNum.charAt(i);
				int iNum = Character.getNumericValue(c);

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}

		}
		else{
			int iNum = 0;
			for(int i = 0; i < sNum.length() - 1; i++){

				if(i == 0){
					char c1 = sNum.charAt(0);
					char c2 = sNum.charAt(1);
					String twoNum = "" + c1 + c2;
					iNum = Integer.parseInt(twoNum);
				}

				char c = sNum.charAt(i + 1);    

				if(i != 0){
					iNum = Character.getNumericValue(c);
				}

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}
		}

		if(num < 0){
			bNum = "-" + bNum;
		}
		else{
			bNum = "+" + bNum;
		}
		return bNum;
	}


	public static double toDecimal(String bNum){

		int convertedNum = 0;
		double finalNum = 0;
		String numString = "";

		for(int u = 1; u < (bNum.length()) / 4; u++){
			char c;
			convertedNum = 0;
			for(int i = 0; i < 4; i++){

				if(u != 0){
					c = bNum.charAt(1 + i + u * 4);
				}
				else{
					c = bNum.charAt(i + u * 4);
				}

				int num = Character.getNumericValue(c);

				if(num == 1){
					convertedNum = convertedNum + Math.round((float)Math.pow(2, Math.abs(i)));
				}

			}
			if(u == 1){
				numString = numString + convertedNum + ".";
			}
			else{
				numString = numString + convertedNum;
			}
		}

		//System.out.println(numString);

		finalNum = Double.parseDouble(numString);
		char nChar = bNum.charAt(0);
		if(nChar == '-'){
			finalNum = finalNum * -1;
		}
		return finalNum;

	}

	public double getPercent(){
		return percent;
	}
	
	public Neuron getNeuron(int neuron1){
		return neurons[neuron1];
	}

	public void setPercent(double newPercent){
		this.percent = newPercent;
	}

	public int getScore(){
		return score;
	}

	public String getWeights(int first, int second){
		return weights[first][second];
	}
    
    public int getTotalTime(){
        return totalTime;
    }
    
	public void setWeights(int first, int second, String num){
		weights[first][second] = num;
	}
    
    public void setInputWeights(int first, int second, String num){
        inputWeights[first][second] = num;
    }
    
    public void setKeepValue(int neuronNum, int oNumber, double newValue, int time){
        //neurons[neuronNum].setValue(oNumber, newValue, time);
        neurons[neuronNum].setValue(newValue);
    }

	public String getNeuronFunction(int num){
		return neuronFunction[num];
	}

	public void setNeuronFunction(int num, String s){
		neuronFunction[num] = s;
	}
    
    public String getInputWeights(int first, int second){
        if(inputWeights[first][second] == null){
            return "null";
        }
        else{
            return inputWeights[first][second];
        }
    }

	public void setAddedScore(int newScore){     
		this.score += newScore;  
	}

	public void setFoodCount(int newFoodCount){      
		this.foodCount = newFoodCount; 
	}

	public String getPower(int num){
		return neuronPower[num];
	}

	public void setPower(int num, String set){
		neuronPower[num] = set;
	}
    public void setNeuronConnections(int neuronNum, int connectedNum, double value1, double value2){
        boolean connected = false;
        for(int i = 0; i < neurons[neuronNum].getConnectionCount(); i++){
            if(neurons[neuronNum].getConnections(i) == connectedNum){
                connected = true;
            }
        }
        if(connected == false){
            neurons[neuronNum].setConnections(connectedNum);
            neurons[connectedNum].addInput(neuronNum);
            //System.out.println("Connection set!");
        }
        weights[neuronNum][connectedNum] = toBinary((value1 + value2) / 2);
        
    }
    
    public void setInputConnections(int neuronNum, int connectedNum, double value1, double value2){
      boolean connected = false;
        for(int i = 0; i < inputs[neuronNum].getConnectionCount(); i++){
            if(inputs[neuronNum].getConnections(i) == connectedNum){
                connected = true;
            }
        }
        if(connected == false){
            inputs[neuronNum].setConnections(connectedNum);
            neurons[connectedNum].addInput(-neuronNum);
        }
        
        inputWeights[neuronNum][connectedNum] = toBinary((value1 + value2) / 2);
    }
    
    public void setNeuronDelay(int neuron1, int delay){
    	neurons[neuron1].setDelay(delay);
    }
    
	public String calculateWeights(String[] inputArray, String desiredOutput){

		String[] inputValues = new String[inputArray.length];
        
        for(int i = 0; i < inputArray.length; i++){
            inputValues[i] = inputArray[i];
        }

		for(int i = 0; i < outNum; i++){
			outPuts[i] = 0;
		}

		boolean stop = false;
		int time = 0;
        String answer = "";
		
        while(stop == false){
        	
        	Neuron[] newActivatedNeurons = new Neuron[colunmNum * rowNum];
        	if(time < inputValues.length){
                int inputNumber = 0;
				for(int i = 0; i < symbols.length(); i++){
					String test = "" + symbols.charAt(i);
					if(test.equalsIgnoreCase(inputValues[time])){
						inputNumber = i;
					}
				}
				
				for(int i = 0; i < inputs[inputNumber].getConnectionCount(); i++){
					double newValue = inputs[inputNumber].getValue() * toDecimal(inputWeights[inputNumber][inputs[inputNumber].getConnections(i)]);
					neurons[inputs[inputNumber].getConnections(i)].addValue(newValue);
					if(neurons[inputs[inputNumber].getConnections(i)].isActivated() == false){
						activatedNeurons[activatedCount] = neurons[inputs[inputNumber].getConnections(i)];
						activatedNeurons[activatedCount].setActivated(true);
						neurons[inputs[inputNumber].getConnections(i)].setActivated(true);
						//System.out.println("Neuron: " + activatedNeurons[activatedCount].getNum() + " " + time);
						activatedCount++;
					}
					
				}
				
        	}
        	
        	for(int i = 0; i < activatedCount; i++){
        		int num = i % 2;
                activatedNeurons = neuronActivated(activatedNeurons[i], activatedNeurons, i, num, time);
        		//System.out.println(activatedNeurons[i].getNum() + " " + i);
        	}
        	
        	Neuron[] activatedOutputs = new Neuron[outNum];
        	double maxValue = 0;
        	int maxNum = 0;
        	for(int i = 0; i < outNum + 2; i++){
        		if(i < outNum){
                    for(int u = 0; u < desiredOutput.length(); u++){
                        if(symbols.charAt(i) == desiredOutput.charAt(u)){
                            
                            neurons[i + colunmNum * rowNum].addTargetValue(10.0);
                        }
                    }
                }
                if(neurons[i + colunmNum * rowNum].isActivated() == true && neurons[i + colunmNum * rowNum].getValue() > maxValue){
        			if(i > outNum - 1){
                        stop = true;
                    }
                    else{
                        maxValue = neurons[i + colunmNum * rowNum].getValue();
                        maxNum = i;
                    	//answer = answer + symbols.charAt(i);
                        //System.out.println(answer);
                        if(answer.length() > 1000){
                            stop = true;
                        }
                    }
        		}
        	}
        	if(maxNum != 0){
        		answer = answer + symbols.charAt(maxNum);
        		outputTime[outputTimeCount] = time;
        		outputTimeCount++;
        	}
        	time++;
        	//System.out.println(time);
        }
        totalTime = time;
		return answer;
		

	}

	public Neuron[] neuronActivated(Neuron neuron, Neuron[] neuronArray, int activatedNum, int type, int time){
		int neuronPos = activatedNum;
		Neuron[] newNeuronArray = (Neuron[]) neuronArray.clone();
		//Tests if the neuron has anymore delay then releases a signal.
		if(neuron.getRemainingDelay() == 0 && neuron.isActivated() == true){
			//Gets the time the neuron sends an output signal.
			neurons[neuron.getNum()].addTime(time);
			for(int i = 0; i < neuron.getConnectionCount(); i++){
				double newValue = neuron.getValue() * toDecimal(weights[neuron.getNum()][neuron.getConnections(i)]);
				neurons[neuron.getConnections(i)].addValue(newValue);
				if(neurons[neuron.getConnections(i)].isActivated() == false && neurons[neuron.getConnections(i)].getNum() < colunmNum * rowNum){
					
					neurons[neuron.getConnections(i)].setActivated(true);
					newNeuronArray[activatedCount] = neurons[neuron.getConnections(i)];
					//System.out.println(neurons[neuron.getConnections(i)].getNum());
					activatedCount++;
					
				}
				if(neurons[neuron.getConnections(i)].getNum() > colunmNum * rowNum){
					neurons[neuron.getConnections(i)].setActivated(true);
					//System.out.println("Output!!");
				}
			}
			newNeuronArray[neuronPos].setActivated(false);
			newNeuronArray = shiftArray(neuronPos, newNeuronArray);
			activatedCount--;
		}
		else if(neuron.isActivated() == true){
			neuron.delayTick();
			newNeuronArray[activatedNum] = neuron;
			neurons[neuron.getNum()] = neuron;
		}
		return newNeuronArray;
	}
	
	public int[] shiftArray(int num, int[] brainArray){
	    
        int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public Neuron[] shiftArray(int num, Neuron[] brainArray){
	    
        Neuron[] tempBrain = new Neuron[brainArray.length];
        tempBrain = (Neuron[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public int[] shiftArrayBack(int num, int[] brainArray){
		int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
            if(i == num){
                brainArray[i] = 0;
            }
            else{
                brainArray[i] = tempBrain[i - 1];
            }
        }
        
        return brainArray;
	}
    
    public void calculateScore(String response, String answer){
        
        int rScore = 0;
        for(int i = 0; i < response.length(); i++){
            if(i < answer.length()){
                if(answer.charAt(i) == response.charAt(i)){
                    rScore++;
                }
                else{
                    rScore--;
                }
            }
            else{
                rScore--;
            }
        }
        
        if(answer.length() > response.length()){
            rScore = rScore - (answer.length() - response.length());
        }
        
        this.score = rScore;
    }
    
    public void createWeights(int n1, int n2, double weight){
        weights[n1][n2] = toBinary(weight);
    }
	
}

class CompBrain implements java.io.Serializable{

	public int radius;

	double percent = 0;

	String symbols = "abcdefghijklmnopqrstuvwxyz;:',!?.()\"123456789 ";
	
	private int[] outputTime;
	private int outputTimeCount = 0;
    private int maxConnectionNum = 10;
    private int maxDelay = 20;
	private int divFunction = 8;
	private int divNeuron = 8;
	private int divPower = 8;
    private int divRotation = 2;
    
    int neuronChange1Count = 0;
    int neuronChange2Count = 0;
    
    Neuron[] activatedNeurons;
    int activatedCount = 0;

    int timeNum;
    
    boolean goOn;
    
	private String[][] weights;
    private String[] connections1;
    private String[] connections2;
    private String[][] inputWeights;
	private Neuron[] neurons;
	private String[] neuronFunction;
	private String[] neuronPower;
	private Neuron[] inputs;
    private Neuron[] neuronChange1;
    private Neuron[] neuronChange2;
    
    private Brain createdBrain;
    private String[] inputString;

	double dx = Math.random() * 638 + 2;
	double dy = Math.random() * 478 + 2;

	int score = 0;

	int divideNum = 1;
	int speedReduce = 1;

	int foodCount;
	int rowNum;
	int colunmNum;
	boolean outputActivated;

	double moveOut, rotationLeftOut, rotationRightOut;
	double[] outPuts;

	int outCNum;
    int outRNum;
    int outONum;
    int outINum;
    int connectionNum;
    int inputConnectionNum;
    int connectionsMade = 0;
    
	int x, y;
	double rotation = 0;

	public CompBrain(int rows, int columnNumber, int outRowNum, int outColNum, int outOutNum, int outInputNum,  boolean first, String[][] weight, int inputNum, Brain brain){
        
        createdBrain = brain;
        outCNum = outColNum;
        outRNum = outRowNum;
        outONum = outOutNum + 2;
        outINum = outInputNum;
		
        rowNum = rows;
		colunmNum = columnNumber;
		neurons = new Neuron[rowNum * colunmNum + outCNum * outRNum + outINum + outONum];
        weights = new String[rowNum * colunmNum + outCNum * outRNum + outINum + outONum][rowNum * colunmNum + outCNum * outRNum + outINum + outONum];
        
        inputWeights = new String[inputNum][columnNumber * rows];
        inputs = new Neuron[inputNum];
        
        neuronChange1 = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
        neuronChange2 = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
		
		activatedNeurons = new Neuron[colunmNum * rowNum];
        activatedCount = 0;
        
        for(int i = 0; i < rowNum * colunmNum + outCNum * outRNum + outINum + outONum; i++){
			neurons[i] = new Neuron(i, maxConnectionNum);
		}
        
		for(int i = 0; i < inputs.length; i++){
            inputs[i] = new Neuron(i, maxConnectionNum);
		}
        
		if(first == true){
			for(int i = 0; i < rowNum * colunmNum + outCNum * outRNum + outINum + outONum; i++){
				neurons[i].setDelay(Math.round((float)(5 + Math.random() * maxDelay)));
			}
			generateWeights();
		}		
	}
    
    private void setInputs(String[] inputStringArray){
        inputString = (String[]) inputStringArray.clone();
    }
    
	private void generateWeights(){
		
		connectionNum = 4000;//1000 + Math.round((float)(Math.random() * (maxConnectionNum * colunmNum * rowNum) / 1.5));
		inputConnectionNum = 400;//150 + Math.round((float)(Math.random() * (inputs.length * (maxConnectionNum - 5))));
		int usedConnections = 0;
        
        for(int i = 0; i < inputConnectionNum; i++){
            
            boolean goOn = false;
            while(goOn == false){
                int inputNeuron = Math.round((float)(Math.random() * (inputs.length - 1)));
                int neuron = Math.round((float)(Math.random() * (colunmNum * rowNum - 1)));
                
                double random = (double)(Math.random() * 16);
                double negativeRan = Math.random();
                if(negativeRan < 0.5){
                    random = random * -1;
                }
                
                if(inputs[inputNeuron].getConnectionCount() < maxConnectionNum){
                
                    inputWeights[inputNeuron][neuron] = toBinary(random);
                    inputs[inputNeuron].setConnections(neuron);
                    neurons[neuron].addInput(-inputNeuron);
                    goOn = true;
                    
                }
            }
        }
		
		for(int i = 0; i < rowNum; i++){
			for(int u = 0; u < connectionNum; u++){
				
                boolean goOn = false;
                while(goOn == false){
                    int neuron1 = Math.round((float)(Math.random() * (rowNum * colunmNum - 1)));
                    int neuron2 = Math.round((float)(Math.random() * (rowNum * colunmNum + outONum + outINum + outCNum * outRNum - 1)));

                    double random = (double)(Math.random() * 16);
                    double negativeRan = Math.random();
                    if(negativeRan < 0.5){
                        random = random * -1;
                    }
                    
				    if(weights[neuron1][neuron2] == null && neurons[neuron1].getConnectionCount() < maxConnectionNum){
					   weights[neuron1][neuron2] = toBinary(random);
					   neurons[neuron1].setConnections(neuron2);
					   neurons[neuron2].addInput(neuron1);
				
                       goOn = true;
				    }
                }
			}
		}
		
		for(int i = 0; i < rowNum * colunmNum; i++){
			//neurons[i].shrinkArray();
		}
	
	}

	public static String toBinary(double num){

		double dNum = Math.abs(num);
		String sNum = "" + dNum;
		String bNum = "";
		char ch = sNum.charAt(1);
		int nu = Character.getNumericValue(ch);

		if(nu == -1){

			for(int i = 0; i < sNum.length(); i++){

				char c = sNum.charAt(i);
				int iNum = Character.getNumericValue(c);

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}

		}
		else{
			int iNum = 0;
			for(int i = 0; i < sNum.length() - 1; i++){

				if(i == 0){
					char c1 = sNum.charAt(0);
					char c2 = sNum.charAt(1);
					String twoNum = "" + c1 + c2;
					iNum = Integer.parseInt(twoNum);
				}

				char c = sNum.charAt(i + 1);    

				if(i != 0){
					iNum = Character.getNumericValue(c);
				}

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}
		}

		if(num < 0){
			bNum = "-" + bNum;
		}
		else{
			bNum = "+" + bNum;
		}
		return bNum;
	}


	public static double toDecimal(String bNum){

		int convertedNum = 0;
		double finalNum = 0;
		String numString = "";

		for(int u = 1; u < (bNum.length()) / 4; u++){
			char c;
			convertedNum = 0;
			for(int i = 0; i < 4; i++){

				if(u != 0){
					c = bNum.charAt(1 + i + u * 4);
				}
				else{
					c = bNum.charAt(i + u * 4);
				}

				int num = Character.getNumericValue(c);

				if(num == 1){
					convertedNum = convertedNum + Math.round((float)Math.pow(2, Math.abs(i)));
				}

			}
			if(u == 1){
				numString = numString + convertedNum + ".";
			}
			else{
				numString = numString + convertedNum;
			}
		}

		//System.out.println(numString);

		finalNum = Double.parseDouble(numString);
		char nChar = bNum.charAt(0);
		if(nChar == '-'){
			finalNum = finalNum * -1;
		}
		return finalNum;

	}

	public double getPercent(){
		return percent;
	}

	public void setPercent(double newPercent){
		this.percent = newPercent;
	}

	public int getScore(){
		return score;
	}

	public String getWeights(int first, int second){
		if(weights[first][second] == null){
			return "null";
		}
		else{
			return weights[first][second];
		}
	}
	
	public Neuron getInputNeurons(int neuronNum){
		return inputs[neuronNum];
	}
	
	public Neuron getNeuron(int neuronNum){
		return neurons[neuronNum];
	}

	public void setWeights(int first, int second, String num){
		weights[first][second] = num;
	}
    
    public void setInputWeights(int first, int second, String num){
        inputWeights[first][second] = num;
    }

	public String getNeuronFunction(int num){
		return neuronFunction[num];
	}

	public void setNeuronFunction(int num, String s){
		neuronFunction[num] = s;
	}
    
    public String getInputWeights(int first, int second){
        if(inputWeights[first][second] == null){
            return "null";
        }
        else{
            return inputWeights[first][second];
        }
    }
    
    public Brain getBrain(){
        return createdBrain;
    }

	public void setAddedScore(int newScore){     
		this.score += newScore;  
	}

	public void setInputPercent(int neuronNum, double newPercent){
		inputs[neuronNum].setPercent(newPercent);
	}
	
	public void setNeuronPercent(int neuronNum, double newPercent){
		neurons[neuronNum].setPercent(newPercent);
	}
	
	public void setFoodCount(int newFoodCount){      
		this.foodCount = newFoodCount; 
	}
	
	public void setBenefit(int neuronNum, double newBenefit){
		neurons[neuronNum].setBenefit(newBenefit);
	}
	
	public void setInputBenefit(int neuronNum, double newBenefit){
		neurons[neuronNum].setBenefit(newBenefit);
	}
	
	public void setScore(int newScore){
		this.score = newScore;
	}
	public String getPower(int num){
		return neuronPower[num];
	}

	public void setPower(int num, String set){
		neuronPower[num] = set;
	}
	
	public void setNeuronConnections(int neuron1, int neuron2){
		neurons[neuron1].setConnections(neuron2);
	}
	
	public void setInputNeuronConnections(int neuron1, int neuron2){
		inputs[neuron1].setConnections(neuron2);
	}
	
	public void setNeuronDelay(int neuronNum, int delayNum){
		neurons[neuronNum].setDelay(delayNum);
	}
    
	public void calculateWeights(String[] inputArray){
		
		timeNum = 0;
		String[] inputValues = new String[inputArray.length];
        
        for(int i = 0; i < inputArray.length; i++){
            inputValues[i] = inputArray[i];
        }

		boolean stop = false;
		int time = 0;
        String answer = "";
		
        while(stop == false){
        	
        	Neuron[] newActivatedNeurons = new Neuron[colunmNum * rowNum];
        	if(time < inputValues.length){
                int inputNumber = 0;
				for(int i = 0; i < symbols.length(); i++){
					String test = "" + symbols.charAt(i);
					if(test.equalsIgnoreCase(inputValues[time])){
						inputNumber = i;
					}
				}
				
				for(int i = 0; i < inputs[inputNumber].getConnectionCount(); i++){
					double newValue = inputs[inputNumber].getValue() * toDecimal(inputWeights[inputNumber][inputs[inputNumber].getConnections(i)]);
					neurons[inputs[inputNumber].getConnections(i)].addValue(newValue);
					if(neurons[inputs[inputNumber].getConnections(i)].isActivated() == false){
						activatedNeurons[activatedCount] = neurons[inputs[inputNumber].getConnections(i)];
						activatedNeurons[activatedCount].setActivated(true);
						neurons[inputs[inputNumber].getConnections(i)].setActivated(true);
						//System.out.println("Neuron: " + activatedNeurons[activatedCount].getNum() + " " + time);
						activatedCount++;
					}
					
				}
				
        	}
        	
        	for(int i = 0; i < activatedCount; i++){
                activatedNeurons = neuronActivated(activatedNeurons[i], activatedNeurons, i, i, time);
        		//System.out.println(activatedNeurons[i].getNum() + " " + i);
        	}
        	
        	//Neuron[] activatedOutputs = new Neuron[outNum];

        	time++;
        	//System.out.println(time);
            if(time == 1000){
                stop = true;
            }
        }
        
	}

	public Neuron[] neuronActivated(Neuron neuron, Neuron[] neuronArray, int activatedNum, int time, int totalTime){
		int neuronPos = activatedNum;
		
		if(time == 0){
			outputActivated = false;
			goOn = false;
		}
		Neuron[] newNeuronArray = (Neuron[]) neuronArray.clone();
		//Tests if the neuron has any delay left, and if it doesn't, it releases a signal.
		if(neuron.getRemainingDelay() == 0 && neuron.isActivated() == true){
			//Records the time the neuron sent an output signal.
			neurons[neuron.getNum()].addTime(time);
			for(int i = 0; i < neuron.getConnectionCount() - 1; i++){

            double newValue = neuron.getValue() * toDecimal(weights[neuron.getNum()][neuron.getConnections(i)]);
				neurons[neuron.getConnections(i)].addValue(newValue);
				if(neurons[neuron.getConnections(i)].isActivated() == false && neurons[neuron.getConnections(i)].getNum() < colunmNum * rowNum){
					
					neurons[neuron.getConnections(i)].setActivated(true);
					newNeuronArray[activatedCount] = neurons[neuron.getConnections(i)];
					//System.out.println(neurons[neuron.getConnections(i)].getNum());
					activatedCount++;
					//System.out.println("Activated: " + activatedCount);
					
				}
				
				if(neurons[neuron.getConnections(i)].getNum() > colunmNum * rowNum && neurons[neuron.getConnections(i)].isActivated() == false){
					//System.out.println("Output Activated " + timeNum + " " + totalTime + " " + neuronChange1Count + " " + neuronChange2Count);
					//This sets a neuron in the first array that needs to be changed.
					if(neuronChange1[neuronChange1Count] == null && timeNum == 0 && neurons[neuron.getConnections(i)].isActivated() == false){
                        neuronChange1[neuronChange1Count] = neurons[neuron.getConnections(i)];
                        neurons[neuron.getConnections(i)].setActivated(true);
                        neuronChange1Count++;
                        //System.out.println("Output1! " + connectionsMade);
                        //System.out.println(neuron.getConnections(i));
                    }
					//This sets a neuron in the second array that needs to be changed. These will be ranked later to see how they line up.
                    else if(neuronChange1[neuronChange2Count] != null && timeNum == 1 && neurons[neuron.getConnections(i)].isActivated() == false){
                        neuronChange2[neuronChange2Count] = neurons[neuron.getConnections(i)];
                        neurons[neuron.getConnections(i)].setActivated(true);
                        neuronChange2Count++;
                        connectionsMade++;
                        //System.out.println(neuron.getConnections(i));
                        //System.out.println("Output2! " + connectionsMade);
                    }
                    else if(timeNum == 1 && neurons[neuron.getConnections(i)].isActivated() == false){
                        neuronChange1[neuronChange2Count] = neurons[neuron.getConnections(i)];
                        neurons[neuron.getConnections(i)].setActivated(true);
                        neuronChange2Count++;
                    }
					
					if(neuronChange1Count == neuronChange2Count){
                    	goOn = true;
                    	
                    }
                    outputActivated = true;
				}
			}
			newNeuronArray[neuronPos].setActivated(false);
			newNeuronArray = shiftArray(neuronPos, newNeuronArray);
			activatedCount--;
		}
		else if(neuron.isActivated() == true){
			neuron.delayTick();
			newNeuronArray[activatedNum] = neuron;
			neurons[neuron.getNum()] = neuron;
		}
        
        if(goOn == true){
            //Rank neurons from highest to lowest to determine what happens first
            Neuron[] topNeurons = new Neuron[neuronChange2Count];
            for(int i = 0; i < neuronChange2Count; i++){
                for(int u = 0; u < neuronChange2Count; u++){
                
                    if(i == 0){
                        topNeurons[i] = neuronChange1[i];
                        break;
                    }
                
                    if(topNeurons[Math.abs(u - neuronChange2Count) - 1] != null){
                	   if(neuronChange1[i].getValue() < topNeurons[Math.abs(u - neuronChange2Count) - 1].getValue()){
                           int newPlace = Math.abs(u - neuronChange2Count);
                           topNeurons = (Neuron[]) shiftArray(newPlace, topNeurons).clone();
                           topNeurons[Math.abs(u - neuronChange2Count)] = neuronChange1[i];
                           break;
                        }
                        else{
                    	   if(u == neuronChange2Count - 1){
                               topNeurons = (Neuron[]) shiftArray(0, topNeurons).clone();
                               topNeurons[0] = neuronChange1[i];
                            }
                        }
                    }
                }
            }
            
            Neuron[] topNeurons2 = new Neuron[neuronChange2Count];
            for(int i = 0; i < neuronChange2Count; i++){
                for(int u = 0; u < neuronChange2Count; u++){
                
                    if(i == 0){
                        topNeurons2[i] = neuronChange2[i];
                        break;
                    }
                
                    if(topNeurons[Math.abs(u - neuronChange2Count) - 1] != null){
                	   if(neuronChange1[i].getValue() < topNeurons2[Math.abs(u - neuronChange2Count) - 1].getValue()){
                           int newPlace = Math.abs(u - neuronChange2Count);
                           topNeurons2 = (Neuron[]) shiftArray(newPlace, topNeurons2).clone();
                           topNeurons2[Math.abs(u - neuronChange2Count)] = neuronChange2[i];
                           break;
                        }
                        else{
                    	   if(u == neuronChange2Count - 1){
                               topNeurons2 = (Neuron[]) shiftArray(0, topNeurons).clone();
                               topNeurons2[0] = neuronChange2[i];
                            }
                        }
                    }
                }
            }
            //Actually sets the connections in the other brain
            int tot = rowNum * colunmNum;
            for(int i = 0; i < neuronChange1Count; i++){
                if(neuronChange1[i].getNum() - tot < outINum && neuronChange2[i].getNum() - tot > outINum){
                  createdBrain.setInputConnections(neuronChange1[i].getNum() - tot, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                }
                else if(neuronChange2[i].getNum() - tot < outINum && neuronChange1[i].getNum() - tot > outINum){
                  createdBrain.setInputConnections(neuronChange2[i].getNum() - tot, neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getValue(), neuronChange1[i].getValue());
                }
                else if(neuronChange1[i].getNum() - tot > outRNum * outCNum && neuronChange2[i].getNum() - tot < outRNum * outCNum){
                  if(neuronChange2[i].getNum() - tot - outINum < 0){
                     createdBrain.setNeuronConnections(neuronChange2[i].getNum() - tot, neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getValue(), neuronChange1[i].getValue());
                  }
                  else{
                     createdBrain.setNeuronConnections(neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getValue(), neuronChange1[i].getValue());
                  }
                }
                else if(neuronChange2[i].getNum() - tot > outRNum * outCNum && neuronChange1[i].getNum() - tot < outRNum * outCNum){
                  if(neuronChange1[i].getNum() - tot - outINum < 0){
                     createdBrain.setNeuronConnections(neuronChange1[i].getNum() - tot, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                  }
                  else{
                     createdBrain.setNeuronConnections(neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                  }
                }
                else if(neuronChange1[i].getNum() - tot > outINum && neuronChange1[i].getNum() - tot < outCNum * outRNum && neuronChange2[i].getNum() - tot > outINum && neuronChange2[i].getNum() - tot < outCNum * outRNum){
                  createdBrain.setNeuronConnections(neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                }
                neurons[neuronChange1[i].getNum()].setActivated(false);
                neurons[neuronChange2[i].getNum()].setActivated(false);
            }
            
            Neuron[] tempNeuron = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
            for(int i = 0; i < neuronChange2Count - neuronChange1Count; i++){
                tempNeuron[i] = neuronChange1[neuronChange1Count + i];
            }
            
            neuronChange1 = (Neuron[]) tempNeuron.clone();
            neuronChange2 = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
            neuronChange1Count = neuronChange2Count - neuronChange1Count;
            neuronChange2Count = 0;
            timeNum = 0;
            goOn = false;
            outputActivated = false;
        }
        else if(timeNum == 0 && outputActivated == true && time == activatedCount - 1 && goOn == false){
        	timeNum = 1;
        }
        
		return newNeuronArray;
	}
	
	
	public int[] shiftArray(int num, int[] brainArray){
	    
        int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public Neuron[] shiftArray(int num, Neuron[] brainArray){
	    
        Neuron[] tempBrain = new Neuron[brainArray.length];
        tempBrain = (Neuron[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public int[] shiftArrayBack(int num, int[] brainArray){
		int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
            if(i == num){
                brainArray[i] = 0;
            }
            else{
                brainArray[i] = tempBrain[i - 1];
            }
        }
        
        return brainArray;
	}
    
    public int score(String response, String answer){
        return 0;
    }
	
}

class Shapes implements java.io.Serializable{

	int x;
	int y;
	String type;

	public Shapes(){

	}

	public String getType(){		
		return type;
	}

	public int getX(){
		return x;
	}

	public int getY(){
		return y;
	}

}

class Circle extends Shapes implements java.io.Serializable{

	int radius;

	public Circle(int radius, int x, int y){

		this.x = x;
		this.y = y;
		this.radius = radius;
		this.type = "Circle";

	}

	public int getRadius(){
		return this.radius;
	}

}

class Square extends Shapes implements java.io.Serializable{

	int height;
	int width;

	public Square(int height, int width, int x, int y){

		this.x = x;
		this.y = y;
		this.height = height;
		this.width = width;
		this.type = "Square";

	}

	public String getType(){
		return type;
	}

	public int getHeight(){
		return this.height;
	}

	public int getWidth(){
		return this.width;
	}

}

class Neuron implements java.io.Serializable{
	
	int[] timesActivated;
    double[] targetValues;
    int alreadyActivated = 0;
    int outputNum = ReccurentNeuralNet.outNum;
    double[] netValues;
	boolean[] alreadyChecked;
    int[][] dValues;
    int[] timeLeft;
	int timeCount = 0;
    int delayAmount = 0;
    int delayRemaining = 0;
	int num;
	int[] connections;
	int[] inputs;
	int inputCount;
	double value;
	int length;
	int finalConnections = 0;
	boolean isActivated = false;
	int subject;
	double benefit = 0;
	double percent = 0;
    double dValuePassed = 0;
    int timesLeft;
	
	public Neuron(int number, int connectionCount){
		num = number;
		value = 0;
		connections = new int[connectionCount];
		inputs = new int[100];
		inputCount = 0;
		timesActivated = new int[5];
        netValues = new double[5];
        targetValues = new double[5];
		alreadyChecked = new boolean[5];
        
        //I don't know why I did this.
        //timesLeft = new int[outputNum];
        timesLeft = 0;
	}
	
	public int getNum(){
		return num;
	}
	public int getConnections(int i){
		return connections[i];
	}
	public double getValue(){
		return value;
	}
    public double getOutput(){
        return (1 /(1 + Math.exp(-value)));
    }
	public int getLength(){
		return length;
	}
	public int getConnectionCount(){
		return finalConnections;
	}
    public int getDelay(){
        return delayAmount;
    }
    public int getRemainingDelay(){
    	return delayRemaining;
    }
    public boolean isActivated(){
    	return isActivated;
    }
    public int getSubject(){
    	return subject;
    }
    public double getBenefit(){
    	return benefit;
    }
    public double getPercent(){
    	return percent;
    }
    public int getInputs(int neuronCount){
    	return inputs[neuronCount];
    }
    public int getInputCount(){
        return inputCount;
    }
    public double getKeepValue(int i){
        return dValues[i][timesLeft];
    }
    public int getTimes(int timeCounts){
    	return timesActivated[timeCount - 1 - timeCounts];
    }
    public double getNetValues(int valueCount){
        return netValues[timeCount - 1 - valueCount];
    }
    public double getOutputValues(int valueCount){
        return 1 / (1 + Math.exp(netValues[timeCount - 1 - valueCount]));
    }
    public int getTimeCount(){
        return timeCount;
    }
    public boolean getChecked(int checkNum){
    	return alreadyChecked[checkNum];
    }
    public double getTargetValueAt(int time){
        for(int i = 0; i < timeCount; i++){
            if(time == timesActivated[i]){
                if(targetValues[i] == 0){
                    return 0;
                }
                else{
                    return targetValues[i];
                }
            }
        }
        return 0;
    }
    public boolean getIfFinished(){
        if(alreadyActivated == inputCount){
            return true;
        }
        else{
            return false;
        }
    }
    public double getDValuePassed(){
        return dValuePassed;
    }
    public double getOutputValueAt(int time){
        for(int i = 0; i < timeCount; i++){
            if(time == timesActivated[i]){
                return 1 / (1 + Math.exp(netValues[i]));
            }
        }
        System.out.println("No value found at time " + time);
        return 0;
    }
    
    public void addValue(double newValue){
        value += newValue;
    }
    public void addInput(int neuronNum){
    	inputs[inputCount] = neuronNum;
    	inputCount++;
    	if(inputCount >= inputs.length){
    		int[] temp = new int[inputCount + 2];
    		for(int i = 0; i < inputs.length; i++){
    			temp[i] = inputs[i];
    		}
    		inputs = temp;
    		temp = null;
    		alreadyChecked = new boolean[inputs.length];
    	}
    }
    public void addTime(int timeNum){
    	timesActivated[inputCount] = timeNum;
        netValues[inputCount] = this.value;
    	timeCount++;
        timesLeft = timeCount;
    	if(timeCount >= timesActivated.length){
    		int[] temp = new int[timeCount + 2];
            double[] vTemp = new double[timeCount + 2];
            double[] tvTemp = new double[timeCount + 2];
            dValues = new int[outputNum][timeCount + 2];
    		for(int i = 0; i < timesActivated.length; i++){
    			temp[i] = timesActivated[i];
                vTemp[i] = netValues[i];
                tvTemp[i] = targetValues[i];
    		}
    		timesActivated = temp;
            netValues = vTemp;
            targetValues = tvTemp;
    		temp = null;
            vTemp = null;
            tvTemp = null;
    	}
    }
	
    public void addActivated(){
        timeCount++;
    }
    
	public void setConnections(int neuronNum){
		connections[finalConnections] = neuronNum;
      if(finalConnections < connections.length - 1){
         finalConnections++;
      }
 
	}
	public void setValue(double newValue){
		value = newValue;
	}
	public void setLength(int newLength){
		length = newLength;
	}
	public void setDelay(int newDelay){
        delayAmount = newDelay;
    }
    public void setActivated(boolean newState){
    	isActivated = newState;
    	if(newState == true){
    		delayRemaining = delayAmount;
    	}
    }
    public void setKeepValue(int oNum, int keepValue, int time){
        if(time == timesActivated[timesLeft]){
            timesLeft--;
            dValues[oNum][timesLeft + 1] = keepValue;
            //return keepValue;    
        }
        else{
            dValues[oNum][timesLeft] = keepValue;
        }
        //timesLeft--;
    }
    public void setSubject(int newSubject){
    	subject = newSubject;
    }
    public void setBenefit(double newBenefit){
    	benefit = newBenefit;
    }
    public void setPercent(double newPercent){
    	percent = newPercent;
    }
    public void setDValuePassed(double newDNet){
        dValuePassed = newDNet;
    }
    public void addTargetValue(double value){
        targetValues[timeCount--] = value;
    }
	
	public void shrinkArray(){
		
		int[] tempConnections = new int[finalConnections];
		for(int i = 0; i < finalConnections - 1; i++){
			tempConnections[i] = connections[i];
		}
		connections = null;
		connections = new int[finalConnections];
		System.arraycopy(tempConnections, 0, connections, 0, tempConnections.length);
		this.setLength(connections.length);
		
	}
    
    public boolean checkConnection(int connectedTo){
        for(int i = 0; i < finalConnections; i++){
            if(connections[i] == connectedTo){
                return true;
            }
        }
        return false;
    }
    
    public void delayTick(){
        if(delayRemaining != 0){
            delayRemaining = delayRemaining - 1;
        }
    }
    
    public void setChecked(int checkNum, boolean state){
    	alreadyChecked[checkNum] = state;
    }
	
}

class Memory implements java.io.Serializable{
    
    String mem;
    int num;
    
    public Memory(String memory, int number){
        mem = memory;
        num = number;
    }
    
    public String getMemory(){
        return mem;
    }
    
    public void setMemory(String newMemory){
        mem = newMemory;
    }

}


Version 2:

import java.util.Scanner;
import java.util.Random;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.*;
import java.awt.*;

import javax.swing.BorderFactory; 
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.awt.event.MouseEvent;

public class ReccurentNeuralNet extends JPanel{

	Timer timer;
	int speed = 2;
    
	String symbols = "abcdefghijklmnopqrstuvwxyz;:',!?.()\"123456789 ";
	
    int screenCordX = 0;
    int screenCordY = 0;
    
    public JScrollPane scroller;
    public JScrollPane scroller2;
    public JTextArea display;
    public JTextField inputLine;
    
	public static Circle[] foodArray;
	public static Circle base;
    
    int xTransform = 0;
    int yTransform = 0;
    
    int switchType = 0;
    
    CompBrain[] brainList;
    int[][] weightTypes;
    int[][] inputWeightTypes;
        
	public static int rNum = 1;
	public static int cNum = 1000;
	public static int inNum = 46;
	public static int outNum = 46;
    
    public Brain first;
    public CompBrain comp;
    
    public static int keepBrainNum = 0;
    
	public static int foodNum = 20;
	public static int brainNum = 0;
    
    public static double mutationPercent = .10;

	static CompBrain[] brains;
	static String[] brainFileLoc;
	static Neuron[] inputs;

	int count = 0;
	int maxCount = 10000;

	int genNum = 2;

	public void paintComponent(Graphics g){

		super.paintComponent(g);

	}
    
    // Checklist: -Check the getOutputValueAt() function and where it is used. It might be wrong.
    
    
    // Done:      -Find and set each target value.
    //            -Finish adding the new neurons to the list of active neurons.
    //            -At each point I need to make each neuron store the value it has when it activates. The net value and the value after being passed through
    //             the activation function. DONE
    //            -Create a function that does this: If an output neuron is activated that isn't the correct one, and the other desired output neuron has a value of
    //             zero, randomly connect that neuron to other neurons that are activated at that time to make sure it will have some way of working. Because if it
    //             isn't connected to any neurons that are activated at that time, it won't ever be able to work, no matter what. Do this by looping through every neuron
    //             and check every time on each neuron. If one of them is the right time, form a connection between the two of them.
    
    public Brain backPropagate(Brain b){
        
        Neuron[] activeNeurons = new Neuron[rNum * cNum + outNum];
        int activeNeuronCount = outNum;
        double learningRate = .5;
        //Sets all of the active neurons to the outputs because they are the first ones that need to be checked.
        for(int i = 0; i < outNum; i++){
            activeNeurons[i] = b.getNeuron(i + rNum * cNum);
        }

        boolean first = true;
        
        //Loop through all of the time the brain was active.
        for(int i = b.getTotalTime(); i >= 0; i--){
            
            //Loops through all of the active neurons.
            for(int u = 0; u < activeNeuronCount; u++){
                //Loops through all of the inputs into the certain neuron.
                for(int y = 0; y < activeNeurons[u].getInputCount(); y++){
                    
                    Neuron n = activeNeurons[u];
                    Neuron iN;
                    //This will return a negative number if it is an input neuron.
                    if(n.getInputs(y) > 0){
                        iN = b.getNeuron(n.getInputs(y));
                    }
                    else{
                        iN = b.getInputNeurons(n.getInputs(y));
                    }
                    
                    //This is the value holds all of the various partial derivatives that the next weight will depend on.
                    double keepValue;
                    
                    //The value that the neuron is supposed to have at a certai point in time.
                    double targetValue = activeNeurons[u].getTargetValueAt(i);
                    
                    for(int z = 0; z < iN.getTimeCount(); z++){
                        if(iN.getTimes(z) == i){
                            if(first == true){
                                
                                double outputValue = n.getOutputValueAt(iN.getTimes(z));
                                if(targetValue > 0 && outputValue == 0){
                                    for(int a = 0; a < rNum * cNum; a++){
                                        Neuron test = b.getNeuron(a);
                                        for(int c = 0; c < test.getTimeCount(); c++){
                                            if(test.getTimes(c) == i){
                                                if(Math.random() < .5){
                                                    b.createWeights(test.getNum(), iN.getNum(), Math.random() * 16);
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                double dError = -(targetValue - outputValue) * (outputValue * (1 - outputValue)) * iN.getOutputValues(z);
                                
                                //This value will be passed to the next layer the is backpropagated.
                                keepValue = -(targetValue - outputValue); // * (outputValue * (1 - outputValue));
                                b.setKeepValue(n.getInputs(y) - (rNum * cNum), u, keepValue /* + iN.getValuePassed() I don't remember why I put this here...*/, i);
                                
                                //Next, mutiply by the learning rate and subtract that value from the weight.
                                double newWeight = Brain.toDecimal(b.getWeights(iN.getNum(), n.getNum())) - dError * learningRate;
                                b.setWeights(iN.getNum(), n.getNum(), Brain.toBinary(newWeight));

                            }
                            else{
                                double outputValue = n.getOutputValueAt(iN.getTimes(z));
                                double outErrors[] = new double[outNum];
                                double totalError = 0;
                                for(int x = 0; x < outNum; x++){
                                    if(n.getKeepValue(x) != 0){
                                        outputValue = n.getOutputValueAt(iN.getTimes(z));
                                        double newKeepValue;
                                        if(n.getInputs(y) > 0){ //Have to add another part for input weights
                                            
                                            //This could be wrong, the ending part.
                                            newKeepValue = n.getKeepValue(x) * (outputValue * (1 - outputValue)) * (outputValue * Brain.toDecimal(b.getWeights(n.getNum(), iN.getNum())));
                                            b.setKeepValue(n.getInputs(y) - (rNum * cNum), u, newKeepValue, i);
                                        }
                                        else{
                                            newKeepValue = n.getKeepValue(x) * (outputValue * (1 - outputValue)) * (outputValue * Brain.toDecimal(b.getInputWeights(n.getNum(), iN.getNum())));
                                            b.setKeepValue(n.getInputs(y) - (rNum * cNum), u, newKeepValue, i);
                                        }
                                        totalError += newKeepValue * iN.getOutputValueAt(iN.getTimes(z));
                                    }
                                }
                                //Next, mutiply by the learning rate and subtract that value from the weight.
                                if(n.getInputs(y) > 0){  //Have to add another part for input weights.
                                    double newWeight = Brain.toDecimal(b.getWeights(iN.getNum(), n.getNum())) - totalError * learningRate;
                                    b.setWeights(iN.getNum(), n.getNum(), Brain.toBinary(newWeight));
                                    activeNeuronCount++;
                                    activeNeurons[activeNeuronCount] = iN;
                                    //n.addActivated();
                                }
                                else{
                                    double newWeight = Brain.toDecimal(b.getWeights(iN.getNum(), n.getNum())) - totalError * learningRate;
                                    b.setInputWeights(iN.getNum(), n.getNum(), Brain.toBinary(newWeight));
                                }
                            }
                        }
                        else if(iN.getTimes(z) < u){
                            break;
                        }
                        
                    }
                    
                }
                
            }
            first = false;

        }
        return b;
    }
    
    // This function will call itself inside it to keep digginf deeper into the network. Once it digs as deep as it can, it will begin to go back out then in. It will
    // repeat this process until it climbs back out to the original function. This is called a recursive function. Just an idea.

    public void checkBackPropagate(Brain b, int timeLeft, Neuron n){
        
    }
	
    public CompBrain[] shiftArray(int num, CompBrain[] brainArray){
    
        CompBrain[] tempBrain = new CompBrain[brainArray.length];
        tempBrain = (CompBrain[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
            if(i == num){
                brainArray[i] = null;
            }
            else{
                brainArray[i] = tempBrain[i - 1];
            }
        }
        
        return brainArray;
    
    }

	public static void main(String[] args){

		brains = new CompBrain[brainNum];
        
		ReccurentNeuralNet content = new ReccurentNeuralNet();
        JFrame window = new JFrame();
		window.setContentPane(content);
		window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		window.setLocation(120,70);
		window.setSize(640,480);
		window.setVisible(true);

	}

	class Task extends TimerTask {
        
		public void run(){
            /*
			count++;
			String[] inputArray = new String[inNum];
			
			for(int i = 0; i < brainNum; i++){
				brains[i].calculateWeights(inputArray);
				brains[i].calculateMovement();
			}

			repaint();
            */
		}
        
	}
    
    public class mouseListener implements MouseMotionListener, MouseListener {
        
        boolean mouseHeld = false;
        int x1, x2, xDistance;
        int y1, y2, yDistance;
        
        public void mouseClicked(MouseEvent e){}
        public void mouseDragged(MouseEvent e){
            if(mouseHeld == true){
                x2 = e.getX();
                y2 = e.getY();
                
                xDistance = x1 - x2;
                yDistance = y1 - y2;
                
                xTransform += -xDistance;
                yTransform += -yDistance;
                
                x1 = x2;
                y1 = y2;
            }
        }
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}
        public void mouseMoved(MouseEvent e){}
        public void mousePressed(MouseEvent e){
            mouseHeld = true;
            x1 = e.getX();
            y1 = e.getY();
        }
        public void mouseReleased(MouseEvent e){
            mouseHeld = false;
        }
        public void mouseWheel(MouseEvent e){}
        
    }
    
    public class textListener implements ActionListener{
    
        public void actionPerformed(ActionEvent e){
            
            display.setText(display.getText() + inputLine.getText() + "\n");
            String[] inputs = new String[inputLine.getText().length()];
            String[] inputs2 = new String["What is Sam?".length()];
            
            for(int i = 0; i < inputLine.getText().length(); i++){
                inputs[i] = "" + inputLine.getText().charAt(i);
            }
            
            for(int i = 0; i < "What is Sam?".length(); i++){
                inputs2[i] = "" + "What is Sam?".charAt(i);
            }
            
            boolean goOn = false;
            
            String[][] emptyWeights = new String[rNum * cNum][rNum * cNum * 2 + outNum + 2];
            Brain brain =  new Brain(rNum, cNum, true, emptyWeights, 10, outNum, inNum);
            /*
            while(goOn == false){
            	
                int addNum = 0;
            	if(genNum % 2 == 1){
            		addNum = brainNum;
            	}
            	for(int i = 0; i < brainNum; i++){
            		System.out.println("Calculating...");
            		brains[i] = openBrain(brainFileLoc[i], i + addNum);
            		brains[i].calculateWeights(inputs);
            		System.out.println("Calculated.");
            		System.out.println("Calculating response...");
            		String reply = brains[i].getBrain().calculateWeights(inputs2);
            		System.out.println(reply);
            		System.out.println("Calculated...");
            		int score = calculateScore("A cat.", reply);
            		//improveBrain(brains[i], inputs, "What is Sam?", "A cat.", score);
            		//display.setText(display.getText() + reply + "\n");
            		brains[i].setScore(score);
            		saveBrain(brains[i], i + addNum);
            		CompBrain emptyBrain = new CompBrain(0, 0, 0, 0, 0, 0, false, null, 0, null);
            		emptyBrain.setScore(score);
            		brains[i] = emptyBrain;
            	}
            	createNextGen();
            	genNum++;
            }
            inputLine.setText("");
            comp.calculateWeights(inputs);
            //first.setInputs(inputs);
            //System.out.println("Generating a reply...");
            String reply = comp.getBrain().calculateWeights(inputs);
            */
            
            //I don't remember what this is...   double[][] desiredOutputs = new double[][outNum];
            String reply = null;
            System.out.println("Starting...");
            while(goOn == false){
                reply = brain.calculateWeights(inputs2, inputLine.getText());
                System.out.println(reply);
                backPropagate(brain);
            }
            
            inputLine.setText("");    
            
            display.setText(display.getText() + reply + "\n");
        }
    
    }
    
    public void saveBrain(CompBrain brain, int brainNum){
    	
    	try{
    		FileOutputStream fos = new FileOutputStream("C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + brainNum + ".dat");
    		ObjectOutputStream out = new ObjectOutputStream(fos);
    		out.writeObject(brain);
    		fos.close();
    		out.close();
    	}
    	catch(IOException e){
    		
    	}
    	
    }
    
    public CompBrain openBrain(String fileLoc, int num){
    	
    	CompBrain brain = null;
    	try{
    		FileInputStream fIS = new FileInputStream("C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + num + ".dat");
    		ObjectInputStream iNS = new ObjectInputStream(fIS);
    		try{
    			brain = (CompBrain) iNS.readObject();
    		}
    		catch(ClassNotFoundException e){
    			
    		}
    		fIS.close();
    		iNS.close();
    	}
    	catch(IOException e){
    		
    	}
    	
    	return brain;
    	
    }
    
	public ReccurentNeuralNet(){

		//timer = new Timer();
		//timer.schedule(new Task(), 0, speed);
        
        //int rows, int columnNumber, boolean first, String[][] weight, int bRadius, int outputNum, int inputNum
        weightTypes = new int[rNum * cNum][rNum * cNum + rNum * cNum + outNum + inNum + 2];
        inputWeightTypes = new int[inNum][rNum * cNum];
		String[][] emptyWeights = new String[rNum * cNum][rNum * cNum * 2 + outNum + 2];
        brains = new CompBrain[brainNum];
        brainFileLoc = new String[brainNum];
        for(int i = 0; i < brainNum; i++){
        	
        	Brain f = new Brain(rNum, cNum, false, emptyWeights, 10, outNum, inNum);
        	CompBrain compBrain = new CompBrain(rNum, cNum, rNum, cNum, outNum, inNum,  true, emptyWeights, inNum, f);
        	brainFileLoc[i] = "C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + i + ".dat";
        	saveBrain(compBrain, i);

        }
        Border textBorder = BorderFactory.createEtchedBorder();
        
        display = new JTextArea(25, 55);
        display.setBorder(textBorder);
        display.setEditable(false);
        scroller = new JScrollPane( display );
        this.add(scroller);
        
        inputLine = new JTextField("", 55);
        inputLine.setBorder(textBorder);
        inputLine.addActionListener(new textListener());
        scroller2 = new JScrollPane( inputLine );
        //scroller2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        this.add(scroller2);
        
        mouseListener listener = new mouseListener();
        addMouseListener(listener);
        addMouseMotionListener(listener);

	}
	
	public int calculateScore(String expected, String returned){
		int score = 0;
		
		score = Math.abs(expected.length() - returned.length());
		if(expected.length() < returned.length()){
			for(int i = 0; i < expected.length(); i++){
				if(expected.charAt(i) == returned.charAt(i)){
					score = score - 5;
				}
				else{
					score = score + 5;
				}
			}
		}
		else{
			for(int i = 0; i < returned.length(); i++){
				if(expected.charAt(i) == returned.charAt(i)){
					score = score - 5;
				}
				else{
					score = score + 5;
				}
			}
		}
		if(score < 0){
			score = 0;
		}
		return score;
	}
	
    /*
	public CompBrain improveBrain(CompBrain brain, String[] inputArray, String inputString, String expectedOutput, int originalScore){
		
		if(switchType == 0){
			for(int i = 0; i < inNum; i++){
				
				for(int u = 0; u < brain.getInputNeurons(i).getConnectionCount(); u++){
						System.out.println("0Input: " + i);
						String orgWeight = brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u));
						double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) + 3;
						if(newWeight > 16){
							newWeight = 15.99;						
						}
						brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
						brain.calculateWeights(inputArray);
						String output = brain.getBrain().calculateWeights(inputArray);
						int score = calculateScore(expectedOutput, output);
						if(score > originalScore){
							inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] = 1;
							double diff = score - originalScore;
							brain.setInputBenefit(i, brain.getInputNeurons(i).getBenefit() + diff);
						}
						else{
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), orgWeight);
							double newWeightLower = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) - 3;
							if(newWeightLower < -16){
								newWeightLower = 15.99;						
							}
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeightLower));
							brain.calculateWeights(inputArray);
							String output2 = brain.getBrain().calculateWeights(inputArray);
							score = calculateScore(expectedOutput, output);
							if(score > originalScore){
								inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] = 2;
								double diff = score - originalScore;
								brain.setInputBenefit(i, brain.getInputNeurons(i).getBenefit() + diff);
							}
							else{
								inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] = 0;
								brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), orgWeight);
							}
						
						}
				}
			}
			
			for(int i = 0; i < rNum * cNum; i++){
				
				for(int u = 0; u < brain.getNeuron(i).getConnectionCount(); u++){
					String orgWeight = brain.getWeights(i, brain.getNeuron(i).getConnections(u));
					System.out.println("0Neuron: " + i);
						double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) + 3;
						if(newWeight > 16){
							newWeight = -15.99;						
						}
						brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
						brain.calculateWeights(inputArray);
						String output = brain.getBrain().calculateWeights(inputArray);
						int score = calculateScore(expectedOutput, output);
						if(score > originalScore){
							weightTypes[i][brain.getNeuron(i).getConnections(u)] = 1;
							double diff = score - originalScore;
							brain.setBenefit(i, brain.getNeuron(i).getBenefit() + diff);
						}
						else{
							brain.setWeights(i, brain.getNeuron(i).getConnections(u),orgWeight);
							double newWeightLower = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) - 3;
							if(newWeightLower < -16){
								newWeightLower = -15.99;						
							}
							brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeightLower));
							brain.calculateWeights(inputArray);
							String output2 = brain.getBrain().calculateWeights(inputArray);
							score = calculateScore(expectedOutput, output);
							if(score > originalScore){
								weightTypes[i][brain.getNeuron(i).getConnections(u)] = 2;
							}
							else{
								weightTypes[i][brain.getNeuron(i).getConnections(u)] = 0;
								brain.setWeights(i, brain.getNeuron(i).getConnections(u), orgWeight);
								double diff = score - originalScore;
								brain.setBenefit(i, brain.getNeuron(i).getBenefit() + diff);
							}
						
						}
				}
			}
			
			switchType = 1;
			
		}
		else{
			for(int i = 0; i < inNum; i++){
				for(int u = 0; u < brain.getNeuron(i).getConnectionCount(); u++){
					
					if(inputWeightTypes[i][brain.getInputNeurons(i).getConnections(u)] == 1){
						double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) + 1;
						if(newWeight > 16){
							newWeight = 15.99;						
						}
						brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else if(inputWeightTypes[i][brain.getNeuron(i).getConnections(u)] == 2){
						double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) - 1;
						if(newWeight < 16){
							newWeight = -15.99;						
						}
						brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else{
						double random = Math.random();
						if(random > .5){
							double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) - 1;
							if(newWeight < 16){
								newWeight = -15.99;						
							}
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
						}
						else{
							double newWeight = Brain.toDecimal(brain.getInputWeights(i, brain.getInputNeurons(i).getConnections(u))) + 1;
							if(newWeight > 16){
								newWeight = 15.99;						
							}
							brain.setInputWeights(i, brain.getInputNeurons(i).getConnections(u), Brain.toBinary(newWeight));
						}
					}
				}
			}
			
			for(int i = 0; i < rNum * cNum; i++){
				for(int u = 0; u < brain.getNeuron(i).getConnectionCount(); u++){
					if(weightTypes[i][brain.getNeuron(i).getConnections(u)] == 1){
						double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) + 1;
						if(newWeight > 16){
							newWeight = 15.99;						
						}
						brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else if(weightTypes[i][brain.getNeuron(i).getConnections(u)] == 2){
						double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) - 1;
						if(newWeight < 16){
							newWeight = -15.99;						
						}
						brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
					}
					else{
						double random = Math.random();
						if(random > .5){
							double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) - 1;
							if(newWeight < 16){
								newWeight = -15.99;						
							}
							brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
						}
						else{
							double newWeight = Brain.toDecimal(brain.getWeights(i, brain.getNeuron(i).getConnections(u))) + 1;
							if(newWeight > 16){
								newWeight = 15.99;						
							}
							brain.setWeights(i, brain.getNeuron(i).getConnections(u), Brain.toBinary(newWeight));
						}
					}
				}
			}
			
			brain.calculateWeights(inputArray);
			String output = brain.getBrain().calculateWeights(inputArray);
			int score = calculateScore(expectedOutput, output);
			if(score < originalScore){
				switchType = 0;
			}
			
		}
		double total = 0;
		for(int i = 0; i < inNum; i++){
			total += brain.getInputNeurons(i).getBenefit();
		}
		
		for(int i = 0; i < rNum * cNum; i++){
			total += brain.getNeuron(i).getBenefit();
		}
		double totalPercent = 0;
		for(int i = 0; i < inNum; i++){
			brain.setInputPercent(i, brain.getInputNeurons(i).getBenefit() / total);
			totalPercent = totalPercent + brain.getInputNeurons(i).getPercent();
			brain.setInputPercent(i, totalPercent);
		}
		for(int i = 0; i < rNum * cNum; i++){
			brain.setNeuronPercent(i, brain.getNeuron(i).getBenefit() / total);
			totalPercent = totalPercent + brain.getNeuron(i).getPercent();
			brain.setNeuronPercent(i, totalPercent);
		}
		
		double avg = total / (rNum * cNum + inNum);
		
		for(int i = 0; i < 2; i++){			
			double random = Math.random();
			for(int u = 0; u < inNum + rNum * cNum; u++){
				if(u < inNum){
					if(random < brain.getInputNeurons(u).getPercent()){
						for(int y = 0; y < brain.getInputNeurons(u).getConnectionCount(); y++){
							double newNeuron = Math.random() * (rNum * cNum);
							newNeuron = Math.round(newNeuron);
							brain.setInputNeuronConnections(y, (int)newNeuron);
							brain.setInputWeights(u, (int)newNeuron, Brain.toBinary(Math.random() * 16));
						}
						break;
					}
					
				}
				else{
					if(random < brain.getNeuron(u).getPercent()){
						for(int y = 0; y < brain.getNeuron(u).getConnectionCount(); y++){
							double newNeuron = Math.random() * (rNum * cNum + rNum * cNum + inNum + outNum + 2);
							newNeuron = Math.round(newNeuron);
							brain.setNeuronConnections(y, (int)newNeuron);
							brain.setWeights(u, (int)newNeuron, Brain.toBinary(Math.random() * 16));
						}
						break;
					}
				}
			}
		}
		
		return brain;
	}
    
    */
    
	public CompBrain breedBrains(CompBrain brain1, CompBrain brain2){
		
		String[][] emptyWeights = new String[rNum * cNum][rNum * cNum + outNum + 2];
		Brain firstBrain = new Brain(rNum, cNum, false, emptyWeights, 10, outNum, inNum);
		for(int i = 0; i < rNum * cNum; i++){
			firstBrain.setNeuronDelay(i, brain1.getBrain().getNeuron(i).getDelay());
		}
		
		CompBrain newBrain = new CompBrain(rNum, cNum, rNum, cNum, outNum, inNum, false, emptyWeights, inNum, firstBrain);
        int connectionCount = 0;
        
        for(int i = 0; i < inNum; i++){
        	int topC = 0;
        	if(brain1.getInputNeurons(i).getConnectionCount() > brain2.getInputNeurons(i).getConnectionCount()){
        		topC = brain1.getInputNeurons(i).getConnectionCount();
        	}
        	else{
        		topC = brain2.getInputNeurons(i).getConnectionCount();
        	}
            for(int u = 0; u < topC; u++){
            	double random = Math.random();
            	if(u < brain1.getInputNeurons(i).getConnectionCount() && u < brain2.getInputNeurons(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getInputNeurons(i).setConnections(brain1.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain1.getInputNeurons(i).getConnections(u), brain1.getInputWeights(i, brain1.getInputNeurons(i).getConnections(u)));
            		}
            		else{
            			newBrain.getInputNeurons(i).setConnections(brain2.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain2.getInputNeurons(i).getConnections(u), brain2.getInputWeights(i, brain2.getInputNeurons(i).getConnections(u)));
            		}
            	}
            	else if(u < brain1.getInputNeurons(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getInputNeurons(i).setConnections(brain1.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain1.getInputNeurons(i).getConnections(u), brain1.getInputWeights(i, brain1.getInputNeurons(i).getConnections(u)));
            		}
            	}
            	else{
            		if(random > .5){
            			newBrain.getInputNeurons(i).setConnections(brain2.getInputNeurons(i).getConnections(u));
            			newBrain.setInputWeights(i, brain2.getInputNeurons(i).getConnections(u), brain2.getInputWeights(i, brain2.getInputNeurons(i).getConnections(u)));
            		}
            	}
            }
        }
        
        for(int i = 0; i < rNum * cNum; i++){
        	int topC = 0;
        	if(brain1.getNeuron(i).getConnectionCount() > brain2.getNeuron(i).getConnectionCount()){
        		topC = brain1.getNeuron(i).getConnectionCount();
        	}
        	else{
        		topC = brain2.getNeuron(i).getConnectionCount();
        	}
            for(int u = 0; u < topC; u++){
            	double random = Math.random();
            	if(u < brain1.getNeuron(i).getConnectionCount() && u < brain2.getNeuron(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getNeuron(i).setConnections(brain1.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain1.getNeuron(i).getConnections(u), brain1.getWeights(i, brain1.getNeuron(i).getConnections(u)));
            		}
            		else{
            			newBrain.getNeuron(i).setConnections(brain2.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain2.getNeuron(i).getConnections(u), brain2.getWeights(i, brain2.getNeuron(i).getConnections(u)));
            		}
            	}
            	else if(u < brain1.getNeuron(i).getConnectionCount()){
            		if(random < .5){
            			newBrain.getNeuron(i).setConnections(brain1.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain1.getNeuron(i).getConnections(u), brain1.getWeights(i, brain1.getNeuron(i).getConnections(u)));
            		}
            	}
            	else{
            		if(random > .5){
            			newBrain.getNeuron(i).setConnections(brain2.getNeuron(i).getConnections(u));
            			newBrain.setWeights(i, brain2.getNeuron(i).getConnections(u), brain2.getWeights(i, brain2.getNeuron(i).getConnections(u)));
            		}
            	}
            }
        }
        
        for(int i = 0; i < rNum * cNum + rNum * cNum + inNum + outNum + 2; i++){
        	double random = Math.random();
        	if(random < .5){
        		newBrain.setNeuronDelay(i, brain1.getNeuron(i).getDelay());
        	}
        	else{
        		newBrain.setNeuronDelay(i, brain2.getNeuron(i).getDelay());
        	}
        	
        }
        
        System.out.println("ConnectionCount: " + connectionCount);
        return newBrain;
        
	}
    
	public void createNextGen(){
        
        CompBrain[] topBrains = new CompBrain[brainNum];
        /*
        for(int i = 0; i < brainNum; i++){
            for(int u = 0; u < brainNum; u++){
                
                if(i == 0){
                    topBrains[i] = brains[i];
                    break;
                }
                
                if(topBrains[Math.abs(u - brainNum) - 1] != null){
                	if(brains[i].getScore() < topBrains[Math.abs(u - brainNum) - 1].getScore()){
                    	int newPlace = Math.abs(u - brainNum);
                    	System.out.println("Array shifted");
                        topBrains = (CompBrain[]) shiftArray(newPlace, topBrains).clone();
                        topBrains[Math.abs(u - brainNum)] = brains[i];
                        break;
                    }
                    else{
                    	if(u == brainNum - 1){
                    		topBrains = (CompBrain[]) shiftArray(0, topBrains).clone();
                    		topBrains[0] = brains[i];
                        }
                    }
                }
            }
        }
        */
        
		double totalScore = 0;
		int maxScore = 0;
		for(int i = 0; i < brainNum; i++){
			if(brains[i].getScore() > maxScore){
				maxScore = brains[i].getScore();
			}
			System.out.println("Brain" + i + " score");
		}
		
		for(int i = 0; i < brainNum; i++){
			brains[i].setScore(maxScore - brains[i].getScore());
			totalScore += brains[i].getScore();
			System.out.println("Brain" + i + " percent calculated");
		}
		
		System.out.println(totalScore);
		for(int i = 0; i < brainNum; i++){
			brains[i].setPercent((brains[i].getScore() / totalScore) * 100);
			System.out.println("Brain" + i + " more percent calculated");
		}
        /*
        int lowestNum = topBrains[brainNum - 1].getScore();
        for(int i = 0; i < brainNum; i++){
            topBrains[i].setAddedScore(Math.abs(lowestNum));
        }
         */
		int comScore = 0;

		for(int i = 0; i < brainNum; i++){    		
			comScore += brains[i].getPercent();
			brains[i].setPercent(brains[i].getPercent() + comScore);
			System.out.println("Brain" + i + " even more percent calculated");
			//System.out.println(brains[i].getPercent());
		}
		
		boolean done = false;
		boolean done1 = false;
		CompBrain chosenBrain1 = null;
		CompBrain chosenBrain2 = null;

		CompBrain[] newBrainList = new CompBrain[brainNum];
		String[] newFileLoc = new String[brainNum];
        /*
        for(int i = 0; i < keepBrainNum; i++){
        
            newBrainList[i] = topBrains[i];
            System.out.println((i + 1) + ": " + topBrains[i].getScore());
        
        }
		*/
		for(int z = 0/*keepBrainNum*/; z < brainNum; z++){
			int addNum = 0;
			if(genNum % 2 == 1){
				addNum = brainNum;
			}
			done1 = false;
			done = false;
			while(done1 == false){
				double random = Math.random() * 100;
				for(int i = 0; i < brainNum; i++){
					if(i == 0){
						if(brains[i].getPercent() > random){
							chosenBrain1 = openBrain(brainFileLoc[i], i + addNum);
							System.out.println("Brain 1: " + i);
							System.out.println("Score: " + chosenBrain1.getScore());
							done1 = true;
							break;
						}
					} 	
					else if(brains[i].getPercent() >= random && brains[i - 1].getPercent() < random){						
						chosenBrain1 = openBrain(brainFileLoc[i], i + addNum);
						System.out.println("Brain 1: " + i);
						System.out.println("Score: " + chosenBrain1.getScore());
						done1 = true;
						break;
					}
					
				}
			}
			while(done == false){
				double random1 = Math.random() * 100;
				for(int i = 0; i < brainNum; i++){
					if(i == 0){
						if(brains[i].getPercent() > random1){
							if(chosenBrain1.equals(brains[i])){

							}
							else{
								chosenBrain2 = openBrain(brainFileLoc[i], i + addNum);
								System.out.println("Brain 2: " + i);
								System.out.println("Score: " + chosenBrain2.getScore());
								done = true;
								break;
							}
						}
					}
					else if(brains[i].getPercent() >= random1 && brains[i - 1].getPercent() < random1){
						if(chosenBrain1.equals(brains[i])){

						}
						else{
							chosenBrain2 = openBrain(brainFileLoc[i], i + addNum);
							System.out.println("Brain 2: " + i);
							System.out.println("Score: " + chosenBrain2.getScore());
							done = true;
							break;
						}
					}

				}

			}
			int addNum2 = 0;
			if(addNum == 0){
				addNum2 = brainNum;
			}
			newFileLoc[z] = "C:/Users/Dylan/Desktop/Desktop Junk/Brains/Brain" + (z + addNum2) + ".dat";
			saveBrain(breedBrains(chosenBrain1, chosenBrain2), z + addNum2);
			chosenBrain1 = null;
			chosenBrain2 = null;

		}

		for(int i = 0; i < brainNum; i++){
			brainFileLoc[i] = newFileLoc[i];
		}

	}

}


class Brain implements java.io.Serializable{

	public int radius;

	double percent = 0;

	String symbols = "abcdefghijklmnopqrstuvwxyz;:',!?.()\"123456789 ";
    
    private int totalTime;
	private int[] outputTime;
	private int outputTimeCount = 0;
    private int maxConnectionNum = 7;
    private int maxDelay = 20;
	private int divFunction = 8;
	private int divNeuron = 8;
	private int divPower = 8;
    private int divRotation = 2;
    
    Neuron[] activatedNeurons;
    int activatedCount = 0;

	private String[][] weights;
    private String[] connections1;
    private String[] connections2;
    private String[][] inputWeights;
    private String[] inputs1;
    private String[] inputs2;
	private Neuron[] neurons;
	private String[] neuronFunction;
	private String[] neuronPower;
	private Neuron[] inputs;
    
    private String[] inputString;

	double dx = Math.random() * 638 + 2;
	double dy = Math.random() * 478 + 2;

	int score = 0;

	int divideNum = 1;
	int speedReduce = 1;

	int foodCount;
	int rowNum;
	int colunmNum;

	double moveOut, rotationLeftOut, rotationRightOut;
	double[] outPuts;

	int outNum;
    int connectionNum;
    int inputConnectionNum;

	int x, y;
	double rotation = 0;

	public Brain(int rows, int columnNumber, boolean first, String[][] weight, int bRadius, int outputNum, int inputNum){
        
        inputs = new Neuron[inputNum];
		weights = new String[columnNumber * rows][columnNumber * rows + outputNum + 2];
        inputWeights = new String[inputNum][columnNumber * rows + outputNum + 2];
		outNum = outputNum;
		radius = bRadius;
		System.arraycopy(weight, 0, weights, 0, weight.length);
		rowNum = rows;
		colunmNum = columnNumber;
		neurons = new Neuron[rowNum * colunmNum + outputNum + 2];
		neuronFunction = new String[neurons.length + ReccurentNeuralNet.outNum];
		neuronPower = new String[neuronFunction.length];
		outPuts = new double[outNum];
		
		activatedNeurons = new Neuron[colunmNum * rowNum];
        activatedCount = 0;
        outputTime = new int[1000];

		if(first == true){
			generateWeights();
            System.out.println("Weights generated.");
		}
        else{
            for(int i = 0; i < rowNum * colunmNum; i++){
                neurons[i] = new Neuron(i, maxConnectionNum);
                neurons[i].setDelay(Math.round((float)(5 + Math.random() * maxDelay)));
            }
            for(int i = 0; i < outNum + 2; i++){
                neurons[i + rowNum * colunmNum] = new Neuron(i, maxConnectionNum);
            }
            System.out.println(neurons.length);
            for(int i = 0; i < inputs.length; i++){
                inputs[i] = new Neuron(i, maxConnectionNum);
            }
        }

	}
    
    private void setInputs(String[] inputStringArray){
        inputString = (String[]) inputStringArray.clone();
    }
    
    public Neuron getInputNeurons(int neuronNum){
		return inputs[neuronNum];
	}
    
	private void generateWeights(){
		
        System.out.println("Generating weights.......");
        
		connectionNum = 1000 + Math.round((float)(Math.random() * (maxConnectionNum * colunmNum * rowNum) / 1.5));
		inputConnectionNum = 5 + Math.round((float)(Math.random() * (inputs.length * (maxConnectionNum - 5))));
		int usedConnections = 0;
		
		for(int i = 0; i < rowNum * colunmNum; i++){
			neurons[i] = new Neuron(i, maxConnectionNum);
            neurons[i].setDelay(Math.round((float)(5 + Math.random() * maxDelay)));
		}
		for(int i = 0; i < outNum + 2; i++){
            neurons[i + rowNum * colunmNum] = new Neuron(i, maxConnectionNum);
        }
        //System.out.println(neurons.length);
		for(int i = 0; i < inputs.length; i++){
            inputs[i] = new Neuron(i, maxConnectionNum);
		}
        
        for(int i = 0; i < inputConnectionNum; i++){
            
            boolean goOn = false;
            while(goOn == false){
                int inputNeuron = Math.round((float)(Math.random() * (inputs.length - 1)));
                int neuron = Math.round((float)(Math.random() * (colunmNum * rowNum - 1)));
                
                double random = (double)(Math.random() * 16);
                double negativeRan = Math.random();
                if(negativeRan < 0.5){
                    random = random * -1;
                }
                
                if(inputs[inputNeuron].getConnectionCount() < maxConnectionNum){
                
                    inputWeights[inputNeuron][neuron] = toBinary(random);
                    inputs[inputNeuron].setConnections(neuron);
                    neurons[neuron].addInput(-inputNeuron);
                    goOn = true;
                    
                }
            }
        }
		int output = 0;
		for(int i = 0; i < rowNum; i++){
			for(int u = 0; u < connectionNum; u++){
				
                boolean goOn = false;
                while(goOn == false){
                    int neuron1 = Math.round((float)(Math.random() * (rowNum * colunmNum - 1)));
                    int neuron2 = Math.round((float)(Math.random() * (rowNum * colunmNum + this.outNum - 1 + 2)));
                    
                    double random = (double)(Math.random() * 16);
                    double negativeRan = Math.random();
                    if(negativeRan < 0.5){
                        random = random * -1;
                    }
                    
				    if(weights[neuron1][neuron2] == null && neurons[neuron1].getConnectionCount() < maxConnectionNum){
					   weights[neuron1][neuron2] = toBinary(random);
					   neurons[neuron1].setConnections(neuron2);
					   neurons[neuron2].addInput(neuron1);
                       goOn = true;
                        if(neuron2 > rowNum * colunmNum){
                            System.out.println("Output Connected. " + output);
                            output++;
                        }
				    }
                }
			}
		}
		
		for(int i = 0; i < rowNum * colunmNum; i++){
			//neurons[i].shrinkArray();
		}

		for(int i = 0; i < neuronFunction.length; i++){

			double random = (double)(Math.random() * 16);
			double negativeRan = Math.random();
			if(negativeRan < 0.5){
				random = random * -1;
			}
			neuronFunction[i] = toBinary(random);

		}

		for(int i = 0; i < neuronFunction.length; i++){

			double random = Math.random() * 16;
			neuronPower[i] = toBinary(random);

		}

	}

	public static String toBinary(double num){

		double dNum = Math.abs(num);
		String sNum = "" + dNum;
		String bNum = "";
		char ch = sNum.charAt(1);
		int nu = Character.getNumericValue(ch);

		if(nu == -1){

			for(int i = 0; i < sNum.length(); i++){

				char c = sNum.charAt(i);
				int iNum = Character.getNumericValue(c);

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}

		}
		else{
			int iNum = 0;
			for(int i = 0; i < sNum.length() - 1; i++){

				if(i == 0){
					char c1 = sNum.charAt(0);
					char c2 = sNum.charAt(1);
					String twoNum = "" + c1 + c2;
					iNum = Integer.parseInt(twoNum);
				}

				char c = sNum.charAt(i + 1);    

				if(i != 0){
					iNum = Character.getNumericValue(c);
				}

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}
		}

		if(num < 0){
			bNum = "-" + bNum;
		}
		else{
			bNum = "+" + bNum;
		}
		return bNum;
	}


	public static double toDecimal(String bNum){

		int convertedNum = 0;
		double finalNum = 0;
		String numString = "";

		for(int u = 1; u < (bNum.length()) / 4; u++){
			char c;
			convertedNum = 0;
			for(int i = 0; i < 4; i++){

				if(u != 0){
					c = bNum.charAt(1 + i + u * 4);
				}
				else{
					c = bNum.charAt(i + u * 4);
				}

				int num = Character.getNumericValue(c);

				if(num == 1){
					convertedNum = convertedNum + Math.round((float)Math.pow(2, Math.abs(i)));
				}

			}
			if(u == 1){
				numString = numString + convertedNum + ".";
			}
			else{
				numString = numString + convertedNum;
			}
		}

		//System.out.println(numString);

		finalNum = Double.parseDouble(numString);
		char nChar = bNum.charAt(0);
		if(nChar == '-'){
			finalNum = finalNum * -1;
		}
		return finalNum;

	}

	public double getPercent(){
		return percent;
	}
	
	public Neuron getNeuron(int neuron1){
		return neurons[neuron1];
	}

	public void setPercent(double newPercent){
		this.percent = newPercent;
	}

	public int getScore(){
		return score;
	}

	public String getWeights(int first, int second){
		return weights[first][second];
	}
    
    public int getTotalTime(){
        return totalTime;
    }
    
	public void setWeights(int first, int second, String num){
		weights[first][second] = num;
	}
    
    public void setInputWeights(int first, int second, String num){
        inputWeights[first][second] = num;
    }
    
    public void setKeepValue(int neuronNum, int oNumber, double newValue, int time){
        //neurons[neuronNum].setValue(oNumber, newValue, time);
        neurons[neuronNum].setValue(newValue);
    }

	public String getNeuronFunction(int num){
		return neuronFunction[num];
	}

	public void setNeuronFunction(int num, String s){
		neuronFunction[num] = s;
	}
    
    public String getInputWeights(int first, int second){
        if(inputWeights[first][second] == null){
            return "null";
        }
        else{
            return inputWeights[first][second];
        }
    }

	public void setAddedScore(int newScore){     
		this.score += newScore;  
	}

	public void setFoodCount(int newFoodCount){      
		this.foodCount = newFoodCount; 
	}

	public String getPower(int num){
		return neuronPower[num];
	}

	public void setPower(int num, String set){
		neuronPower[num] = set;
	}
    public void setNeuronConnections(int neuronNum, int connectedNum, double value1, double value2){
        boolean connected = false;
        for(int i = 0; i < neurons[neuronNum].getConnectionCount(); i++){
            if(neurons[neuronNum].getConnections(i) == connectedNum){
                connected = true;
            }
        }
        if(connected == false){
            neurons[neuronNum].setConnections(connectedNum);
            neurons[connectedNum].addInput(neuronNum);
            //System.out.println("Connection set!");
        }
        weights[neuronNum][connectedNum] = toBinary((value1 + value2) / 2);
        
    }
    
    public void setInputConnections(int neuronNum, int connectedNum, double value1, double value2){
      boolean connected = false;
        for(int i = 0; i < inputs[neuronNum].getConnectionCount(); i++){
            if(inputs[neuronNum].getConnections(i) == connectedNum){
                connected = true;
            }
        }
        if(connected == false){
            inputs[neuronNum].setConnections(connectedNum);
            neurons[connectedNum].addInput(-neuronNum);
        }
        
        inputWeights[neuronNum][connectedNum] = toBinary((value1 + value2) / 2);
    }
    
    public void setNeuronDelay(int neuron1, int delay){
    	neurons[neuron1].setDelay(delay);
    }
    
	public String calculateWeights(String[] inputArray, String desiredOutput){

		String[] inputValues = new String[inputArray.length];
        
        for(int i = 0; i < inputArray.length; i++){
            inputValues[i] = inputArray[i];
        }

		for(int i = 0; i < outNum; i++){
			outPuts[i] = 0;
		}

		boolean stop = false;
		int time = 0;
        String answer = "";
		
        while(stop == false){
        	//System.out.println(answer);
        	Neuron[] newActivatedNeurons = new Neuron[colunmNum * rowNum];
        	if(time < inputValues.length){
                int inputNumber = 0;
				for(int i = 0; i < symbols.length(); i++){
					String test = "" + symbols.charAt(i);
					if(test.equalsIgnoreCase(inputValues[time])){
						inputNumber = i;
					}
				}
				
				for(int i = 0; i < inputs[inputNumber].getConnectionCount(); i++){
					double newValue = inputs[inputNumber].getValue() * toDecimal(inputWeights[inputNumber][inputs[inputNumber].getConnections(i)]);
					neurons[inputs[inputNumber].getConnections(i)].addValue(newValue);
					if(neurons[inputs[inputNumber].getConnections(i)].isActivated() == false){
						activatedNeurons[activatedCount] = neurons[inputs[inputNumber].getConnections(i)];
						activatedNeurons[activatedCount].setActivated(true);
						neurons[inputs[inputNumber].getConnections(i)].setActivated(true);
						//System.out.println("Neuron: " + activatedNeurons[activatedCount].getNum() + " " + time);
						activatedCount++;
					}
					
				}
				
        	}
        	
        	for(int i = 0; i < activatedCount; i++){
        		int num = i % 2;
                activatedNeurons = neuronActivated(activatedNeurons[i], activatedNeurons, i, num, time);
        		//System.out.println(activatedNeurons[i].getNum() + " " + i);
        	}
        	
        	Neuron[] activatedOutputs = new Neuron[outNum];
        	double maxValue = 0;
        	int maxNum = 0;
        	for(int i = 0; i < outNum + 2; i++){
        		if(i < outNum){
                    for(int u = 0; u < desiredOutput.length(); u++){
                        if(symbols.charAt(i) == desiredOutput.charAt(u)){
                            
                            neurons[i + colunmNum * rowNum].addTargetValue(10.0);
                        }
                    }
                }
                if(neurons[i + colunmNum * rowNum].isActivated() == true && neurons[i + colunmNum * rowNum].getValue() > maxValue){
        			if(i > outNum - 1){
                        stop = true;
                    }
                    else{
                        maxValue = neurons[i + colunmNum * rowNum].getValue();
                        maxNum = i;
                    	//answer = answer + symbols.charAt(i);
                        //System.out.println(answer);
                        System.out.println("Set max value!");
                        if(answer.length() > 1000){
                            stop = true;
                        }
                    }
        		}
        	}
        	if(maxNum != 0){
        		answer = answer + symbols.charAt(maxNum);
        		outputTime[outputTimeCount] = time;
        		outputTimeCount++;
        	}
        	time++;
            if(answer.length() > desiredOutput.length()){
                stop = true;
            }
        	
        }
        totalTime = time;
		return answer;
		

	}

	public Neuron[] neuronActivated(Neuron neuron, Neuron[] neuronArray, int activatedNum, int type, int time){
		int neuronPos = activatedNum;
		Neuron[] newNeuronArray = (Neuron[]) neuronArray.clone();
		//Tests if the neuron has anymore delay then releases a signal.
		if(neuron.getRemainingDelay() == 0 && neuron.isActivated() == true){
			//Gets the time the neuron sends an output signal.
			neurons[neuron.getNum()].addTime(time);
			for(int i = 0; i < neuron.getConnectionCount(); i++){
				double newValue = neuron.getValue() * toDecimal(weights[neuron.getNum()][neuron.getConnections(i)]);
				neurons[neuron.getConnections(i)].addValue(newValue);
				if(neurons[neuron.getConnections(i)].isActivated() == false && neurons[neuron.getConnections(i)].getNum() < colunmNum * rowNum){
					
					neurons[neuron.getConnections(i)].setActivated(true);
					newNeuronArray[activatedCount] = neurons[neuron.getConnections(i)];
					//System.out.println(neurons[neuron.getConnections(i)].getNum());
					activatedCount++;
					
				}
				if(neurons[neuron.getConnections(i)].getNum() > colunmNum * rowNum){
					neurons[neuron.getConnections(i)].setActivated(true);
					System.out.println("Output!!");
				}
			}
			newNeuronArray[neuronPos].setActivated(false);
			newNeuronArray = shiftArray(neuronPos, newNeuronArray);
			activatedCount--;
		}
		else if(neuron.isActivated() == true){
			neuron.delayTick();
			newNeuronArray[activatedNum] = neuron;
			neurons[neuron.getNum()] = neuron;
		}
		return newNeuronArray;
	}
	
	public int[] shiftArray(int num, int[] brainArray){
	    
        int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public Neuron[] shiftArray(int num, Neuron[] brainArray){
	    
        Neuron[] tempBrain = new Neuron[brainArray.length];
        tempBrain = (Neuron[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public int[] shiftArrayBack(int num, int[] brainArray){
		int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
            if(i == num){
                brainArray[i] = 0;
            }
            else{
                brainArray[i] = tempBrain[i - 1];
            }
        }
        
        return brainArray;
	}
    
    public void calculateScore(String response, String answer){
        
        int rScore = 0;
        for(int i = 0; i < response.length(); i++){
            if(i < answer.length()){
                if(answer.charAt(i) == response.charAt(i)){
                    rScore++;
                }
                else{
                    rScore--;
                }
            }
            else{
                rScore--;
            }
        }
        
        if(answer.length() > response.length()){
            rScore = rScore - (answer.length() - response.length());
        }
        
        this.score = rScore;
    }
    
    public void createWeights(int n1, int n2, double weight){
        weights[n1][n2] = toBinary(weight);
    }
	
}

class CompBrain implements java.io.Serializable{

	public int radius;

	double percent = 0;

	String symbols = "abcdefghijklmnopqrstuvwxyz;:',!?.()\"123456789 ";
	
	private int[] outputTime;
	private int outputTimeCount = 0;
    private int maxConnectionNum = 10;
    private int maxDelay = 20;
	private int divFunction = 8;
	private int divNeuron = 8;
	private int divPower = 8;
    private int divRotation = 2;
    
    int neuronChange1Count = 0;
    int neuronChange2Count = 0;
    
    Neuron[] activatedNeurons;
    int activatedCount = 0;

    int timeNum;
    
    boolean goOn;
    
	private String[][] weights;
    private String[] connections1;
    private String[] connections2;
    private String[][] inputWeights;
	private Neuron[] neurons;
	private String[] neuronFunction;
	private String[] neuronPower;
	private Neuron[] inputs;
    private Neuron[] neuronChange1;
    private Neuron[] neuronChange2;
    
    private Brain createdBrain;
    private String[] inputString;

	double dx = Math.random() * 638 + 2;
	double dy = Math.random() * 478 + 2;

	int score = 0;

	int divideNum = 1;
	int speedReduce = 1;

	int foodCount;
	int rowNum;
	int colunmNum;
	boolean outputActivated;

	double moveOut, rotationLeftOut, rotationRightOut;
	double[] outPuts;

	int outCNum;
    int outRNum;
    int outONum;
    int outINum;
    int connectionNum;
    int inputConnectionNum;
    int connectionsMade = 0;
    
	int x, y;
	double rotation = 0;

	public CompBrain(int rows, int columnNumber, int outRowNum, int outColNum, int outOutNum, int outInputNum,  boolean first, String[][] weight, int inputNum, Brain brain){
        
        createdBrain = brain;
        outCNum = outColNum;
        outRNum = outRowNum;
        outONum = outOutNum + 2;
        outINum = outInputNum;
		
        rowNum = rows;
		colunmNum = columnNumber;
		neurons = new Neuron[rowNum * colunmNum + outCNum * outRNum + outINum + outONum];
        weights = new String[rowNum * colunmNum + outCNum * outRNum + outINum + outONum][rowNum * colunmNum + outCNum * outRNum + outINum + outONum];
        
        inputWeights = new String[inputNum][columnNumber * rows];
        inputs = new Neuron[inputNum];
        
        neuronChange1 = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
        neuronChange2 = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
		
		activatedNeurons = new Neuron[colunmNum * rowNum];
        activatedCount = 0;
        
        for(int i = 0; i < rowNum * colunmNum + outCNum * outRNum + outINum + outONum; i++){
			neurons[i] = new Neuron(i, maxConnectionNum);
		}
        
		for(int i = 0; i < inputs.length; i++){
            inputs[i] = new Neuron(i, maxConnectionNum);
		}
        
		if(first == true){
			for(int i = 0; i < rowNum * colunmNum + outCNum * outRNum + outINum + outONum; i++){
				neurons[i].setDelay(Math.round((float)(5 + Math.random() * maxDelay)));
			}
			generateWeights();
		}		
	}
    
    private void setInputs(String[] inputStringArray){
        inputString = (String[]) inputStringArray.clone();
    }
    
	private void generateWeights(){
		
		connectionNum = 4000;//1000 + Math.round((float)(Math.random() * (maxConnectionNum * colunmNum * rowNum) / 1.5));
		inputConnectionNum = 400;//150 + Math.round((float)(Math.random() * (inputs.length * (maxConnectionNum - 5))));
		int usedConnections = 0;
        
        for(int i = 0; i < inputConnectionNum; i++){
            
            boolean goOn = false;
            while(goOn == false){
                int inputNeuron = Math.round((float)(Math.random() * (inputs.length - 1)));
                int neuron = Math.round((float)(Math.random() * (colunmNum * rowNum - 1)));
                
                double random = (double)(Math.random() * 16);
                double negativeRan = Math.random();
                if(negativeRan < 0.5){
                    random = random * -1;
                }
                
                if(inputs[inputNeuron].getConnectionCount() < maxConnectionNum){
                
                    inputWeights[inputNeuron][neuron] = toBinary(random);
                    inputs[inputNeuron].setConnections(neuron);
                    neurons[neuron].addInput(-inputNeuron);
                    goOn = true;
                    
                }
            }
        }
		
		for(int i = 0; i < rowNum; i++){
			for(int u = 0; u < connectionNum; u++){
				
                boolean goOn = false;
                while(goOn == false){
                    int neuron1 = Math.round((float)(Math.random() * (rowNum * colunmNum - 1)));
                    int neuron2 = Math.round((float)(Math.random() * (rowNum * colunmNum + outONum + outINum + outCNum * outRNum - 1)));

                    double random = (double)(Math.random() * 16);
                    double negativeRan = Math.random();
                    if(negativeRan < 0.5){
                        random = random * -1;
                    }
                    
				    if(weights[neuron1][neuron2] == null && neurons[neuron1].getConnectionCount() < maxConnectionNum){
					   weights[neuron1][neuron2] = toBinary(random);
					   neurons[neuron1].setConnections(neuron2);
					   neurons[neuron2].addInput(neuron1);
				
                       goOn = true;
				    }
                }
			}
		}
		
		for(int i = 0; i < rowNum * colunmNum; i++){
			//neurons[i].shrinkArray();
		}
	
	}

	public static String toBinary(double num){

		double dNum = Math.abs(num);
		String sNum = "" + dNum;
		String bNum = "";
		char ch = sNum.charAt(1);
		int nu = Character.getNumericValue(ch);

		if(nu == -1){

			for(int i = 0; i < sNum.length(); i++){

				char c = sNum.charAt(i);
				int iNum = Character.getNumericValue(c);

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}

		}
		else{
			int iNum = 0;
			for(int i = 0; i < sNum.length() - 1; i++){

				if(i == 0){
					char c1 = sNum.charAt(0);
					char c2 = sNum.charAt(1);
					String twoNum = "" + c1 + c2;
					iNum = Integer.parseInt(twoNum);
				}

				char c = sNum.charAt(i + 1);    

				if(i != 0){
					iNum = Character.getNumericValue(c);
				}

				for(int u = 0; u < 4; u++){

					if( iNum == -1){
						String binaryDec = ".";
						bNum = bNum + binaryDec;
						break;
					}
					else{
						int binaryNum = iNum % 2;

						if(binaryNum == 1){
							iNum = (iNum - 1) / 2;
						}
						else{
							iNum = iNum / 2;
						}

						bNum = bNum + binaryNum;
					}

				}
			}
		}

		if(num < 0){
			bNum = "-" + bNum;
		}
		else{
			bNum = "+" + bNum;
		}
		return bNum;
	}


	public static double toDecimal(String bNum){

		int convertedNum = 0;
		double finalNum = 0;
		String numString = "";

		for(int u = 1; u < (bNum.length()) / 4; u++){
			char c;
			convertedNum = 0;
			for(int i = 0; i < 4; i++){

				if(u != 0){
					c = bNum.charAt(1 + i + u * 4);
				}
				else{
					c = bNum.charAt(i + u * 4);
				}

				int num = Character.getNumericValue(c);

				if(num == 1){
					convertedNum = convertedNum + Math.round((float)Math.pow(2, Math.abs(i)));
				}

			}
			if(u == 1){
				numString = numString + convertedNum + ".";
			}
			else{
				numString = numString + convertedNum;
			}
		}

		//System.out.println(numString);

		finalNum = Double.parseDouble(numString);
		char nChar = bNum.charAt(0);
		if(nChar == '-'){
			finalNum = finalNum * -1;
		}
		return finalNum;

	}

	public double getPercent(){
		return percent;
	}

	public void setPercent(double newPercent){
		this.percent = newPercent;
	}

	public int getScore(){
		return score;
	}

	public String getWeights(int first, int second){
		if(weights[first][second] == null){
			return "null";
		}
		else{
			return weights[first][second];
		}
	}
	
	public Neuron getInputNeurons(int neuronNum){
		return inputs[neuronNum];
	}
	
	public Neuron getNeuron(int neuronNum){
		return neurons[neuronNum];
	}

	public void setWeights(int first, int second, String num){
		weights[first][second] = num;
	}
    
    public void setInputWeights(int first, int second, String num){
        inputWeights[first][second] = num;
    }

	public String getNeuronFunction(int num){
		return neuronFunction[num];
	}

	public void setNeuronFunction(int num, String s){
		neuronFunction[num] = s;
	}
    
    public String getInputWeights(int first, int second){
        if(inputWeights[first][second] == null){
            return "null";
        }
        else{
            return inputWeights[first][second];
        }
    }
    
    public Brain getBrain(){
        return createdBrain;
    }

	public void setAddedScore(int newScore){     
		this.score += newScore;  
	}

	public void setInputPercent(int neuronNum, double newPercent){
		inputs[neuronNum].setPercent(newPercent);
	}
	
	public void setNeuronPercent(int neuronNum, double newPercent){
		neurons[neuronNum].setPercent(newPercent);
	}
	
	public void setFoodCount(int newFoodCount){      
		this.foodCount = newFoodCount; 
	}
	
	public void setBenefit(int neuronNum, double newBenefit){
		neurons[neuronNum].setBenefit(newBenefit);
	}
	
	public void setInputBenefit(int neuronNum, double newBenefit){
		neurons[neuronNum].setBenefit(newBenefit);
	}
	
	public void setScore(int newScore){
		this.score = newScore;
	}
	public String getPower(int num){
		return neuronPower[num];
	}

	public void setPower(int num, String set){
		neuronPower[num] = set;
	}
	
	public void setNeuronConnections(int neuron1, int neuron2){
		neurons[neuron1].setConnections(neuron2);
	}
	
	public void setInputNeuronConnections(int neuron1, int neuron2){
		inputs[neuron1].setConnections(neuron2);
	}
	
	public void setNeuronDelay(int neuronNum, int delayNum){
		neurons[neuronNum].setDelay(delayNum);
	}
    
	public void calculateWeights(String[] inputArray){
		
		timeNum = 0;
		String[] inputValues = new String[inputArray.length];
        
        for(int i = 0; i < inputArray.length; i++){
            inputValues[i] = inputArray[i];
        }

		boolean stop = false;
		int time = 0;
        String answer = "";
		
        while(stop == false){
        	
        	Neuron[] newActivatedNeurons = new Neuron[colunmNum * rowNum];
        	if(time < inputValues.length){
                int inputNumber = 0;
				for(int i = 0; i < symbols.length(); i++){
					String test = "" + symbols.charAt(i);
					if(test.equalsIgnoreCase(inputValues[time])){
						inputNumber = i;
					}
				}
				
				for(int i = 0; i < inputs[inputNumber].getConnectionCount(); i++){
					double newValue = inputs[inputNumber].getValue() * toDecimal(inputWeights[inputNumber][inputs[inputNumber].getConnections(i)]);
					neurons[inputs[inputNumber].getConnections(i)].addValue(newValue);
					if(neurons[inputs[inputNumber].getConnections(i)].isActivated() == false){
						activatedNeurons[activatedCount] = neurons[inputs[inputNumber].getConnections(i)];
						activatedNeurons[activatedCount].setActivated(true);
						neurons[inputs[inputNumber].getConnections(i)].setActivated(true);
						//System.out.println("Neuron: " + activatedNeurons[activatedCount].getNum() + " " + time);
						activatedCount++;
					}
					
				}
				
        	}
        	
        	for(int i = 0; i < activatedCount; i++){
                activatedNeurons = neuronActivated(activatedNeurons[i], activatedNeurons, i, i, time);
        		//System.out.println(activatedNeurons[i].getNum() + " " + i);
        	}
        	
        	//Neuron[] activatedOutputs = new Neuron[outNum];

        	time++;
        	//System.out.println(time);
            if(time == 1000){
                stop = true;
            }
        }
        
	}

	public Neuron[] neuronActivated(Neuron neuron, Neuron[] neuronArray, int activatedNum, int time, int totalTime){
		int neuronPos = activatedNum;
		
		if(time == 0){
			outputActivated = false;
			goOn = false;
		}
		Neuron[] newNeuronArray = (Neuron[]) neuronArray.clone();
		//Tests if the neuron has any delay left, and if it doesn't, it releases a signal.
		if(neuron.getRemainingDelay() == 0 && neuron.isActivated() == true){
			//Records the time the neuron sent an output signal.
			neurons[neuron.getNum()].addTime(time);
			for(int i = 0; i < neuron.getConnectionCount() - 1; i++){

            double newValue = neuron.getValue() * toDecimal(weights[neuron.getNum()][neuron.getConnections(i)]);
				neurons[neuron.getConnections(i)].addValue(newValue);
				if(neurons[neuron.getConnections(i)].isActivated() == false && neurons[neuron.getConnections(i)].getNum() < colunmNum * rowNum){
					
					neurons[neuron.getConnections(i)].setActivated(true);
					newNeuronArray[activatedCount] = neurons[neuron.getConnections(i)];
					//System.out.println(neurons[neuron.getConnections(i)].getNum());
					activatedCount++;
					//System.out.println("Activated: " + activatedCount);
					
				}
				
				if(neurons[neuron.getConnections(i)].getNum() > colunmNum * rowNum && neurons[neuron.getConnections(i)].isActivated() == false){
					//System.out.println("Output Activated " + timeNum + " " + totalTime + " " + neuronChange1Count + " " + neuronChange2Count);
					//This sets a neuron in the first array that needs to be changed.
					if(neuronChange1[neuronChange1Count] == null && timeNum == 0 && neurons[neuron.getConnections(i)].isActivated() == false){
                        neuronChange1[neuronChange1Count] = neurons[neuron.getConnections(i)];
                        neurons[neuron.getConnections(i)].setActivated(true);
                        neuronChange1Count++;
                        //System.out.println("Output1! " + connectionsMade);
                        //System.out.println(neuron.getConnections(i));
                    }
					//This sets a neuron in the second array that needs to be changed. These will be ranked later to see how they line up.
                    else if(neuronChange1[neuronChange2Count] != null && timeNum == 1 && neurons[neuron.getConnections(i)].isActivated() == false){
                        neuronChange2[neuronChange2Count] = neurons[neuron.getConnections(i)];
                        neurons[neuron.getConnections(i)].setActivated(true);
                        neuronChange2Count++;
                        connectionsMade++;
                        //System.out.println(neuron.getConnections(i));
                        //System.out.println("Output2! " + connectionsMade);
                    }
                    else if(timeNum == 1 && neurons[neuron.getConnections(i)].isActivated() == false){
                        neuronChange1[neuronChange2Count] = neurons[neuron.getConnections(i)];
                        neurons[neuron.getConnections(i)].setActivated(true);
                        neuronChange2Count++;
                    }
					
					if(neuronChange1Count == neuronChange2Count){
                    	goOn = true;
                    	
                    }
                    outputActivated = true;
				}
			}
			newNeuronArray[neuronPos].setActivated(false);
			newNeuronArray = shiftArray(neuronPos, newNeuronArray);
			activatedCount--;
		}
		else if(neuron.isActivated() == true){
			neuron.delayTick();
			newNeuronArray[activatedNum] = neuron;
			neurons[neuron.getNum()] = neuron;
		}
        
        if(goOn == true){
            //Rank neurons from highest to lowest to determine what happens first
            Neuron[] topNeurons = new Neuron[neuronChange2Count];
            for(int i = 0; i < neuronChange2Count; i++){
                for(int u = 0; u < neuronChange2Count; u++){
                
                    if(i == 0){
                        topNeurons[i] = neuronChange1[i];
                        break;
                    }
                
                    if(topNeurons[Math.abs(u - neuronChange2Count) - 1] != null){
                	   if(neuronChange1[i].getValue() < topNeurons[Math.abs(u - neuronChange2Count) - 1].getValue()){
                           int newPlace = Math.abs(u - neuronChange2Count);
                           topNeurons = (Neuron[]) shiftArray(newPlace, topNeurons).clone();
                           topNeurons[Math.abs(u - neuronChange2Count)] = neuronChange1[i];
                           break;
                        }
                        else{
                    	   if(u == neuronChange2Count - 1){
                               topNeurons = (Neuron[]) shiftArray(0, topNeurons).clone();
                               topNeurons[0] = neuronChange1[i];
                            }
                        }
                    }
                }
            }
            
            Neuron[] topNeurons2 = new Neuron[neuronChange2Count];
            for(int i = 0; i < neuronChange2Count; i++){
                for(int u = 0; u < neuronChange2Count; u++){
                
                    if(i == 0){
                        topNeurons2[i] = neuronChange2[i];
                        break;
                    }
                
                    if(topNeurons[Math.abs(u - neuronChange2Count) - 1] != null){
                	   if(neuronChange1[i].getValue() < topNeurons2[Math.abs(u - neuronChange2Count) - 1].getValue()){
                           int newPlace = Math.abs(u - neuronChange2Count);
                           topNeurons2 = (Neuron[]) shiftArray(newPlace, topNeurons2).clone();
                           topNeurons2[Math.abs(u - neuronChange2Count)] = neuronChange2[i];
                           break;
                        }
                        else{
                    	   if(u == neuronChange2Count - 1){
                               topNeurons2 = (Neuron[]) shiftArray(0, topNeurons).clone();
                               topNeurons2[0] = neuronChange2[i];
                            }
                        }
                    }
                }
            }
            //Actually sets the connections in the other brain
            int tot = rowNum * colunmNum;
            for(int i = 0; i < neuronChange1Count; i++){
                if(neuronChange1[i].getNum() - tot < outINum && neuronChange2[i].getNum() - tot > outINum){
                  createdBrain.setInputConnections(neuronChange1[i].getNum() - tot, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                }
                else if(neuronChange2[i].getNum() - tot < outINum && neuronChange1[i].getNum() - tot > outINum){
                  createdBrain.setInputConnections(neuronChange2[i].getNum() - tot, neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getValue(), neuronChange1[i].getValue());
                }
                else if(neuronChange1[i].getNum() - tot > outRNum * outCNum && neuronChange2[i].getNum() - tot < outRNum * outCNum){
                  if(neuronChange2[i].getNum() - tot - outINum < 0){
                     createdBrain.setNeuronConnections(neuronChange2[i].getNum() - tot, neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getValue(), neuronChange1[i].getValue());
                  }
                  else{
                     createdBrain.setNeuronConnections(neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getValue(), neuronChange1[i].getValue());
                  }
                }
                else if(neuronChange2[i].getNum() - tot > outRNum * outCNum && neuronChange1[i].getNum() - tot < outRNum * outCNum){
                  if(neuronChange1[i].getNum() - tot - outINum < 0){
                     createdBrain.setNeuronConnections(neuronChange1[i].getNum() - tot, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                  }
                  else{
                     createdBrain.setNeuronConnections(neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                  }
                }
                else if(neuronChange1[i].getNum() - tot > outINum && neuronChange1[i].getNum() - tot < outCNum * outRNum && neuronChange2[i].getNum() - tot > outINum && neuronChange2[i].getNum() - tot < outCNum * outRNum){
                  createdBrain.setNeuronConnections(neuronChange1[i].getNum() - tot - outINum, neuronChange2[i].getNum() - tot - outINum, neuronChange1[i].getValue(), neuronChange2[i].getValue());
                }
                neurons[neuronChange1[i].getNum()].setActivated(false);
                neurons[neuronChange2[i].getNum()].setActivated(false);
            }
            
            Neuron[] tempNeuron = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
            for(int i = 0; i < neuronChange2Count - neuronChange1Count; i++){
                tempNeuron[i] = neuronChange1[neuronChange1Count + i];
            }
            
            neuronChange1 = (Neuron[]) tempNeuron.clone();
            neuronChange2 = new Neuron[(rowNum * colunmNum + outCNum * outRNum + outINum + outONum)];
            neuronChange1Count = neuronChange2Count - neuronChange1Count;
            neuronChange2Count = 0;
            timeNum = 0;
            goOn = false;
            outputActivated = false;
        }
        else if(timeNum == 0 && outputActivated == true && time == activatedCount - 1 && goOn == false){
        	timeNum = 1;
        }
        
		return newNeuronArray;
	}
	
	
	public int[] shiftArray(int num, int[] brainArray){
	    
        int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public Neuron[] shiftArray(int num, Neuron[] brainArray){
	    
        Neuron[] tempBrain = new Neuron[brainArray.length];
        tempBrain = (Neuron[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
                brainArray[i] = tempBrain[i + 1];
        } 
        
        return brainArray;
    
    }
	
	public int[] shiftArrayBack(int num, int[] brainArray){
		int[] tempBrain = new int[brainArray.length];
        tempBrain = (int[]) brainArray.clone();
        
        for(int i = num; i < brainArray.length - 1; i++){
            if(i == num){
                brainArray[i] = 0;
            }
            else{
                brainArray[i] = tempBrain[i - 1];
            }
        }
        
        return brainArray;
	}
    
    public int score(String response, String answer){
        return 0;
    }
	
}

class Shapes implements java.io.Serializable{

	int x;
	int y;
	String type;

	public Shapes(){

	}

	public String getType(){		
		return type;
	}

	public int getX(){
		return x;
	}

	public int getY(){
		return y;
	}

}

class Circle extends Shapes implements java.io.Serializable{

	int radius;

	public Circle(int radius, int x, int y){

		this.x = x;
		this.y = y;
		this.radius = radius;
		this.type = "Circle";

	}

	public int getRadius(){
		return this.radius;
	}

}

class Square extends Shapes implements java.io.Serializable{

	int height;
	int width;

	public Square(int height, int width, int x, int y){

		this.x = x;
		this.y = y;
		this.height = height;
		this.width = width;
		this.type = "Square";

	}

	public String getType(){
		return type;
	}

	public int getHeight(){
		return this.height;
	}

	public int getWidth(){
		return this.width;
	}

}

class Neuron implements java.io.Serializable{
	
	int[] timesActivated;
    double[] targetValues;
    int alreadyActivated = 0;
    int outputNum = ReccurentNeuralNet.outNum;
    double[] netValues;
	boolean[] alreadyChecked;
    int[][] dValues;
    int[] timeLeft;
	int timeCount = 0;
    int delayAmount = 0;
    int delayRemaining = 0;
	int num;
	int[] connections;
	int[] inputs;
	int inputCount;
	double value;
	int length;
	int finalConnections = 0;
	boolean isActivated = false;
	int subject;
	double benefit = 0;
	double percent = 0;
    double dValuePassed = 0;
    int timesLeft;
	
	public Neuron(int number, int connectionCount){
		num = number;
		value = 0;
		connections = new int[connectionCount];
		inputs = new int[100];
		inputCount = 0;
		timesActivated = new int[5];
        netValues = new double[5];
        targetValues = new double[5];
		alreadyChecked = new boolean[5];
        
        //I don't know why I did this.
        //timesLeft = new int[outputNum];
        timesLeft = 0;
	}
	
	public int getNum(){
		return num;
	}
	public int getConnections(int i){
		return connections[i];
	}
	public double getValue(){
		return value;
	}
    public double getOutput(){
        return (1 /(1 + Math.exp(-value)));
    }
	public int getLength(){
		return length;
	}
	public int getConnectionCount(){
		return finalConnections;
	}
    public int getDelay(){
        return delayAmount;
    }
    public int getRemainingDelay(){
    	return delayRemaining;
    }
    public boolean isActivated(){
    	return isActivated;
    }
    public int getSubject(){
    	return subject;
    }
    public double getBenefit(){
    	return benefit;
    }
    public double getPercent(){
    	return percent;
    }
    public int getInputs(int neuronCount){
    	return inputs[neuronCount];
    }
    public int getInputCount(){
        return inputCount;
    }
    public double getKeepValue(int i){
        return dValues[i][timesLeft];
    }
    public int getTimes(int timeCounts){
    	return timesActivated[timeCount - 1 - timeCounts];
    }
    public double getNetValues(int valueCount){
        return netValues[timeCount - 1 - valueCount];
    }
    public double getOutputValues(int valueCount){
        return 1 / (1 + Math.exp(netValues[timeCount - 1 - valueCount]));
    }
    public int getTimeCount(){
        return timeCount;
    }
    public boolean getChecked(int checkNum){
    	return alreadyChecked[checkNum];
    }
    public double getTargetValueAt(int time){
        for(int i = 0; i < timeCount; i++){
            if(time == timesActivated[i]){
                if(targetValues[i] == 0){
                    return 0;
                }
                else{
                    return targetValues[i];
                }
            }
        }
        return 0;
    }
    public boolean getIfFinished(){
        if(alreadyActivated == inputCount){
            return true;
        }
        else{
            return false;
        }
    }
    public double getDValuePassed(){
        return dValuePassed;
    }
    public double getOutputValueAt(int time){
        for(int i = 0; i < timeCount; i++){
            if(time == timesActivated[i]){
                return 1 / (1 + Math.exp(netValues[i]));
            }
        }
        System.out.println("No value found at time " + time);
        return 0;
    }
    
    public void addValue(double newValue){
        value += newValue;
    }
    public void addInput(int neuronNum){
    	inputs[inputCount] = neuronNum;
    	inputCount++;
    	if(inputCount >= inputs.length){
    		int[] temp = new int[inputCount + 2];
    		for(int i = 0; i < inputs.length; i++){
    			temp[i] = inputs[i];
    		}
    		inputs = temp;
    		temp = null;
    		alreadyChecked = new boolean[inputs.length];
    	}
    }
    public void addTime(int timeNum){
    	timesActivated[timeCount] = timeNum;
        netValues[timeCount] = this.value;
    	timeCount++;
        timesLeft = timeCount;
    	if(timeCount >= timesActivated.length){
    		int[] temp = new int[timeCount + 2];
            double[] vTemp = new double[timeCount + 2];
            double[] tvTemp = new double[timeCount + 2];
            dValues = new int[outputNum][timeCount + 2];
    		for(int i = 0; i < timesActivated.length; i++){
    			temp[i] = timesActivated[i];
                vTemp[i] = netValues[i];
                tvTemp[i] = targetValues[i];
    		}
    		timesActivated = temp;
            netValues = vTemp;
            targetValues = tvTemp;
    		temp = null;
            vTemp = null;
            tvTemp = null;
    	}
    }
	
    public void addActivated(){
        timeCount++;
    }
    
	public void setConnections(int neuronNum){
		connections[finalConnections] = neuronNum;
      if(finalConnections < connections.length - 1){
         finalConnections++;
      }
 
	}
	public void setValue(double newValue){
		value = newValue;
	}
	public void setLength(int newLength){
		length = newLength;
	}
	public void setDelay(int newDelay){
        delayAmount = newDelay;
    }
    public void setActivated(boolean newState){
    	isActivated = newState;
    	if(newState == true){
    		delayRemaining = delayAmount;
    	}
    }
    public void setKeepValue(int oNum, int keepValue, int time){
        if(time == timesActivated[timesLeft]){
            timesLeft--;
            dValues[oNum][timesLeft + 1] = keepValue;
            //return keepValue;    
        }
        else{
            dValues[oNum][timesLeft] = keepValue;
        }
        //timesLeft--;
    }
    public void setSubject(int newSubject){
    	subject = newSubject;
    }
    public void setBenefit(double newBenefit){
    	benefit = newBenefit;
    }
    public void setPercent(double newPercent){
    	percent = newPercent;
    }
    public void setDValuePassed(double newDNet){
        dValuePassed = newDNet;
    }
    public void addTargetValue(double value){
        targetValues[timeCount] = value;
    }
	
	public void shrinkArray(){
		
		int[] tempConnections = new int[finalConnections];
		for(int i = 0; i < finalConnections - 1; i++){
			tempConnections[i] = connections[i];
		}
		connections = null;
		connections = new int[finalConnections];
		System.arraycopy(tempConnections, 0, connections, 0, tempConnections.length);
		this.setLength(connections.length);
		
	}
    
    public boolean checkConnection(int connectedTo){
        for(int i = 0; i < finalConnections; i++){
            if(connections[i] == connectedTo){
                return true;
            }
        }
        return false;
    }
    
    public void delayTick(){
        if(delayRemaining != 0){
            delayRemaining = delayRemaining - 1;
        }
    }
    
    public void setChecked(int checkNum, boolean state){
    	alreadyChecked[checkNum] = state;
    }
	
}

class Memory implements java.io.Serializable{
    
    String mem;
    int num;
    
    public Memory(String memory, int number){
        mem = memory;
        num = number;
    }
    
    public String getMemory(){
        return mem;
    }
    
    public void setMemory(String newMemory){
        mem = newMemory;
    }

}


    

To learn more HTML/CSS, check out these tutorials!