pull/1/head
Yong Zhu 7 years ago
parent cf3f514cbc
commit 5770f3afe6

@ -58,9 +58,8 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
* 移殖到超级电脑上,由人来同它交流,输入新的图形和汉字,纠正它说的错误的话
* 移殖到并行芯片硬件上
## 目前进展和成绩
2018.10.21 开始编码。
2019.03.11 虚拟环境已建好,可以模拟低等生命的遗传、繁殖、变异、进化现象,但目前只能往一个方向运动,相当于一个最简单的单细胞生物,还不具备视觉能力,不具备主动找食能力。
## 目前进展和成绩
2019.03.11 虚拟环境已建好,可以模拟低等生命的遗传、繁殖、变异、进化现象,但目前只能往一个方向运动,相当于一个最简单的单细胞生物,还不具备视觉能力,不具备主动找食能力。
运行run.bat可以查看演示。Env.java中的几个重要参数说明:
* SHOW_SPEED 调整实验的速度(1~1000),值越小则越慢。
* EGG_QTY: 每次允许Frog下多少个蛋每个蛋可以孵出4个青蛙。通常下蛋取值在10~1000之间。蛋保存着我们测试的结果。实验的最终目标就是获得一个蛋。
@ -68,7 +67,8 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
下面是这个测试的动画截图,有兴趣的可以试着自己运行一下:
![截图](https://gitee.com/drinkjava2/frog/raw/master/result.gif)
另外每步演示的结果(egg)会存盘在根目根目录下名为egg.ser可以删除这个文件以从头开始新的测试。目前万里长征刚踏上第一步因为还没涉及脑模型的搭建。可以看到有些青蛙跑得飞快这是自然选择的结果因为跑在最前面的吃得多。以后会改正这个bug要让最聪明的、会抢食的Frog胜出而不是让跑得快的胜出。
2019.03.21 添加了脑图改进随机运动模式为Hungry区驱动。从脑图上可以直观地观察脑结构方便调试。
2019.03.21 添加了脑图改进随机运动模式为Hungry区驱动。从脑图上可以直观地观察脑结构方便调试。
2019.04.01 改进脑图的显示bug, 每一次生成Frog时添加随机神经元并简单实现"卵+精子->受精卵"算法,以促进种群多样性。
## 版权 | License
[Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0)

@ -29,8 +29,7 @@ import com.github.drinkjava2.frog.env.Application;
import com.github.drinkjava2.frog.env.Env;
/**
* Frog = brain + body(mouth, eye, leg), but now let's focus on brain, ignore
* body
* Frog = brain + body, but now let's only focus on brain, ignore body
*
*
*
@ -39,6 +38,8 @@ import com.github.drinkjava2.frog.env.Env;
*/
public class Frog {
public CellGroup[] cellGroups;
/** brain cells */
public List<Cell> cells = new ArrayList<Cell>();
@ -59,8 +60,7 @@ public class Frog {
public int x;
public int y;
public long energy = 10000;
public Egg egg; // 青蛙是从哪个egg孵出来的,如果青蛙生存下来将用这个egg来下蛋
public long energy = 10000;
public boolean alive = true; // 设为false表示青蛙死掉了将不参与任何计算以节省时间
static final Random r = new Random();
@ -76,12 +76,16 @@ public class Frog {
public Frog(int x, int y, Egg egg) {
this.x = x;
this.y = y;
if (egg.cellgroups == null)
throw new IllegalArgumentException("Illegal egg cellgroups argument:" + egg.cellgroups);
for (int k = 0; k < egg.cellgroups.length; k++) {
CellGroup g = egg.cellgroups[k];
if (egg.cellGroups == null)
throw new IllegalArgumentException("Illegal egg cellgroups argument:" + egg.cellGroups);
cellGroups = new CellGroup[egg.cellGroups.length];
for (int k = 0; k < egg.cellGroups.length; k++) {
CellGroup g = egg.cellGroups[k];
cellGroups[k] = new CellGroup(g);
for (int i = 0; i < g.cellQty; i++) {// 开始根据蛋来创建脑细胞
Cell c = new Cell();
c.group = k;
int cellQTY = Math.round(g.inputQtyPerCell);
c.inputs = new Input[cellQTY];
for (int j = 0; j < cellQTY; j++) {
@ -100,8 +104,7 @@ public class Frog {
}
cells.add(c);
}
}
this.egg = new Egg(egg);// 克隆一份蛋,如果没被淘汰掉,将来下蛋时要用这个蛋来下变异蛋
}
}
private int goUp = 0;
@ -122,38 +125,40 @@ public class Frog {
for (Cell cell : cells) {
if (energy < 10000) // in hungry
for (Input input : cell.inputs) {
if (input.nearby(hungry)) {
if (cell.energy < 100) {
if (input.nearby(hungry)) {
if (cell.energy < 100)
cell.energy++;
egg.cellgroups[cell.group].activeTimes++;
}
}
}
for (Output output : cell.outputs) { // hungry drive moves
if (goUp < 1 && cell.energy > 10 && moveUp.nearby(output)) {
cellGroups[cell.group].fat++;
goUp++;
if (cell.energy > 0)
cell.energy--;
}
if (goDown < 1 && cell.energy > 10 && moveDown.nearby(output)) {
cellGroups[cell.group].fat++;
goDown++;
if (cell.energy > 0)
cell.energy--;
}
if (goLeft < 1 && cell.energy > 10 && moveLeft.nearby(output)) {
cellGroups[cell.group].fat++;
goLeft++;
if (cell.energy > 0)
cell.energy--;
}
if (goRight < 1 && cell.energy > 10 && moveRight.nearby(output)) {
cellGroups[cell.group].fat++;
goRight++;
if (cell.energy > 0)
cell.energy--;
}
}
moveAndEat(env);
}
moveAndEat(env);
return alive;
}
@ -185,58 +190,11 @@ public class Frog {
}
}
private boolean allowVariation = false;
private float percet1(float f) {
if (!allowVariation)
return f;
return (float) (f * (0.99f + r.nextFloat() * 0.02));
}
private static boolean percent70() {
return r.nextInt(10) > 2;
}
private float percet2(float f) {
if (!allowVariation)
return f;
return (float) (f * (0.98f + r.nextFloat() * 0.04));
}
private static Zone randomPosInZone(Zone z) {
return new Zone(z.x - z.radius + z.radius * 2 * r.nextFloat(), z.y - z.radius + z.radius * 2 * r.nextFloat(),
0);
}
public Egg layEgg() {
if (r.nextInt(100) > 25) // 变异率先固定在25%
allowVariation = false;// 如果不允许变异,下的蛋就相当于克隆原来的蛋
else
allowVariation = true;
Egg newEgg = new Egg();
List<CellGroup> gpList = new ArrayList<>();
for (int i = 0; i < egg.cellgroups.length; i++) {
if (egg.cellgroups[i].activeTimes == 0 && percent70())
// if (egg.cellgroups[i].activeTimes == 0)
continue;// 从未激活过的神经元有70%的概率被丢弃掉
CellGroup cellGroup = new CellGroup();
CellGroup oldGp = egg.cellgroups[i];
cellGroup.groupInputZone = new Zone(percet2(oldGp.groupInputZone.x), percet2(oldGp.groupInputZone.y),
percet2(oldGp.groupInputZone.radius));
cellGroup.groupOutputZone = new Zone(percet2(oldGp.groupOutputZone.x), percet2(oldGp.groupOutputZone.y),
percet2(oldGp.groupOutputZone.radius));
cellGroup.cellQty = Math.round(percet2(oldGp.cellQty));
cellGroup.cellInputRadius = percet1(oldGp.cellInputRadius);
cellGroup.cellOutputRadius = percet1(oldGp.cellOutputRadius);
cellGroup.inputQtyPerCell = Math.round(percet2(oldGp.inputQtyPerCell));
cellGroup.outputQtyPerCell = Math.round(percet2(oldGp.outputQtyPerCell));
gpList.add(cellGroup);
}
newEgg.cellgroups = gpList.toArray(new CellGroup[gpList.size()]);
return newEgg;
}
public void show(Graphics g) {
if (!alive)
return;

@ -11,6 +11,7 @@
package com.github.drinkjava2.frog.egg;
import java.io.Serializable;
import java.util.Random;
/**
* CellGroup represents a bunch of similar nerve cells <br/>
@ -38,5 +39,38 @@ public class CellGroup implements Serializable {
public float inputQtyPerCell; // input qty per cell
public float outputQtyPerCell; // output qty per cell
public long activeTimes = 0; // if activate times=0 ,this cellgroup may be ignored in egg
public long fat = 0; // if activate times=0 ,this cellgroup may be ignored in egg
public boolean inherit = false; // set to true if is inherited from egg, not by random
private static final Random r = new Random();
public CellGroup() {
}
public CellGroup(CellGroup g) {// clone old CellGroup
groupInputZone = new Zone(g.groupInputZone);
groupOutputZone = new Zone(g.groupOutputZone);
cellInputRadius = g.cellInputRadius;
cellOutputRadius = g.cellOutputRadius;
cellQty = g.cellQty;
inputQtyPerCell = g.inputQtyPerCell;
outputQtyPerCell = g.outputQtyPerCell;
fat = g.fat;
inherit = g.inherit;
}
public CellGroup(int brainWidth, int randomCellQtyPerGroup, int randomInputQtyPerCell, int randomOutQtyPerCell) {
inherit = false;
groupInputZone = new Zone(r.nextFloat() * brainWidth, r.nextFloat() * brainWidth,
(float) (r.nextFloat() * brainWidth * .01));
groupOutputZone = new Zone(r.nextFloat() * brainWidth, r.nextFloat() * brainWidth,
(float) (r.nextFloat() * brainWidth * .01));
cellQty = 1 + r.nextInt(randomCellQtyPerGroup);
cellInputRadius = (float) (0.001 + r.nextFloat() * 2);
cellOutputRadius = (float) (0.001 + r.nextFloat() * 2);
inputQtyPerCell = 1 + r.nextInt(randomInputQtyPerCell);
outputQtyPerCell = 1 + r.nextInt(randomOutQtyPerCell);
}
}

@ -11,8 +11,12 @@
package com.github.drinkjava2.frog.egg;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.github.drinkjava2.frog.Frog;
/**
* Egg is the static structure description of frog, can save as text file, to
* build a frog, first need build a egg.<br/>
@ -24,45 +28,28 @@ import java.util.Random;
public class Egg implements Serializable {
private static final long serialVersionUID = 2L;
public static final int BRAIN_WIDTH = 800;
public int randomCellGroupQty = 100;
public int randomCellQtyPerGroup = 5;
public int randomInputQtyPerCell = 10;
public int randomOutQtyPerCell = 5;
public CellGroup[] cellgroups;
public int realCellGroupQty=0; //z
public int randomCellGroupQty = 100; // 随机生成多少个组
public int randomCellQtyPerGroup = 3; // 每个组有多少个脑细胞
public int randomInputQtyPerCell = 3;// 每个脑细胞有多少个输入触突
public int randomOutQtyPerCell = 2; // 每个脑细胞有多少个输出触突
public CellGroup[] cellGroups;
public Egg() {
// default constructor
}
private static Random r = new Random();
public Egg(Egg e) {// clone the old egg
cellgroups = new CellGroup[e.cellgroups.length];
for (int i = 0; i < e.cellgroups.length; i++) {
CellGroup oldCellGroup = e.cellgroups[i];
CellGroup cellGroup = new CellGroup();
cellgroups[i] = cellGroup;
cellGroup.groupInputZone = new Zone(oldCellGroup.groupInputZone);
cellGroup.groupOutputZone = new Zone(oldCellGroup.groupOutputZone);
cellGroup.cellQty = oldCellGroup.cellQty;
cellGroup.cellInputRadius = oldCellGroup.cellInputRadius;
cellGroup.cellOutputRadius = oldCellGroup.cellOutputRadius;
cellGroup.inputQtyPerCell = oldCellGroup.inputQtyPerCell;
cellGroup.outputQtyPerCell = oldCellGroup.outputQtyPerCell;
}
realCellGroupQty=e.realCellGroupQty;
}
// 我靠,两个蛋怎么合成一个蛋?看来要模拟XY染色体了不能做加法会撑暴内存的但现在每次只随机加一个
public Egg(Egg x, Egg y) { // use 2 eggs to create a zygote
cellgroups = new CellGroup[x.cellgroups.length + y.cellgroups.length+ randomCellGroupQty/5];
for (int i = 0; i < x.cellgroups.length; i++) {
CellGroup oldCellGroup = x.cellgroups[i];
// x里原来的CellGroup
cellGroups = new CellGroup[x.cellGroups.length + 1 + randomCellGroupQty / 3];
for (int i = 0; i < x.cellGroups.length; i++) {
CellGroup oldCellGroup = x.cellGroups[i];
CellGroup cellGroup = new CellGroup();
cellgroups[i] = cellGroup;
cellGroups[i] = cellGroup;
cellGroup.inherit = true;
cellGroup.groupInputZone = new Zone(oldCellGroup.groupInputZone);
cellGroup.groupOutputZone = new Zone(oldCellGroup.groupOutputZone);
cellGroup.cellQty = oldCellGroup.cellQty;
@ -71,55 +58,70 @@ public class Egg implements Serializable {
cellGroup.inputQtyPerCell = oldCellGroup.inputQtyPerCell;
cellGroup.outputQtyPerCell = oldCellGroup.outputQtyPerCell;
}
int xLength = x.cellgroups.length;
for (int i = 0; i < y.cellgroups.length; i++) {
CellGroup oldCellGroup = y.cellgroups[i];
CellGroup cellGroup = new CellGroup();
cellgroups[xLength + i] = cellGroup;
cellGroup.groupInputZone = new Zone(oldCellGroup.groupInputZone);
cellGroup.groupOutputZone = new Zone(oldCellGroup.groupOutputZone);
cellGroup.cellQty = oldCellGroup.cellQty;
cellGroup.cellInputRadius = oldCellGroup.cellInputRadius;
cellGroup.cellOutputRadius = oldCellGroup.cellOutputRadius;
cellGroup.inputQtyPerCell = oldCellGroup.inputQtyPerCell;
cellGroup.outputQtyPerCell = oldCellGroup.outputQtyPerCell;
}
int yLength=y.cellgroups.length;
realCellGroupQty=xLength+yLength;
for (int i = 0; i < randomCellGroupQty/5; i++) {
CellGroup cellGroup = new CellGroup();
cellgroups[i+xLength+yLength] = cellGroup;
cellGroup.groupInputZone = new Zone(r.nextFloat() * BRAIN_WIDTH, r.nextFloat() * BRAIN_WIDTH,
(float) (r.nextFloat() * BRAIN_WIDTH * .01));
cellGroup.groupOutputZone = new Zone(r.nextFloat() * BRAIN_WIDTH, r.nextFloat() * BRAIN_WIDTH,
(float) (r.nextFloat() * BRAIN_WIDTH * .01));
cellGroup.cellQty = r.nextInt(x.randomCellQtyPerGroup);
cellGroup.cellInputRadius = (float) (r.nextFloat() * 0.001);
cellGroup.cellOutputRadius = (float) (r.nextFloat() * 0.001);
cellGroup.inputQtyPerCell = r.nextInt(x.randomInputQtyPerCell);
cellGroup.outputQtyPerCell = r.nextInt(x.randomOutQtyPerCell);
}
// 从y里借一个CellGroup
CellGroup randomY = y.cellGroups[r.nextInt(y.cellGroups.length)];
CellGroup cellGroup = new CellGroup(randomY);
cellGroups[x.cellGroups.length ] = cellGroup;
//随机生成一批CellGroup
for (int i = 0; i < randomCellGroupQty / 3; i++)
cellGroups[i + x.cellGroups.length + 1] = new CellGroup(Egg.BRAIN_WIDTH, x.randomCellQtyPerGroup,
x.randomInputQtyPerCell, x.randomOutQtyPerCell);
}
public static Egg createBrandNewEgg() { // create a brand new Egg
Egg egg = new Egg();
egg.cellgroups = new CellGroup[egg.randomCellGroupQty];
for (int i = 0; i < egg.randomCellGroupQty; i++) {
Egg egg = new Egg();
egg.cellGroups = new CellGroup[egg.randomCellGroupQty];
for (int i = 0; i < egg.randomCellGroupQty; i++)
egg.cellGroups[i] = new CellGroup(Egg.BRAIN_WIDTH, egg.randomCellQtyPerGroup, egg.randomInputQtyPerCell,
egg.randomOutQtyPerCell);
return egg;
}
private static boolean allowVariation = false;
private static float percet1(float f) {
if (!allowVariation)
return f;
return (float) (f * (0.99f + r.nextFloat() * 0.02));
}
private static boolean percent(int percent) {
return r.nextInt(100) < percent;
}
private static float percet2(float f) {
if (!allowVariation)
return f;
return (float) (f * (0.98f + r.nextFloat() * 0.04));
}
public Egg(Frog frog, boolean allowVariate) { // create a brand new Egg
allowVariation = allowVariate;
List<CellGroup> gpList = new ArrayList<>();
for (int i = 0; i < frog.cellGroups.length; i++) {
if (frog.cellGroups[i].fat <= 0) {
if (! frog.cellGroups[i].inherit)
continue;// 从未激活过的神经元,并且就是本轮随机生成的,丢弃之
if (percent(10))
continue;// 继承下来的神经元,但是本轮并没用到, 扔掉又可惜,可以小概率丢掉
}
CellGroup cellGroup = new CellGroup();
egg.cellgroups[i] = cellGroup;
cellGroup.groupInputZone = new Zone(r.nextFloat() * BRAIN_WIDTH, r.nextFloat() * BRAIN_WIDTH,
(float) (r.nextFloat() * BRAIN_WIDTH * .01));
cellGroup.groupOutputZone = new Zone(r.nextFloat() * BRAIN_WIDTH, r.nextFloat() * BRAIN_WIDTH,
(float) (r.nextFloat() * BRAIN_WIDTH * .01));
cellGroup.cellQty = r.nextInt(egg.randomCellQtyPerGroup);
cellGroup.cellInputRadius = (float) (r.nextFloat() * 0.001);
cellGroup.cellOutputRadius = (float) (r.nextFloat() * 0.001);
cellGroup.inputQtyPerCell = r.nextInt(egg.randomInputQtyPerCell);
cellGroup.outputQtyPerCell = r.nextInt(egg.randomOutQtyPerCell);
CellGroup oldGp = frog.cellGroups[i];
cellGroup.groupInputZone = new Zone(percet2(oldGp.groupInputZone.x), percet2(oldGp.groupInputZone.y),
percet2(oldGp.groupInputZone.radius));
cellGroup.groupOutputZone = new Zone(percet2(oldGp.groupOutputZone.x), percet2(oldGp.groupOutputZone.y),
percet2(oldGp.groupOutputZone.radius));
cellGroup.cellQty = Math.round(percet2(oldGp.cellQty));
cellGroup.cellInputRadius = percet1(oldGp.cellInputRadius);
cellGroup.cellOutputRadius = percet1(oldGp.cellOutputRadius);
cellGroup.inputQtyPerCell = Math.round(percet2(oldGp.inputQtyPerCell));
cellGroup.outputQtyPerCell = Math.round(percet2(oldGp.outputQtyPerCell));
cellGroup.inherit = true;
gpList.add(cellGroup);
}
egg.realCellGroupQty=egg.cellgroups.length;
return egg;
cellGroups = gpList.toArray(new CellGroup[gpList.size()]);
}
}

@ -29,7 +29,7 @@ public class Application {
if (SHOW_FIRST_FROG_BRAIN)
mainFrame.setSize(1320, 840); // 窗口大小
else
mainFrame.setSize(550, 550); // 窗口大小
mainFrame.setSize(550, 570); // 窗口大小
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭时退出程序
mainFrame.add(env);
@ -48,14 +48,31 @@ public class Application {
mainFrame.setSize(1320, 840);
} else {
button.setText("Show first frog's brain");
mainFrame.setSize(550, 550);
mainFrame.setSize(550, 570);
}
}
};
button.addActionListener(al);
mainFrame.add(button);
JButton stopButton = new JButton("Pause");
stopButton.setVisible(true);
stopButton.setLayout(null);// 空布局
stopButton.setBounds(150, 490, 180, 30);
ActionListener a2 = new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Env.pause = !Env.pause;
if (Env.pause) {
stopButton.setText("Resume");
} else {
stopButton.setText("Pause");
}
}
};
stopButton.addActionListener(a2);
mainFrame.add(stopButton);
mainFrame.setVisible(true);
env.run();

@ -27,13 +27,17 @@ public class BrainStructure extends JPanel {
g.drawRect(round(z.x - z.radius), round(z.y - z.radius), round(z.radius * 2), round(z.radius * 2));
}
void drawZoneCircle(Graphics g, Zone z) {
g.drawArc(round(z.x - 8), round(z.y - 8), 16, 16, 0, 360);
}
void fillZone(Graphics g, Zone z) {
g.fillRect(round(z.x - z.radius), round(z.y - z.radius), round(z.radius * 2), round(z.radius * 2));
}
private static Color color(float i) {
if (i <= 1)
return Color.GRAY;
return Color.RED;
if (i <= 3)
return Color.ORANGE;
if (i <= 10)
@ -50,36 +54,41 @@ public class BrainStructure extends JPanel {
public void drawBrain(Frog frog) {
if (!Application.SHOW_FIRST_FROG_BRAIN)
return;
Graphics g = this.getGraphics();
Graphics g = this.getGraphics();// border
g.setColor(Color.WHITE);
g.fillRect(0, 0, 800, 800);
g.setColor(Color.black);
g.drawRect(0, 0, 800, 800);
g.setColor(Color.red);
drawZone(g, frog.eye);
drawZone(g, frog.eye); // eye
g.setColor(Color.green);
drawZone(g, frog.happy);
drawZone(g, frog.happy); // happy
g.setColor(Color.yellow);
drawZone(g, frog.hungry);
drawZone(g, frog.hungry); // hungry
g.setColor(Color.gray);
drawZone(g, frog.moveUp);
drawZone(g, frog.moveUp); // moves
drawZone(g, frog.moveDown);
drawZone(g, frog.moveLeft);
drawZone(g, frog.moveRight);
g.setColor(Color.black);
for (int j = 0; j < frog.egg.realCellGroupQty; j++) {
CellGroup group = frog.egg.cellgroups[j];
g.setColor(color(group.cellQty));// 取随机色
for (CellGroup group : frog.cellGroups) {
if (!group.inherit)
g.setColor(Color.lightGray); // 如果是本轮随机生成的,灰色表示
else
g.setColor(color(group.cellQty)); // 如果是继承的,彩虹色表示,颜色数越往后表示数量越多
g.drawLine(round(group.groupInputZone.x), round(group.groupInputZone.y), round(group.groupOutputZone.x),
round(group.groupOutputZone.y));
drawZone(g, group.groupInputZone);
fillZone(g, group.groupOutputZone);
if (group.fat > 0) {
g.setColor(Color.BLACK);
drawZoneCircle(g, group.groupOutputZone); // 如果胖了,表示激活过了,下次下蛋少不了这一组
}
}
}

@ -32,6 +32,8 @@ public class Env extends JPanel {
EggTool.deleteEggs();
}
public static boolean pause = false;
private static final Random r = new Random();
/** Virtual environment x size is 500 pixels */
@ -42,7 +44,7 @@ public class Env extends JPanel {
public byte[][] foods = new byte[ENV_XSIZE][ENV_YSIZE];
public int FOOD_QTY =800; // as name
public int FOOD_QTY = 1800; // as name
public int EGG_QTY = 50; // as name
@ -87,6 +89,15 @@ public class Env extends JPanel {
}
}
private static void sleep() {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() throws InterruptedException {
EggTool.loadEggs(this); // 从磁盘加载egg或新建一批egg
int round = 1;
@ -94,6 +105,10 @@ public class Env extends JPanel {
Graphics g = buffImg.getGraphics();
long t1, t2;
do {
if (pause) {
sleep();
continue;
}
t1 = System.currentTimeMillis();
rebuildFrogAndFood();
boolean allDead = false;
@ -119,10 +134,12 @@ public class Env extends JPanel {
Graphics g2 = this.getGraphics();
g2.drawImage(buffImg, 0, 0, this);
}
EggTool.layEggs(this);
Application.brainStructure.drawBrain(frogs.get(0));
t2 = System.currentTimeMillis();
Application.mainFrame.setTitle("Frog test round: " + round++ + ", time used: " + (t2 - t1) + " ms");
Application.mainFrame.setTitle("Frog test round: " + round++ + ", time used: " + (t2 - t1) + " ms, x="
+ frogs.get(0).x + ", y=" + frogs.get(0).y);
} while (true);
}
}

@ -40,14 +40,15 @@ public class EggTool {
*/
public static void layEggs(Env env) {
sortFrogsOrderByEnergyDesc(env);
System.out.print("First frog has " + env.frogs.get(0).egg.cellgroups.length + " cellgroups, energy="
System.out.print("First frog has " + env.frogs.get(0).cellGroups.length + " cellgroups, energy="
+ env.frogs.get(0).energy);
System.out.print(", Last frog energy=" + env.frogs.get(env.frogs.size() - 1).energy + ", ");
try {
List<Egg> newEggs = new ArrayList<Egg>();
for (int i = 0; i < env.EGG_QTY; i++)
newEggs.add(env.frogs.get(i).layEgg());
newEggs.add( new Egg(env.frogs.get(i), true));
System.out.print(", EggCellGroups="+newEggs.get(0).cellGroups.length);
if (JSON_FILE_FORMAT) {
String newEggsString = JSON.toJSONString(newEggs);
FrogFileUtils.writeFile(Application.CLASSPATH + "eggs.json", newEggsString, "utf-8");
@ -59,7 +60,7 @@ public class EggTool {
}
env.eggs = newEggs;
System.out
.println("Saved " + env.eggs.size() + " eggs to file '" + Application.CLASSPATH + "eggs.ser" + "'");
.println(" Saved " + env.eggs.size() + " eggs to file '" + Application.CLASSPATH + "eggs.ser" + "'");
} catch (IOException e) {
System.out.println(e);
}

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

@ -18,8 +18,10 @@
在脑区添加Hungry删除随机运动的硬编码改成由Hungry区来驱动一旦frog能量小于10000,hungry区的所有脑神经元的input区激活如果这些神经元的输出区位于move区则作相应的移动。这是一个更随机一点的运动不再总是固定向一个方向。
### 2019-03-27, 1.0.3版, Commit:Shrink & Sperm
添加了"蛋+精子->受精蛋"的模拟,这是为了实现生物多样性。添加了每次添加一批随机神经元,但是只保留激活过的,如果某组神经元从没被用到(激活过),则有很大的可能不会将这组神经元添加到蛋中(用进废退规则)。
添加了"卵+精子->受精卵"的模拟,这是为了实现生物多样性。添加了每次添加一批随机神经元,但是只保留激活过的,如果某组神经元从没被用到(激活过),则有很大的可能不会将这组神经元添加到蛋中(用进废退规则)。
### 2019-03-29, Commit:Rainbow
更正一个小Bug,BrainStructure的zone显示的半径是实际的一半用彩虹色而不是随机数来表示CellGroup的细胞数量色彩越靠后表示细胞数越多。
### 2019-04-01, Commit:Cleanup
做一些debug清理,每个Frog不再保留egg的副本“卵+精子->受精卵”算法改进一下不能简单两两相加而是随机取一个精子的cellgroup。

Loading…
Cancel
Save