Here's a Neural Network(A.K.A an artificial brain)

The little circles learn over time how to move around and collect food. This essentially is a simple artificial intelligence. I am constantly updating/modifying the code.

      
      
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.*;

public class NeuralNetwork extends JPanel{

	Timer timer;
	int speed = 2;

	public static Circle[] foodArray;
	public static Circle base;

	public static int rNum = 2;
	public static int cNum = 5;
	public static int inNum = 2;
	public static int outNum = 3;

	public static int foodNum = 20;
	public static int brainNum = 20;

	static Brain[] brains;

	int count = 0;
	int maxCount = 15000;

	int genNum = 0;

	public void paintComponent(Graphics g){

		super.paintComponent(g);

		//g.drawOval(base.getX(), base.getY(), base.getRadius() * 2, base.getRadius() * 2);
		double radFov = (20 * Math.PI) / 180;

		for(int i = 0; i < brains.length; i++){
			g.drawOval(brains[i].getX(), brains[i].getY(), brains[i].radius * 2, brains[i].radius * 2);

			g.drawLine(brains[i].getX() + brains[i].radius, brains[i].getY() + brains[i].radius, brains[i].getX() + brains[i].radius + Math.round((float)(Math.cos(brains[i].rotation)) * 4), brains[i].getY() + brains[i].radius - Math.round((float)(Math.sin(brains[i].rotation)) * 4));
			//g.drawLine(brains[i].getX() + brains[i].radius, brains[i].getY() + brains[i].radius, brains[i].getX() + brains[i].radius + Math.round((float)(Math.cos(brains[i].rotation - radFov)) * 1000), brains[i].getY() + brains[i].radius - Math.round((float)(Math.sin(brains[i].rotation - radFov)) * 1000));

		}

		for(int i = 0; i < foodArray.length; i++){
			g.drawOval(foodArray[i].getX(), foodArray[i].getY(), foodArray[i].getRadius() * 2, foodArray[i].getRadius() * 2);
		}


	}

	public static void main(String[] args){

		brains = new Brain[brainNum];
		foodArray = new Circle[foodNum];
		base = new Circle(40, (640 / 2) - 40, (480 / 2) - 40);

		for(int i = 0; i < foodNum; i++){

			foodArray[i] = new Circle(10, (int)Math.round(Math.random() * 640), (int)Math.round(Math.random() * 480));

		}       
		for(int i = 0; i < brainNum; i++){

			String[][] newWeights = new String[rNum][cNum * cNum];
			brains[i] = new Brain(rNum, cNum, true, newWeights, 5);

		}

		NeuralNetwork content = new NeuralNetwork();
		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++;
			double[] inputArray = new double[inNum];
			double smallestFood = 800;
			double newFood = 0;
			int smallNum = 0;

			if(count > maxCount){
				createNextGen();
				count = 0;
				genNum++;
				System.out.println("Generation: " + genNum);
			}

			for(int i = 0; i < brainNum; i++){

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

					newFood = brains[i].canSee(foodArray[u], 40);

					if(newFood < smallestFood){
						smallestFood = newFood;
						smallNum = u;
					}
					//Tests if food can be eaten
					int eatTest = brains[i].getDistance(foodArray[u]);

					if(eatTest < 16 && brains[i].getFoodCount() < 100000){

						foodArray[u] = new Circle(10, (int)Math.round(Math.random() * 640), (int)Math.round(Math.random() * 480));
						brains[i].setAddedScore(1);
						brains[i].setFoodCount(brains[i].getFoodCount() + 1);

					}
				}

				inputArray[0] = Math.abs((double)(brains[i].canSee(foodArray[smallNum], 40) - 800) / 800);
				//System.out.println(inputArray[0]);
				
				/*
				if(brains[i].getDistance(base) < 45 && brains[i].getFoodCount() > 4){
					System.out.println("Dropped off food");
					int scoreAdded = 2 * brains[i].getFoodCount();
					brains[i].setAddedScore(scoreAdded);
					brains[i].setFoodCount(0);

				}
				*/
				
				//inputArray[1] = Math.abs((double)(brains[i].canSee(base, 40) - 800) / 800);
				
				/*
				if(brains[i].getFoodCount() > 4){
					inputArray[2] = 1;
				}
				else{
					inputArray[2] = 0;
				}
				*/
				if(inputArray[0] <= 0 ){
					inputArray[1] = 1.0;
				}
				else{
					inputArray[1] = 0;
				}

				brains[i].calculateWeights(inputArray);
				brains[i].calculateMovement();
			}

