package example.logical; /** 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 java.util.Map; import java.util.concurrent.ThreadLocalRandom; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import me.zombie_striker.neuralnetwork.*; import me.zombie_striker.neuralnetwork.neurons.*; import me.zombie_striker.neuralnetwork.neurons.input.InputBooleanNeuron; import me.zombie_striker.neuralnetwork.senses.Sensory2D_Booleans; import me.zombie_striker.neuralnetwork.util.DeepReinforcementUtil; public class LogicalAND extends NNBaseEntity implements Controler { public Sensory2D_Booleans binary = new Sensory2D_Booleans(1, 2); public LogicalAND(boolean createAI) { this.controler = this; if (createAI) { /** * If createAI is true, then generate the AI with 3 layers (i.e, 1 * hidden layer), 2 inputs, 3 neurons, and 2 bias neurons. After * that, connect all the neurons. * * If you want to test using random inputs (what should be done, but * makes replication and understanding a bit hander), add * randomizeNeurons() after connecting then. */ this.ai = NNAI.generateAI(this, 1, 3, "output"); for (int binaryIndex = 0; binaryIndex < 2; binaryIndex++) { InputBooleanNeuron.generateNeuronStatically(ai, 0, binaryIndex, this.binary); } for (int neurons = 0; neurons < 3; neurons++) { Neuron.generateNeuronStatically(ai, 1); } BiasNeuron.generateNeuronStatically(ai, 0); BiasNeuron.generateNeuronStatically(ai, 1); connectNeurons(); } } public String learn() { /** * Simple explanation of these steps: * * 1) If it is currently learning, change the inputs to either true or false. * * 2) Let the NN tick and think. This will return the outputs from the OutpuitNeurons * * 3) If it is not learning, just return the answer. * * 4) Else, do the logic and see if the answer it gave (thought[0]) was correct. * * 5) If it was not correct, use the DeepReinforcementUtil to improve it. * * 6) After inprovement, return a message with if it was correct, the accuracy, the inputs, and what it thought was the output, */ binary.changeValueAt(0, 0, ThreadLocalRandom.current().nextBoolean()); binary.changeValueAt(0, 1, ThreadLocalRandom.current().nextBoolean()); boolean[] thought = tickAndThink(); boolean logic = (binary.getBooleanAt(0, 0) && binary.getBooleanAt(0, 1)); boolean wasCorrect = (logic == thought[0]); this.getAccuracy().addEntry(wasCorrect); // IMPROVE IT HashMap<Neuron, Double> map = new HashMap<>(); for (int i = 0; i < thought.length; i++) map.put(ai.getNeuronFromId(i), logic ? 1.0 : -1.0); if (!wasCorrect) DeepReinforcementUtil.instantaneousReinforce(this, map,1); return (wasCorrect ? ChatColor.GREEN : ChatColor.RED) + "acc " + getAccuracy().getAccuracyAsInt() + "|" + binary.getBooleanAt(0, 0) + " + " + binary.getBooleanAt(0, 1) + " ~~ " + thought[0]; } @Override public String update() { boolean[] thought = tickAndThink(); return ("|" + binary.getBooleanAt(0, 0) + " + " + binary.getBooleanAt(0, 1) + " ~~ " + thought[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 > 2) { boolean test = false; try { test = Boolean.parseBoolean(args[1]); } catch (Exception e) { } boolean test2 = false; try { test2 = Boolean.parseBoolean(args[2]); } catch (Exception e) { } binary.changeValueAt(0, 0, test); binary.changeValueAt(0, 1, test2); } else { initiator.sendMessage("Provide two values (True or false)"); } } @Override public NNBaseEntity clone() { LogicalAND thi = new LogicalAND(false); thi.ai = this.ai; return thi; } @Override public void setBase(NNBaseEntity t) { } public LogicalAND(Map<String, Object> map) { super(map); } }