Cleanup, eliminate hard code

pull/1/head
Yong Zhu 6 years ago
parent 0ce5f409f2
commit 14f9c43659

@ -56,21 +56,14 @@
<dependencies>
<!-- For JSON translate -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
<dependency>
<dependencies>
<!--dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependency-->
</dependencies>
<build>

@ -21,7 +21,7 @@ import com.github.drinkjava2.frog.egg.EggTool;
@SuppressWarnings("serial")
public class Env extends JPanel {
/** Speed of test */
public static final int SHOW_SPEED = 5; // 测试速度1~1000,可调, 数值越小,速度越慢
public static final int SHOW_SPEED = 1; // 测试速度1~1000,可调, 数值越小,速度越慢
public static final int ENV_WIDTH = 400; // 虚拟环境的宽度, 可调
@ -32,7 +32,7 @@ public class Env extends JPanel {
public static final int FROG_BRAIN_DISP_WIDTH = 300; // Frog的脑图在屏幕上的显示大小,可调
/** Steps of one test round */
public static final int STEPS_PER_ROUND = 2000;// 每轮测试步数,可调
public static final int STEPS_PER_ROUND = 1000;// 每轮测试步数,可调
/** Frog's brain width, fixed to 1000 unit */
public static final float FROG_BRAIN_WIDTH = 1000; // frog的脑宽度固定为1000,不要随便调整,因为器官的相对位置和大小是按脑大小设定的

@ -57,7 +57,7 @@ public class Frog {
this.y = y;
for (Organ org : egg.organs) {
organs.add(org);
org.init(this);// 每个新器官初始化如果是Group类它们会生成许多脑细胞
org.initFrog(this);// 每个新器官初始化如果是Group类它们会生成许多脑细胞
}
}

@ -10,8 +10,6 @@
*/
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.brain.group.Group;
/**
* Cell is the basic unit of frog's brain
*
@ -22,7 +20,7 @@ public class Cell {
public static final float MAX_ENERGY_LIMIT = 1000.0f;
// this cell belong to frog's which organ
public Group group;
public Organ organ;
// inputs of cell
public Input[] inputs; // 每个细胞有一组输入触突

@ -14,6 +14,7 @@ import java.awt.Color;
import java.awt.Graphics;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Organ is a part of frog, organ can be saved in egg
@ -23,24 +24,30 @@ import com.github.drinkjava2.frog.Frog;
* @author Yong Zhu
* @since 1.0.4
*/
public abstract class Organ extends Zone {
public class Organ extends Zone {
private static final long serialVersionUID = 1L;
public String name; // 显示在脑图上的器官名称,可选
public long fat = 0; // 如果活跃多fat值高则保留及变异的可能性大反之则很可能丢弃掉
public float organActiveEnergy = 1; // 执行器官激活需要消耗细胞多少能量
public float organOutputEnergy = 2; // 感觉 器官激活会给细胞增加多少能量
public boolean initilized; // 通过这个标记判断是否需要手工给定它的参数初值
public boolean allowBorrow() { // 是否允许在精子中将这个器官借出
return false;
}
/** Each loop step call active method, Child class can override this method */
public void active(Frog f) { // 每一步都会调用器官的active方法 ,缺省啥也不干
}
/** If active in this organ's zone? */
public boolean outputActive(Frog f) { // 如果一个细胞能量>10,且它的输出触突位于这个器官内,则器官被激活
for (Cell cell : f.cells) {
if (cell.energy > 10)
if (cell.energy > organActiveEnergy)
for (Output output : cell.outputs) { //
if (this.nearby(output)) {
cell.group.fat++;
cell.energy -= 3;
cell.organ.fat++;
cell.energy -= organActiveEnergy;
return true;
}
}
@ -50,9 +57,7 @@ public abstract class Organ extends Zone {
/** Set X, Y, Radius, name of current Organ */
public Organ setXYRN(float x, float y, float r, String name) {
this.x = x;
this.y = y;
this.r = r;
this.setXYR(x, y, r);
this.name = name;
return this;
}
@ -66,31 +71,27 @@ public abstract class Organ extends Zone {
pic.drawText(g, this, String.valueOf(this.name));
}
/** make a new copy of current organ */
public Organ newCopy() { // 创建一个当前器官的副本
/** Only call once when frog created , Child class can override this method */
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次缺省啥也不干通常用于Group子类的初始化
}
public void varyParam() {
organActiveEnergy = RandomUtils.vary(organActiveEnergy);
organOutputEnergy = RandomUtils.vary(organOutputEnergy);
}
/** Only call once after organ be created by new() method */
public Organ[] vary() { // 在下蛋时每个器官会调用这个方法,缺省返回一个类似自已的副本,子类通常要覆盖这个方法
Organ newOrgan = null;
try {
newOrgan = this.getClass().newInstance();
copyXYR(this, newOrgan);
newOrgan.name = this.name;
newOrgan.fat = this.fat;
return newOrgan;
} catch (Exception e) {
throw new UnknownError("Can not make new Organ copy for " + this);
}
}
/** Only call once when frog created , Child class can override this method */
public void init(Frog f) { // 仅在Frog生成时这个方法会调用一次缺省啥也不干通常用于Group子类的初始化
}
/** Only call once when frog created , Child class can override this method */
public Organ[] vary() { // 在下蛋时每个器官会调用这个方法缺省返回自已的副本Group类通常要覆盖这个方法
return new Organ[] { newCopy() };
}
/** Each loop step call active method, Child class can override this method */
public void active(Frog f) { // 每一步都会调用器官的active方法 ,缺省啥也不干
copyXYR(this, newOrgan);
newOrgan.name = this.name;
newOrgan.fat = this.fat;
return new Organ[] { newOrgan };
}
}

@ -10,7 +10,6 @@
*/
package com.github.drinkjava2.frog.brain.group;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
/**
@ -32,20 +31,4 @@ import com.github.drinkjava2.frog.brain.Organ;
public abstract class Group extends Organ {
private static final long serialVersionUID = 1L;
@Override
public boolean allowBorrow() { // 是否允许在精子中将这个器官借出
return true;
}
/** Each loop step call active method, Child class can override this method */
@Override
public void active(Frog f) { // 每一步都会调用器官的active方法
f.frogEngery -= 1; // 每个器官运动都要消耗能量, 死了也要消耗能量
if (!f.alive)
return;
if (f.frogEngery < 0) { // 如果能量小于0则死
f.alive = false;
return;
}
}
}

@ -38,15 +38,19 @@ public class RandomConnectGroup extends Group {
public Zone inputZone; // 输入触突区
public Zone outputZone; // 输出触突区
float inputWeight = 1; // 输入权重
float outputWeight = 1; // 输出权重
@Override
public void init(Frog f) {
if (inputZone == null)
public boolean allowBorrow() { // 是否允许在精子中将这个器官借出
return true;
}
@Override
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
inputZone = RandomUtils.randomPosInZone(this);
if (outputZone == null)
outputZone = RandomUtils.randomPosInZone(this);
}
Cell c = new Cell();
@ -58,7 +62,7 @@ public class RandomConnectGroup extends Group {
out.cell = c;
c.outputs = new Output[] { out };
c.group = this;
c.organ = this;
f.cells.add(c);
}
@ -67,11 +71,8 @@ public class RandomConnectGroup extends Group {
if (fat <= 0)// 如果胖值为0表示这个组的细胞没有用到可以小概率丢掉它了
if (RandomUtils.percent(50))
return new Organ[] {};
if (RandomUtils.percent(20)) { // 有20机率权重变大
inputWeight = RandomUtils.vary(inputWeight);
outputWeight = RandomUtils.vary(outputWeight);
}
return new Organ[] { this }; // 大部分时间原样返回它的副本就行了,相当于儿子是父亲的克隆
this.varyParam(); // 器官缺省权重变异
return new Organ[] { this };
}
public RandomConnectGroup(float x, float y, float r) {
@ -90,7 +91,9 @@ public class RandomConnectGroup extends Group {
/** Child class can override this method to drawing picture */
public void drawOnBrainPicture(BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法
Graphics g = pic.getGraphics();// border
g.setColor(Color.gray); // 缺省是灰色
if (fat <= 0)
g.setColor(Color.LIGHT_GRAY); // 缺省是灰色
else g.setColor(Color.red);
pic.drawZone(g, this);
pic.drawLine(g, inputZone, outputZone);
pic.drawZone(g, inputZone);

@ -28,7 +28,7 @@ public class Eat extends Organ {// Eat这个类将食物转化为能量能量
// 能量境加青蛙感觉不到但是Happy区激活青蛙能感觉到因为Happy区是一个脑器官
Organ o = f.organs.get(0);
((Happy) o).happy += 200; // 找到食物有奖!
((Happy) o).happy += 2; // 找到食物有奖!
}
}

@ -12,6 +12,7 @@ package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.BrainPicture;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
@ -27,6 +28,33 @@ import com.github.drinkjava2.frog.brain.Zone;
public class Eye extends Organ {
private static final long serialVersionUID = 1L;
@Override
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次缺省啥也不干通常用于Group子类的初始化
if (!initilized) {
initilized = true;
organOutputEnergy = 300;
}
}
public void drawOnBrainPicture(BrainPicture pic) {// 把自已这个器官在脑图上显示出来
super.drawOnBrainPicture(pic);
float qRadius = r / 4;
float q3Radius = (float) (r * .75);
Zone seeUp = new Zone(x, y + q3Radius, qRadius);
Zone seeDown = new Zone(x, y - q3Radius, qRadius);
Zone seeLeft = new Zone(x - q3Radius, y, qRadius);
Zone seeRight = new Zone(x + q3Radius, y, qRadius);
pic.drawZone(pic.getGraphics(), seeUp);
pic.drawZone(pic.getGraphics(), seeDown);
pic.drawZone(pic.getGraphics(), seeLeft);
pic.drawZone(pic.getGraphics(), seeRight);
}
@Override
public Organ[] vary() {
return new Organ[] { this };
}
@Override
public void active(Frog f) {
// 第一个眼睛只能观察上、下、左、右四个方向有没有食物
@ -78,16 +106,16 @@ public class Eye extends Organ {
for (Input input : cell.inputs) {
if (input.nearby(this)) {
if (foodAtUp && input.nearby(seeUp)) {
input.cell.energy += 500; // 所有的硬编码都是bug这个500将来要参与进化下同
input.cell.energy += organOutputEnergy;
}
if (foodAtDown && input.nearby(seeDown)) {
input.cell.energy += 500;
input.cell.energy += organOutputEnergy;
}
if (foodAtLeft && input.nearby(seeLeft)) {
input.cell.energy += 500;
input.cell.energy += organOutputEnergy;
}
if (foodAtRight && input.nearby(seeRight)) {
input.cell.energy += 500;
input.cell.energy += organOutputEnergy;
}
}
}

@ -14,6 +14,7 @@ import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Hungry will active cell's inputs, if frog's energy not enough
@ -21,16 +22,31 @@ import com.github.drinkjava2.frog.brain.Organ;
public class Hungry extends Organ {
private static final long serialVersionUID = 1L;
@Override
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次缺省啥也不干通常用于Group子类的初始化
if (!initilized) {
initilized = true;
organOutputEnergy = 2;
}
}
@Override
public Organ[] vary() {
if (RandomUtils.percent(20)) // 有20机率权重变化
organOutputEnergy = RandomUtils.vary(organOutputEnergy);
return new Organ[] { this };
}
@Override
public void active(Frog f) {
if (f.frogEngery < 10000)// 所有的硬编码都是bug包括这个10000
if (f.frogEngery < 100000000)// 所有的硬编码都是bug包括这个100000000
for (Cell cell : f.cells) {
if (cell.energy > 0)
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)
for (Input input : cell.inputs)
if (input.nearby(this)) // input zone near by hungry zone
cell.energy += 2; // 所有的硬编码都是bug包括这个2
cell.energy += organOutputEnergy;
}
}

@ -15,6 +15,7 @@ import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Pain zone active after some bad thingg happen like close to edge, hurt...
@ -25,22 +26,31 @@ public class Pain extends Organ { // Pain器官目前激活的条件是离边境
private static final long serialVersionUID = 1L;
public float pain = 0; // happy初始值为0, 如果frog靠近边界将增加Pain值将来如果天敌出现也会激活Frog的Pain区
@Override
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
organOutputEnergy = 150;
}
}
// @Override
// public Organ[] vary() {
// if (RandomUtils.percent(20)) // 有20机率权重变化
// organOutputEnergy = RandomUtils.vary(organOutputEnergy);
// return new Organ[] { this };
// }
@Override
public void active(Frog f) {
if (Env.closeToEdge(f))
pain = 500;// 所有的硬编码都是bug包括这个500
else
pain = 0;
if (pain > 0) {
if (Env.closeToEdge(f)) {
for (Cell cell : f.cells) {
if (cell.energy > 0)
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)
for (Input input : cell.inputs)
if (input.nearby(this)) // if input zone near by happy zone
cell.energy += pain / 10; // 所有的硬编码都是bug包括这个10
cell.energy += organOutputEnergy;
}
}
}

@ -51,7 +51,8 @@ public class EggTool {
if (Env.DEBUG_MODE)
for (int i = 0; i < first.organs.size(); i++) {
Organ org = first.organs.get(i);
System.out.println("Organ(" + i + ")=" + org + ", fat=" + org.fat);
System.out.println("Organ(" + i + ")=" + org + ", fat=" + org.fat + ", activeEnergy=" + org.organActiveEnergy
+ ", outputEnergy=" + org.organOutputEnergy);
}
try {

@ -52,12 +52,24 @@ public class RandomUtils {
public static float vary(float f) { // 大部分时候不变,有极小机会变异,有极极小机会大变异,有极极极小机会大大大变异
int i = rand.nextInt(100);
if (i < 95)
if (i < 50) // 有50的机率不变异
return f;
float rate = .05f;
if (i > 97)
rate = .1f;
return (float) (f * ((1 - rate) + rand.nextFloat() * rate * 2));
float rate = 0.2f; // 50%机率在0.2倍范围变异
if (i > 80)
rate = 1f; // 有20%的机率在1倍的范围变异
if (i > 90)
rate = 10f; // 有10%的机率在10倍的范围变异
if (i > 95)
rate = 100f; // 有5%的机率在100倍的范围变异
if (i > 98)
rate = 1000f; // 有1%的机率在1000倍的范围变异
boolean bigger = rand.nextInt(2) > 0;
if (bigger)
f = f + f * rate * rand.nextFloat() + .001f;
else
f = f - f * rate * rand.nextFloat() - .001f;
return f * rate;
}
}

Binary file not shown.

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save