			repaint();
		}

	}

	public NeuralNetwork(){

		timer = new Timer();
		timer.schedule(new Task(), 0, speed);

	}

	public Brain breedBrains(Brain brain1, Brain brain2){

		Brain newBrain = new Brain(rNum, cNum, false, new String[rNum][cNum * cNum], 5);
		String newGene = "";
		for(int i = 0; i < rNum; i++){
			for(int u = 0; u < cNum * cNum; u++){
				newGene = "";
				int crossoverPoint = Math.round((float)(Math.random() * 14));
				for(int z = 1; z < 14; z++){

					double random = Math.random();
					double mutation = Math.random();

					if(z == 1){
						if(random > .5){
							newGene = newGene + brain1.getWeights(i, u).charAt(0);
						}
						else{
							newGene = newGene + brain2.getWeights(i, u).charAt(0);
						}
					}

					if(random > .5 && Character.getNumericValue(brain1.getWeights(i, u).charAt(z)) != -1){

						if(mutation < .2){
							if(Character.getNumericValue(brain1.getWeights(i, u).charAt(z)) == 1){
								newGene = newGene + "0";
							}
							else{
								newGene = newGene + "1";
							}
						}
						else{
							newGene = newGene + brain1.getWeights(i, u).charAt(z);
						}

					}
					else if(random <= .5 && Character.getNumericValue(brain1.getWeights(i, u).charAt(z)) != -1){

						if(mutation < .2){
							if(Character.getNumericValue(brain2.getWeights(i, u).charAt(z)) == 1){
								newGene = newGene + "0";
							}
							else{
								newGene = newGene + "1";
							}
						}
						else{
							newGene = newGene + brain2.getWeights(i, u).charAt(z);
						}

					}
					else{
						newGene = newGene + ".";
					}
				}

				newBrain.setWeights(i, u, newGene);
			}
		}


		for(int i = 0; i < rNum * cNum + outNum; i++){
			String newFunction = "";
			for(int u = 1; u < 14; u++){

				if(u == 1){

					double negativeRan = Math.random();
					if(negativeRan < .5){
						newFunction = "" + brain1.getNeuronFunction(i).charAt(0);
					}
					else{
						newFunction = "" + brain2.getNeuronFunction(i).charAt(0);
					}

				}

				double random = Math.random();
				if(random < .5 && Character.getNumericValue(brain1.getNeuronFunction(i).charAt(u)) != -1){
					newFunction = newFunction + brain1.getNeuronFunction(i).charAt(u);
				}
				else if(random >= .5  && Character.getNumericValue(brain2.getNeuronFunction(i).charAt(u)) != -1){
					newFunction = newFunction + brain2.getNeuronFunction(i).charAt(u);
				}
				else{
					newFunction = newFunction + ".";
				}
			}
			newBrain.setNeuronFunction(i, newFunction);
		}

		for(int i = 0; i < rNum * cNum + outNum; i++){
			String newPower = "";
			for(int u = 1; u < 14; u++){

				if(u == 1){

					newPower = newPower + "+";

				}

				double random = Math.random();
				if(random < .5 && Character.getNumericValue(brain1.getPower(i).charAt(u)) != -1){
					newPower = newPower + brain1.getPower(i).charAt(u);
				}
				else if(random >= .5  && Character.getNumericValue(brain2.getPower(i).charAt(u)) != -1){
					newPower = newPower + brain2.getPower(i).charAt(u);
				}
				else{
					newPower = newPower+ ".";
				}
			}
			newBrain.setPower(i, newPower);
		}

		return newBrain;

	}

	public void createNextGen(){

		double totalScore = 0;
		for(int i = 0; i < brainNum; i++){
			totalScore += brains[i].getScore();
		}
		for(int i = 0; i < brainNum; i++){
			brains[i].setPercent((brains[i].getScore() / totalScore) * 100);

		}

		int comScore = 0;

		for(int i = 0; i < brainNum; i++){    		
			comScore += brains[i].getPercent();
			brains[i].setPercent(brains[i].getPercent() + comScore);

		}

		boolean done = false;
		boolean done1 = false;
		Brain chosenBrain1 = null;
		Brain chosenBrain2 = null;

		Brain[] newBrainList = new Brain[brainNum];

		for(int z = 0; z < brainNum; z++){

			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 = brains[i];
							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 = brains[i];
						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 = brains[i];
								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 = brains[i];
							System.out.println("Brain 2: " + i);
							System.out.println("Score: " + chosenBrain2.getScore());
							done = true;
							break;
						}
					}
				}

			}

			newBrainList[z] = breedBrains(chosenBrain1, chosenBrain2);

		}


		for(int i = 0; i < brainNum; i++){
			brains[i] = newBrainList[i];
		}

	}

}


