package example.prime_number_guesser; /** Copyright (C) 2017 Zombie_Striker This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. **/ import java.util.HashMap; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import me.zombie_striker.neuralnetwork.*; import me.zombie_striker.neuralnetwork.neurons.BiasNeuron; import me.zombie_striker.neuralnetwork.neurons.Neuron; import me.zombie_striker.neuralnetwork.neurons.input.InputNumberNeuron; import me.zombie_striker.neuralnetwork.senses.Sensory2D_Numbers; import me.zombie_striker.neuralnetwork.util.DeepReinforcementUtil; public class PrimeNumberBot extends NNBaseEntity implements Controler { public Sensory2D_Numbers binary = new Sensory2D_Numbers(2, 10); public boolean wasCorrect = true; public HashMap<Integer, Boolean> ifNumberIsPrime = new HashMap<>(); public PrimeNumberBot(boolean createAI) { super(false, 2000); // We want to store the last 2000 entries, so we know how accurate it is. initValidPrimes(); // this.senses.add(binary); if (createAI) { this.ai = NNAI.generateAI(this, 1, 5, "is A Prime"); for (int trueOrFalse = 0; trueOrFalse < 1; trueOrFalse++) { // Change 1 to 2 if you also want to include if bit is false for (int binaryIndex = 0; binaryIndex < 10; binaryIndex++) { InputNumberNeuron.generateNeuronStatically(ai, trueOrFalse, binaryIndex, this.binary); } } BiasNeuron.generateNeuronStatically(ai, 0); // Creates the neurons for layer 1. for (int neurons = 0; neurons < 40; neurons++) Neuron.generateNeuronStatically(ai, 1); for (int neurons = 0; neurons < 20; neurons++) Neuron.generateNeuronStatically(ai, 2); for (int neurons = 0; neurons < 10; neurons++) Neuron.generateNeuronStatically(ai, 3); connectNeurons(); } this.setNeuronsPerRow(0, 10); this.controler = this; } private int lastNumber = 0; public String learn() { boolean[] bbb = numberToBinaryBooleans((lastNumber++ % 1023)/* (int) (Math.random() * 1023) */); for (int i = 0; i < bbb.length; i++) { binary.changeNumberAt(0, i, (bbb[i]) ? 1 : 0); binary.changeNumberAt(1, i, (bbb[i]) ? 0 : 1); } boolean[] thought = tickAndThink(); float accuracy = 0; // If it isprime: boolean[] booleanBase = new boolean[10]; for (int i = 0; i < 10; i++) { booleanBase[i] = binary.getNumberAt(0, i) != 0; } int number = binaryBooleansToNumber(booleanBase); boolean result = ifNumberIsPrime.get(number); wasCorrect = (result == thought[0]); this.getAccuracy().addEntry(wasCorrect); accuracy = (float) this.getAccuracy().getAccuracy(); // IMPROVE IT HashMap<Neuron, Double> map = new HashMap<>(); map.put(ai.getNeuronFromId(0), result ? 1 : -1.0); if (!wasCorrect) DeepReinforcementUtil.instantaneousReinforce(this, map, 1); return ((wasCorrect ? ChatColor.GREEN : ChatColor.RED) + "acc " + ((int) (100 * accuracy)) + "|=" + number + "|correctResp=" + result + "|WasPrime-Score " + ((int) (100 * (ai.getNeuronFromId(0).getTriggeredStength())))); } @Override public String update() { boolean[] thought = tickAndThink(); float accuracy = 0; // If it isprime: boolean[] booleanBase = new boolean[10]; for (int i = 0; i < 10; i++) { booleanBase[i] = binary.getNumberAt(0, i) != 0; } int number = binaryBooleansToNumber(booleanBase); boolean result = ifNumberIsPrime.get(number); return ((thought[0] ? ChatColor.DARK_GREEN : ChatColor.DARK_RED) + "|=" + number + "|WasPrime-Score " + ((int) (100 * (ai.getNeuronFromId(0).getTriggeredStength())))); } @Override public NNBaseEntity clone() { PrimeNumberBot thi = new PrimeNumberBot(false); thi.ai = this.ai; return thi; } public void setBase(NNBaseEntity t) { // this.base = (PrimeNumberGuesser) t; } /** * Adds string B to the hashmap with value true * * @param b */ public void a(Integer... b) { for (int c : b) ifNumberIsPrime.put(c, true); } private boolean[] numberToBinaryBooleans(int i) { boolean[] k = new boolean[10]; int tempnumber = i; for (int power = 9; power >= 0; power--) { if (tempnumber - Math.pow(2, power) >= 0) { k[power] = true; // System.out.println(tempnumber+" - "+(tempnumber-Math.pow(2,power))); tempnumber -= Math.pow(2, power); } else { k[power] = false; } } return k; } private int binaryBooleansToNumber(boolean[] b) { int k = 0; for (int i = 0; i < b.length; i++) { if (b[i]) k += Math.pow(2, i); } return k; } private boolean isPrime(int n) { // check if n is a multiple of 2 if (n % 2 == 0) return false; // if not, then just check the odds for (int i = 3; i * i <= n; i += 2) { if (n % i == 0) return false; } return true; } private void initValidPrimes() { for (int i = 0; i < 1023; i++) { ifNumberIsPrime.put(i, isPrime(i)); // ifNumberIsPrime.put(i, i%2==0); } } @Override public void setInputs(CommandSender initiator, String[] args) { if (this.shouldLearn) { initiator.sendMessage("Stop the learning before testing. use /nn stoplearning"); return; } if (args.length > 1) { int test = 0; try { test = Integer.parseInt(args[1]); } catch (Exception e) { return; } int tempnumber = test; for (int power = 9; power >= 0; power--) { if (tempnumber - Math.pow(2, power) >= 0) { this.binary.changeNumberAt(0, power, 1); this.binary.changeNumberAt(1, power, 0); tempnumber -= Math.pow(2, power); } else { this.binary.changeNumberAt(0, power, 0); this.binary.changeNumberAt(1, power, 1); } } } else { initiator.sendMessage("Provide a number"); } } }