class Brain{

	public int radius;

	double percent = 0;


	private int divFunction = 8;
	private int divNeuron = 8;
	private int divPower = 8;

	private String[][] weights;
	private double[] neurons;
	private String[] neuronFunction;
	private String[] neuronPower;

	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 = 3;

	int x, y;
	double rotation = 0;

	public Brain(int rows, int columnNumber, boolean first, String[][] weight, int bRadius){

		weights = new String[rows][columnNumber * columnNumber];

		radius = bRadius;
		System.arraycopy(weight, 0, weights, 0, weight.length);
		rowNum = rows;
		colunmNum = columnNumber;
		neurons = new double[rowNum * colunmNum];
		neuronFunction = new String[neurons.length + NeuralNetwork.outNum];
		neuronPower = new String[neuronFunction.length];
		outPuts = new double[outNum];

		x = 100;
		y = 100;

		if(first == true){
			generateWeights();
		}

	}

	private void generateWeights(){

		for(int i = 0; i < rowNum; i++){
			for(int u = 0; u < colunmNum * colunmNum; u++){

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

			}
		}

		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 void setPercent(double newPercent){
		this.percent = newPercent;
	}

	public int getScore(){
		return score;
	}

	public String getWeights(int first, int second){
		return weights[first][second];
	}

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

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

	public void setNeuronFunction(int num, String s){
		neuronFunction[num] = s;
	}

	public int getX(){
		return this.x;
	}

	public int getY(){
		return this.y;
	}

	public int getFoodCount(){
		return foodCount;
	}

	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 calculateWeights(double[] inputArray){

		double[] inputs = new double[inputArray.length];

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

		System.arraycopy(inputArray, 0, inputs, 0, inputArray.length);

		int cNum = 0;
		for(int i = 0; i < rowNum; i++){
			for(int u = 0; u < colunmNum * colunmNum; u++){

				if(i == 0){

					if(u >= NeuralNetwork.inNum * colunmNum){
						break;
					}
					cNum = (int)Math.round((float)(u / NeuralNetwork.inNum));
					neurons[cNum] += toDecimal(weights[i][u]) / divNeuron * inputs[u % NeuralNetwork.inNum];
				}
				else{

					cNum = (int)Math.floor((float)(u / colunmNum));
					neurons[cNum + i * colunmNum] = neurons[cNum + i * colunmNum] + toDecimal(weights[i][u]) / divNeuron * neurons[u % colunmNum + (i - 1) * colunmNum];                 

				}          

			}

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

				//neurons[u + i * colunmNum] = 1 / (1 + Math.pow(2.7, -neurons[u + i * colunmNum]));


				if(neurons[u + i * colunmNum] > toDecimal(neuronFunction[u + i * colunmNum]) / divFunction){
					neurons[u + i * colunmNum] = 1 / (1 + Math.pow(2.7, -neurons[u + i * colunmNum]));
				}
				else{
					neurons[u + i * colunmNum] = 0;
				}

				/*
       		if(neurons[u + i * colunmNum] > toDecimal(neuronFunction[u + i * colunmNum]) / divFunction){
       			neurons[u + i * colunmNum] = toDecimal(neuronPower[u + i * colunmNum]) / divPower;
       		}
       		else{
       			neurons[u + i * colunmNum] = 0;
       		}
				 */
				//System.out.println("Neuron " + (u + i * colunmNum) + ": " + neurons[u + i * colunmNum]);
			}
		}

		for(int u = 0; u < colunmNum * outNum; u++){

			cNum = (int)Math.floor((float)(u / colunmNum));            
			this.outPuts[cNum] += (toDecimal(weights[rowNum - 1][u])) / 8 * neurons[u % colunmNum + colunmNum * (rowNum - 1)];
			//this.outPuts[cNum] = this.outPuts[cNum] / colunmNum; 

		}
		for(int u = 0; u < outNum; u++){

			//this.outPuts[u] = 1 / (1 + Math.pow(2.7, -this.outPuts[u]));  	

			if(this.outPuts[u] > toDecimal(neuronFunction[neurons.length + u]) / divFunction){
				this.outPuts[u] =  1 / (1 + Math.pow(2.7, -this.outPuts[u]));
			}
			else{
				this.outPuts[u] = 0;
			}

			/*
   		if(this.outPuts[u] > toDecimal(neuronFunction[neurons.length + u]) / divFunction){
   			this.outPuts[u] =  toDecimal(neuronPower[neurons.length + u]) / divPower;
   		}
   		else{
   			this.outPuts[u] = 0;
   		}
			 */
		}

		//System.out.println("Output 1: " + outPuts[1]);
		//System.out.println("Output 2: " + outPuts[2]);

	}

	public void calculateMovement(){

		rotation += (this.outPuts[1] - this.outPuts[2]) / 2;

		if(rotation > 2 * Math.PI){
			rotation = 0;
		}
		if(rotation < 0){
			rotation = 2 * Math.PI;
		}

		double xVec = Math.cos(rotation) * this.outPuts[0];
		double yVec = -Math.sin(rotation) * this.outPuts[0];

		dx = dx + (double)(xVec / speedReduce);
		dy = dy + (double)(yVec / speedReduce);

		if(dx > 640){
			dx = (double)4;
		}
		if(dy > 480){
			dy = (double)4;
		}
		if(dx < 0){
			dx = (double)636;
		}
		if(dy < 0){
			dy = (double)476;
		}

		x = (int)dx;
		y = (int)dy;

	}

	public int canSee(Shapes object, int fov){

		double shapeX, shapeY;

		if(object.getType().equals("Circle")){

			Circle objectC = (Circle)object;

			shapeX = (object.getX() + Math.round(objectC.getRadius())) - (this.x - this.radius);
			shapeY = (this.y + this.radius) - (object.getY() + Math.round(objectC.getRadius()));

			double newAngle = Math.atan(shapeY / shapeX);
			if(shapeX < 0){

				if(shapeY < 0){
					newAngle = newAngle - Math.PI;
				}
				else{
					newAngle = newAngle + Math.PI;
				}

			}

			if(newAngle < 0){
				newAngle = newAngle + (2 * Math.PI);
			}

			if(Math.abs(newAngle - rotation) < (fov * Math.PI / 360)){
				return this.getDistance(object);
			}
			else if(Math.abs(newAngle - rotation) > (2 * Math.PI) - (fov * Math.PI / 360)){
				return this.getDistance(object);
			}

		}
		else if(object.getType().equals("Square")){

			Square objectS = (Square)object;
			shapeX = (object.getX() - Math.round(objectS.getWidth() / 2)) - this.x;
			shapeY = this.y - (object.getY() - Math.round(objectS.getHeight() / 2));

			double newAngle = Math.atan(shapeY / shapeX);

			if(shapeX < 0){

				if(shapeY < 0){
					newAngle = newAngle + Math.PI / 2;
				}
				else{
					newAngle = newAngle - Math.PI / 2;
				}

			}
		}

		return 800;

	}

	public int getDistance(Shapes object){

		int distance = 0;

		if(object.getType().equals("Circle")){

			distance = Math.round((float)Math.sqrt(Math.pow((double)(object.getX() + 
					((Circle)object).getRadius()) - (this.x + this.radius), 2.0) + Math.pow((double)(object.getY() + ((Circle)object).getRadius()) - (this.y + this.radius), 2.0)));

		}
		else if(object.getType().equals("Square")){
			distance = (int) Math.round(Math.sqrt(Math.pow((double)(object.getX() + ((Square) object).getWidth() / 2) - this.x, 2.0) + Math.pow((double)(object.getY() + ((Square) object).getHeight() / 2) - this.y, 2.0)));
		}


		return distance;
	}


}

class Shapes{

	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{

	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{

	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;
	}

}



  
  
      
    

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