Copy 2D 003b logic to 3D core folder

pull/2/head
drinkjava2 5 years ago
parent e7b33a3b16
commit f67a1a0f5d

File diff suppressed because one or more lines are too long

@ -1,5 +1,4 @@
## Frog | 人工生命
(Engish instruction see README_EN.md)
这是一个人工生命试验项目最终目标是创建“有自我意识表现”的模拟生命体技术架构基于02年提出的 [一个人工脑模型](一个人工脑模型.md)。
这个项目永远没有结束的时候,开始于模拟一个简单的生命体,然后是青蛙、狗......, 结束于有“自我意识表现”的人工脑,或者说,结束于被机器人代替人类的那一天。
@ -90,9 +89,11 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
上次提交有个大bug有多个字母出现时将不能区分这次提交更正过来。到此为止基本完成了模式识别的原理验证过程即如果字母的象素点与训练图片的重点合越多则听力区收到的反向红色光子数就越多这是一个简单、直观的模式识别方法以后可以通过将声音分成多个小区编码并统计每个区收到多少反向的光子总数来判断是哪个字母图像输入。原理验证比较枯燥但这个模式识别功能是无法绕过去的一旦原理被证实以后就可以有意地引导或者说设计青蛙向这个方向进化而不是由手工来搭建包含模式识别功能的脑模型因为一来要减少手工的干预,硬编码越少越好,尽量利用随机变异、生存竟争这个电脑工具,二来这个原理不光是模式识别要用到,其它信号处理(如快感、痛觉信号与行为信号之间的关联)都要用到类似的细胞级逻辑,因为我一直在强调“任意两个时间上相关的信号,大脑总会将它们关联起来,这是条件反射行为建立的基础”。
另外,这次更新加强了暂停功能,可以在脑图任一时刻暂停,并加上了脑图的剖面显示。所有脑图快捷键有: T:顶视 F前视 L:左视 R:右视 X:斜视 方向键:剖视 空格:暂停 鼠标操作:缩放旋转平移
![result6](https://gitee.com/drinkjava2/frog/raw/master/result6_letter.gif)
2019-11-26 优化了一下程序用8个汉字来进行模式识别原理演示但容错性依然没有变形、变位后的文字识别率很差。以后要考虑借签算法中的侧抑制、卷积、分层等原理来提高它的容错性这方面算法已经很成熟了目前只需要拿来主义用图形化模拟的方式来实现。但总体上算法和图形化模拟是两条路算法通常可以用模拟的方式来表达但不是所有模拟都可以归纳成算法因为模拟(或者说软件本身)有时会非常复杂,不容易总结出规律。也就是说模拟的表现力比算法更强,但模拟的缺点是资源消耗大。
2019-12-27 在history\003a_legs目录下依然是2维脑)尝试给青蛙加两条腿看它能不能自动学会走路。一条腿位于下方负责左右移动一条腿位于右侧负责上下移动每条腿有抬腿、落腿、转动和相应的感觉细胞。只有当腿落下且转动而且另一条脚抬起来时青蛙才会位移具体什么时候抬腿、什么时候转动腿完全由随机数决定。经过一段时间的生存汰淘之后青蛙会进化出会利用两条腿走路了但需要的时间非常长约几个小时之后才达到最高吃食率50%左右,走路风格也比较诡异,是小碎步而不是大踏步。但至少这是青蛙第一次利用两条腿来走路,还是有点意义的,这证明生命进化中就算神经元随机排布,进化出眼睛和腿也是非常简单自然的事。
2020-05-04 在进行3维脑改造过程中发现找食率很低发现自己也看不懂以前的程序怎么编的了所以又添加一个history\003b_simple目录把2维脑简化一下去掉不重要的器官好仔细分析它的逻辑。
2019-11-26 优化了一下程序,用"对酒当歌人生几何"8个汉字来进行模式识别原理演示但容错性依然没有变形、变位后的文字识别率很差。以后要考虑借签算法中的侧抑制、卷积、分层等原理来提高它的容错性用图形化模拟的方式来实现。总体上算法和图形化模拟是两条路算法通常可以用模拟的方式来表达但不是所有模拟都可以归纳成算法因为模拟(或者说软件本身)有时会非常复杂,不容易总结出规律。也就是说模拟的表现力比算法更强,但模拟的缺点是资源消耗大。
2019-12-27 开始设立history目录给主要的版本直接在history目录下创建副本以方便运行。在history\003a_legs目录下依然是2维脑)尝试给青蛙加两条腿看它能不能自动学会走路。一条腿位于下方负责左右移动一条腿位于右侧负责上下移动每条腿有抬腿、落腿、转动和相应的感觉细胞。只有当腿落下且转动而且另一条脚抬起来时青蛙才会位移具体什么时候抬腿、什么时候转动腿完全由随机数决定。经过一段时间的生存汰淘之后青蛙会进化出会利用两条腿走路了但需要的时间非常长约几个小时之后才达到最高吃食率50%左右,走路风格也比较诡异,是小碎步而不是大踏步。但至少这是青蛙第一次利用两条腿来走路,还是有点意义的,这证明生命进化中就算神经元随机排布,进化出眼睛和腿也是非常简单自然的事。
2020-05-04 在进行3维脑改造过程中发现找食率很低发现自己也看不懂以前的程序怎么编的了所以在history目录下又添加一个003b_simple目录把2维脑简化一下去掉不重要的器官好仔细分析它的逻辑。
2020-05-07 经过一番折腾和走弯路之后最后还是原汁原味地将2维脑003b目录的逻辑搬到了3维脑core目录里了实现了同样的找食率(~50%左右)。从现在开始可以专注于改进3D脑本身了。另外README_ENG.md和开发思路.md这两个不重要的文档不再提交到码云。
## 运行方式 | Run
运行core或history各个子目录下的run.bat批处理文件即可启动运行history下有多个子目录按时间顺序按列存放着这个项目演化过程中的主要历史版本供演示。

@ -100,6 +100,7 @@ public class Application {
@Override
public void stateChanged(ChangeEvent e) {
Env.SHOW_SPEED = speedSlider.getValue() * speedSlider.getValue() * speedSlider.getValue();
brainPic.requestFocus();
}
};
speedSlider.addChangeListener(slideAction);

@ -39,9 +39,9 @@ public class Env extends JPanel {
public static final int FROG_PER_SCREEN = EGG_QTY * FROG_PER_EGG / SCREEN; // 每屏上显示几个青蛙,这个数值由上面三个参数计算得来
/** Frog's brain size is a 3D array of Cell */ // 脑空间是个三维Cell数组为节约内存仅在用到数组元素时才去初始化这维按需分配内存
public static final int FROG_BRAIN_XSIZE = 20; // frog的脑在X方向长度
public static final int FROG_BRAIN_YSIZE = 20; // frog的脑在Y方向长度
public static final int FROG_BRAIN_ZSIZE = 20; // frog的脑在Z方向长度
public static final int FROG_BRAIN_XSIZE = 1000; // frog的脑在X方向长度
public static final int FROG_BRAIN_YSIZE = 1000; // frog的脑在Y方向长度
public static final int FROG_BRAIN_ZSIZE = 1000; // frog的脑在Z方向长度
/** SHOW first frog's brain structure */
public static boolean SHOW_FIRST_FROG_BRAIN = true; // 是否显示脑图在Env区的右侧
@ -59,7 +59,7 @@ public class Env extends JPanel {
public static final int FROG_BRAIN_DISP_WIDTH = 600; // Frog的脑图在屏幕上的显示大小,可调
/** Steps of one test round */
public static final int STEPS_PER_ROUND = 4000;// 每轮测试步数,可调
public static final int STEPS_PER_ROUND = 2000;// 每轮测试步数,可调
public static int step;// 当前测试步数
public static final int FOOD_QTY = 1500; // 食物数量, 可调

@ -19,7 +19,6 @@ import java.util.List;
import javax.imageio.ImageIO;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.brain.organ.Line;
import com.github.drinkjava2.frog.egg.Egg;
@ -40,7 +39,7 @@ import com.github.drinkjava2.frog.util.RandomUtils;
*/
public class Frog {// 这个程序大量用到public变量而不是getter/setter主要是为了编程方便和简洁但缺点是编程者需要小心维护各个变量
/** brain cells */
public Cell[][][] cells;// 一开始不要初始化只在调用getOrCreateCell方法时才初始化相关维以节约内存
public List<Cell> cells = new ArrayList<>();
/** organs */
public List<Organ> organs = new ArrayList<>();
@ -68,25 +67,15 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
}
public void initFrog() { // 初始化frog,通常只是调用每个organ的init方法
for (int orgNo = 0; orgNo < organs.size(); orgNo++) {
organs.get(orgNo).init(this, orgNo);
// energy -= 1; // organ 增多需要消耗能量
}
// Cell c1 = this.findFirstCellByClass(Active.class);
// Cell c2 = this.findFirstCellByClass(MoveUp.class);
// organs.add(new Line(c1, c2));
for (Organ org : organs)
org.initFrog(this);// 每个新器官初始化如果是Group类它们会生成许多脑细胞
}
public void addRandomLines() {// 有一定机率在器官间生成随机的神经连线
if (RandomUtils.percent(0.2f)) {
Cell c1 = RandomUtils.getRandomCell(this);
if (c1 == null)
return;
Cell c2 = RandomUtils.getRandomCell(this);
if (c2 == null || c1 == c2)
return;
organs.add(new Line(c1, c2));
if (alive && RandomUtils.percent(0.2f)) {// 有很小的机率在青蛙活着时就创建新的器官
Line line = new Line();
organs.add(line);
line.initFrog(this);
}
}
@ -98,10 +87,13 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
return false;
}
energy -= 20;
// 依次调用每个器官的active方法每个器官各自负责调用各自区域通常是Cuboid)内的细胞的行为
for (Organ o : organs)
o.active(this);
addRandomLines(); // 有一定机率在器官间生成随机的神经连线
// 依次调用每个organ的active方法
for (Organ organ : organs)
organ.active(this);
// 依次调用每个cell的active方法这是写在organ类里的方法因为同一个器官的cell具有相同的行为
for (Cell cell : cells)
cell.organ.active(this, cell);
addRandomLines();
return alive;
}
@ -119,45 +111,6 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
return null;
}
public Cell findFirstCellByClass(Class<?> claz) {// 根据器官名寻找器官,但不是每个器官都有名字
Organ o = findOrganByClass(claz);
Cuboid c = (Cuboid) o.shape;
return this.getCell(c.x, c.y, c.z);
}
/** Check if cell exist */
public Cell getCell(int x, int y, int z) {// 返回指定脑ssf坐标的cell 如果不存在返回null
if (cells == null || cells[x] == null || cells[x][y] == null)
return null;
return cells[x][y][z];
}
public Cell getCell1(Line l) {
return cells[l.x1][l.y1][l.z1];
}
public Cell getCell2(Line l) {
return cells[l.x2][l.y2][l.z2];
}
/** Get a cell in position (x,y,z), if not exist, create a new one */
public Cell getOrCreateCell(int x, int y, int z) {// 获取指定坐标的Cell如果为空则在指定位置新建Cell
if (outBrainRange(x, y, z))
throw new IllegalArgumentException("x,y,z postion out of range, x=" + x + ", y=" + y + ", z=" + z);
if (cells == null)
cells = new Cell[Env.FROG_BRAIN_XSIZE][][];
if (cells[x] == null)
cells[x] = new Cell[Env.FROG_BRAIN_YSIZE][];
if (cells[x][y] == null)
cells[x][y] = new Cell[Env.FROG_BRAIN_ZSIZE];
Cell cell = cells[x][y][z];
if (cell == null) {
cell = new Cell(x, y, z);
cells[x][y][z] = cell;
}
return cell;
}
/** Check if x,y,z out of frog's brain range */
public static boolean outBrainRange(int x, int y, int z) {// 检查指定坐标是否超出frog脑空间界限
return x < 0 || x >= Env.FROG_BRAIN_XSIZE || y < 0 || y >= Env.FROG_BRAIN_YSIZE || z < 0

@ -20,7 +20,6 @@ import javax.swing.JPanel;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.organ.Line;
import com.github.drinkjava2.frog.util.ColorUtils;
/**
@ -124,6 +123,28 @@ public class BrainPicture extends JPanel {
this.setFocusable(true);
}
public void drawZone(Zone o) {// 在脑图上画一个正立方体Zone框架视角是TopView
float x = o.x - o.r;
float y = o.y - o.r;
float z = o.z - o.r;
float e = o.r + o.r;
drawLine(x, y, z, x + e, y, z);// 画立方体的下面边
drawLine(x + e, y, z, x + e, y + e, z);
drawLine(x + e, y + e, z, x, y + e, z);
drawLine(x, y + e, z, x, y, z);
drawLine(x, y, z, x, y, z + e);// 画立方体的中间边
drawLine(x + e, y, z, x + e, y, z + e);
drawLine(x + e, y + e, z, x + e, y + e, z + e);
drawLine(x, y + e, z, x, y + e, z + e);
drawLine(x, y, z + e, x + e, y, z + e);// 画立方体的上面边
drawLine(x + e, y, z + e, x + e, y + e, z + e);
drawLine(x + e, y + e, z + e, x, y + e, z + e);
drawLine(x, y + e, z + e, x, y, z + e);
}
public void drawCuboid(Cuboid c) {// 在脑图上画一个长立方体框架视角是TopView
float x = c.x;
float y = c.y;
@ -148,21 +169,17 @@ public class BrainPicture extends JPanel {
drawLine(x, y + ye, z + ze, x, y, z + ze);
}
public void drawCone(Cone c) {// 在脑图上画一个锥体视角是TopView
drawLine(c.x1, c.y1, c.z1, c.x2, c.y2, c.z2);// 画锥体的中心线
// TODO 画出锥体的上下面
}
/**
* cell c1线cell c2
*/
public void drawLine(Cell c1, Cell c2) {
drawLine(c1.x + .5f, c1.y + .5f, c1.z + .5f, c2.x + .5f, c2.y + .5f, c2.z + .5f);
}
public void drawCell(Cell c) {// 从zone1到z2中心画一条线
if (c == null)
return;
if (c.body != null) {
drawZone(c.body);
if (c.input != null)
drawLine(c.input.x, c.input.y, c.input.z, c.body.x, c.body.y, c.body.z);
if (c.output != null)
drawLine(c.output.x, c.output.y, c.output.z, c.body.x, c.body.y, c.body.z);
}
/** 将Line对象在pic上画一条线 */
public void drawLine(Line l) {
drawLine(l.x1 + .5f, l.y1 + .5f, l.z1 + .5f, l.x2 + .5f, l.y2 + .5f, l.z2 + .5f);
}
/*-
@ -227,11 +244,8 @@ public class BrainPicture extends JPanel {
(int) round(y2) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset);
}
/** 画出cell的中心点 */
public void drawCellCenter(float x, float y, float z, float diameter) {
if (x > 0 && (x < xMask || y < yMask))
return;
drawPoint(x + 0.5f, y + 0.5f, z + 0.5f, (int) Math.max(2, Math.round(scale * diameter)));
public void drawLine(Zone a, Zone b) {
drawLine(a.x, a.y, a.z, b.x, b.y, b.z);
}
/** 画点固定以top视角的角度所以只需要在x1,y1位置画一个点 */
@ -264,7 +278,7 @@ public class BrainPicture extends JPanel {
}
public void drawText(float px1, float py1, float pz1, String text) {
drawText(px1, py1, pz1, text, 1);
drawText(px1, py1, pz1, text, 12);
}
public void drawText(float px1, float py1, float pz1, String text, float textSize) {
@ -291,7 +305,7 @@ public class BrainPicture extends JPanel {
y1 = y;
g.setColor(picColor);
g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, (int) round(textSize * scale * .3)));
g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, (int) round(textSize * scale)));
g.drawString(text, (int) round(x1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + xOffset,
(int) round(y1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset);
@ -310,9 +324,9 @@ public class BrainPicture extends JPanel {
g.drawRect(0, 0, brainDispWidth, brainDispWidth);
setPicColor(BLACK);
drawCuboid(brain);// 先把脑的框架画出来
drawText(1, 0, 0, "x");
drawText(0, 1, 0, "y");
drawText(0, 0, 1, "z");
drawText(100, 0, 0, "x");
drawText(0, 100, 0, "y");
drawText(0, 0, 100, "z");
for (Organ organ : f.organs)// 每个器官负责画出自已在脑图中的位置和形状
organ.drawOnBrainPicture(f, this); // each organ draw itself
@ -321,19 +335,14 @@ public class BrainPicture extends JPanel {
drawLine(0, 0, 0, 0, 1, 0);
drawLine(0, 0, 0, 0, 0, 1);
for (int x = 0; x < Env.FROG_BRAIN_XSIZE; x++) {// 开始画整个脑空间的细胞活跃分布图
if (f.cells != null && f.cells[x] != null)
for (int y = 0; y < Env.FROG_BRAIN_YSIZE; y++) {
if (f.cells[x][y] != null)
for (int z = 0; z < Env.FROG_BRAIN_ZSIZE; z++) {
Cell cell = f.getCell(x, y, z);
if (cell != null && cell.energy > 20) {
setPicColor(ColorUtils.grayColor(cell.energy));// 用灰度表示活跃度
drawCellCenter(x, y, z, 0.6f);
}
}
}
for (Cell cell : f.cells) {
if (cell != null && cell.energy > 20) {
setPicColor(ColorUtils.grayColor(cell.energy));// 用灰度表示活跃度
if (cell.body != null)
drawZone(cell.body);
}
}
g.setColor(Color.black);
if (note != null) // 全局注释
g.drawString(note, 30, 55);

@ -10,72 +10,27 @@
*/
package com.github.drinkjava2.frog.brain;
import java.io.Serializable;
import java.util.Arrays;
/**
* Cell is the smallest unit of brain space, a Cell can have many actions and
* photons and holes and relations
*
* Cell(organs)(Photon)Hole)(Relation)frogcells
*
*
* CellCellActionsCell
*
* JellyMoveJelly,hole)
* ()(线)
* 沿线,
* hebb
*
*
* 2020-2-28A
* B
* Cell is the basic unit of frog's brain
*
* @author Yong Zhu
* @since 1.0
*/
public class Cell implements Serializable {
private static final long serialVersionUID = 1L;
public int x;
public int y;
public int z;
public float energy = 0;
public Cell(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int[] organs = null; // 每个Cell可以被多个Organ登记这里保存organ在蛋里的序号
public class Cell {
public static final float MAX_ENERGY_LIMIT = 100.0f;
public Hole[] holes = null;// 洞(即动态突触),洞由光子产生,洞由时间抹平,洞的角度本身就是关联关系,角度越大,关联关系越大
// this cell belong to frog's which organ
public Organ organ;
public void regOrgan(int orgNo) {// 每个Cell可以被多个Organ登记通常只在青蛙初始化器官时调用这个方法
if (organs == null)
organs = new int[1];
else
organs = Arrays.copyOf(organs, organs.length + 1);
organs[organs.length - 1] = orgNo;
}
// inputs of cell
public Zone input; // 每个细胞有一个输入触突
public boolean inActive() {
if (energy > 30) {
energy -= 30;
return true;
}
return false;
}
// outputs of cell
public Zone output; // 每个细胞有一个输出触突
public void addEnergy(float e) {
energy += e;
if (energy > 1000)
energy = 1000;
}
// body of cell
public Zone body; // 每个细胞有一个本体用来接受其它cell的信号
public void subEnergy(float e) {
energy -= e;
if (energy < 0)
energy = 0;
}
// energy of cell, energy got from food
public float energy; // 每个细胞当前的能量值
}

@ -1,62 +0,0 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.Frog;
/**
* Cone represents a cone 3d zone in brain
*
* Cone()Cuboid.
*
* @author Yong Zhu
* @since 2.0.2
*/
@SuppressWarnings("all")
public class Cone implements Shape {
private static final long serialVersionUID = 1L;
public int x1; // 这6个变量定义了Cone的中心线起点和终点,器官不能拐弯,但拐弯可以用一个锥体分成两个首尾相接的锥体再进一步变异演化出来
public int y1;
public int z1;
public int x2;
public int y2;
public int z2;
public int r1 = 8; // 起点的半径,为了简化编程,通常是是指起点矩形边长的一半,因为圆形计算麻烦
public int r2 = 8; // 终点的半径
public Cone() {
// 空构造器不能省
}
public Cone(int x1, int y1, int z1, int x2, int y2, int z2, int r1, int r2) {// 用x,y,z,r来构造
this.x1 = x1;
this.y1 = y1;
this.z1 = z1;
this.x2 = x2;
this.y2 = y2;
this.z2 = z2;
this.r1 = r1;
this.r2 = r2;
}
@Override
public void drawOnBrainPicture(BrainPicture pic) {
pic.drawCone(this);
}
@Override
public void createCellsRegOrgan(Frog f, int o) {
// TODO 待添加Cone形器官播种脑细胞的代码
}
}

@ -10,8 +10,6 @@
*/
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.Frog;
/**
* Cuboid represents a rectangular prism 3d zone in brain
*
@ -58,21 +56,4 @@ public class Cuboid implements Shape {
pic.drawCuboid(this);
}
@Override
public void createCellsRegOrgan(Frog f, int orgNo) {// 创建Cell并登记Organ 先忽略密度分布等参数
for (int i = x; i < x + xe; i++)
for (int j = y; j < y + ye; j++)
for (int k = z; k < z + ze; k++) {
Cell cell = f.getOrCreateCell(i, j, k);
if (cell != null)
cell.regOrgan(orgNo);
}
}
public void createCells(Frog f) {// 创建Cell 先忽略密度分布等参数
for (int i = x; i < x + xe; i++)
for (int j = y; j < y + ye; j++)
for (int k = z; k < z + ze; k++)
f.getOrCreateCell(i, j, k);
}
}

@ -1,55 +0,0 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain;
/**
* Hole is a hole on jelly cell, it works like synapse on nerve cell
*
*
*
* @author Yong Zhu
* @since 2.0.2
*/
public class Hole {
public float x;// x,y,z 是 洞的中心坐标点,这个是脑内的绝对坐标
public float y;
public float z;
public float mx; // mx,my,mz分别是光子砸出这个洞时的光子每单元移动方向在三个轴上的投影
public float my;
public float mz;
public float size = 0;// 洞的大小收到光子会变大1.1倍直到饱和,平时会沿指数曲线消失
public Hole(Photon p) {
this.x = p.x;
this.y = p.y;
this.z = p.z;
this.mx = p.mx;
this.my = p.my;
this.mz = p.mz;
}
public float angleCompare(Hole p) {// 比较洞与光子之间的角度差值
return Math.abs(p.mx - mx) + Math.abs(p.my - my) + Math.abs(p.mz - mz);
}
public float angleCompare(Photon p) {// 比较洞与光子之间的角度差值
return Math.abs(p.mx - mx) + Math.abs(p.my - my) + Math.abs(p.mz - mz);
}
public boolean ifSameWay(Photon p) {// 如果光子运动方向与洞完全同向,实际上也就是说从同一个波源发出来的
return Math.abs(p.mx - mx) < 0.0001 && Math.abs(p.my - my) < 0.0001 && Math.abs(p.mz - mz) < 0.0001;
}
public boolean ifSimilarWay(Photon p) {// 如果光子运动方向与洞近似相同
return Math.abs(p.mx - mx) < 0.05 && Math.abs(p.my - my) < 0.05 && Math.abs(p.mz - mz) < 0.05;
}
}

@ -11,104 +11,95 @@
package com.github.drinkjava2.frog.brain;
import java.awt.Color;
import java.io.Serializable;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Organ is a cone-cylinder shape zone inside of brain,, organ can be saved in
* egg organ will create cells in brain. Most organ's size, angle, location and
* cell parameters are randomly created
*
*
*
*
* ,
*
*
*
*
*
* )
*
* Cell,
* Cell
* Organ is a part of frog, organ can be saved in egg
*
*
*
* @author Yong Zhu
* @since 1.0.4
*/
public class Organ implements Serializable, Cloneable {// 因为要保存在蛋文件里,所以必须支持串行化
public class Organ extends Zone {
private static final long serialVersionUID = 1L;
public String name; // 显示在脑图上的器官名称,可选
public long fat = 0; // 如果活跃多fat值高则保留及变异的可能性大反之则很可能丢弃掉
// public float organWasteEnergy = 0.05f; //
// 器官在每个测试循环中需要消耗青蛙多少能量,可以通过调节这个参数抑制器官数量无限增长
public float organActiveEnergy = 1; // 输出器官激活需要消耗每个脑细胞多少能量
public float organOutputEnergy = 2; // 感觉器官激活会给每个脑细胞增加多少能量
public boolean initilized; // 通过这个标记判断是否需要手工给定它的参数初值
// 以下是各种器官类型每个神经元都属于一个器官每个器官都有一个type类型参数
public float fat = 0;// 细胞活跃多则fat值大如果fat值很低则这个器官被丢弃的可能性加大这个值很重要它使得孤岛器官被淘汰
public boolean allowVary;// 是否允许变异,有一些器官是手工创建的,在项目初级阶段禁止它们参与变异和生存竟争。
public boolean allowBorrow;// 是否允许在精子中将这个器官借出,有一些器官是手工创建的,在项目初级阶段禁止它们借出
public String organName = this.getClass().getSimpleName();;// 器官的名字通常只有手工创建的器官才有名字可以用frog.findOrganByName来查找到这个器官
public Shape shape; // 器官的形状,不同的形状要写出不同的播种行为
/** Only call once after organ be created */
public Organ[] vary(Frog f) { // 器官变异仅会在青蛙下蛋时即new Egg(frog)中被调用一次,返回本身或变异后的一个或一组类似器官返回
if (!allowVary)
return new Organ[] { this };// 如果不允许变异,器官就把自身返回,存放在蛋里
// 各参数 随机有大概率小变异,小概率大变异,极小概率极大变异
shape = RandomUtils.vary(shape);
return new Organ[] { this };
public boolean allowBorrow() { // 是否允许在精子中将这个器官借出
return false;
}
/** Only call once when frog created , Child class can override this method */
public void init(Frog f, int orgNo) { // 在青蛙生成时会调用这个方法,进行一些初始化,通常是根据参数来播种脑细胞
// 里是器官播种脑细胞的具体代码,对于手工生成的器官也可以重写这个方法对于自动生成的器官必须根据type和shape等来播种要写死在这里
if (shape != null)
shape.createCellsRegOrgan(f, orgNo); // 先均匀播种脑细胞试试
public void initFrog(Frog f) { // 仅在Frog生成时会调用一次
}
/** each step will call Organ's active methodd */
public void active(Frog f) {// 每一步测试都会调用active方法它通常遍历每个细胞调用它们的cellAct方法
// 这里是缺省的方法体,只针对最常见的形状为长方体的器官,子类可以重写这个方法
if (!f.alive || shape == null || shape.getClass() != Cuboid.class)
return;
Cuboid c = (Cuboid) shape;
for (int px = 0; px < c.xe; px++)
for (int py = 0; py < c.ye; py++)
for (int pz = 0; pz < c.ze; pz++) {
cellAct(f, f.getCell(c.x + px, c.y + py, c.z + pz));
/** Each loop step call active method, Child class can override this method */
public void active(Frog f) { // 这是器官级别的方法,每个步长调用一次
}
/** Each loop step call active method, Child class can override this method */
public void active(Frog f, Cell c) { // 这是Cell级别的方法每个步长、每个细胞都要调用一次
}
/** If active in this organ's zone? */
public boolean outputActive(Frog f) { // 如果一个细胞能量>10,且它的输出触突位于这个器官内,则器官被激活
for (Cell cell : f.cells)
if (cell.energy > organActiveEnergy)
if (this.nearby(cell.output)) {
cell.organ.fat++;
cell.energy -= 30;//
return true;
}
return false;
}
/** If active in this organ's zone? */
public void activeInput(Frog f, float energy) { // 如果一个细胞能量>10,且它的输出触突位于这个器官内,则器官被激活
for (Cell cell : f.cells)
if (cell.energy < 100)
if (this.nearby(cell.input)) {
cell.energy += energy;
return;
}
}
/** each step will call Organ's active methodd */
public void cellAct(Frog f, Cell c) { // 每个细胞都会调用cellAct方法,这是针对细胞级别的方法,子类要覆盖它
/** Set X, Y, Radius, name of current Organ */
public Organ setXYZRN(float x, float y, float z, float r, String name) {
this.setXYZR(x, y, z, r);
this.name = name;
return this;
}
/** Child class can override this method to drawing picture */
public void drawOnBrainPicture(Frog f, BrainPicture pic) { // 把器官的轮廓显示在脑图上,子类可以重写这个方法
if (!Env.SHOW_FIRST_FROG_BRAIN || !f.alive || shape == null) // 如果不允许画或青蛙死了或没形状,就直接返回
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法
if (!Env.SHOW_FIRST_FROG_BRAIN)
return;
pic.setPicColor(Color.LIGHT_GRAY); // 缺省是灰色
shape.drawOnBrainPicture(pic);
if (this.organName != null && this.shape.getClass() == Cuboid.class) {
int x = ((Cuboid) shape).x;
int y = ((Cuboid) shape).y;
int z = ((Cuboid) shape).z;
pic.drawText(x, y, z, this.organName);
}
pic.setPicColor(Color.BLACK); // 缺省是黑色
pic.drawZone(this);
if (this.name != null)
pic.drawText(x, y, z, String.valueOf(this.name));
}
pic.setPicColor(Color.RED);
if (this.shape.getClass() == Cuboid.class) { // 显示每个细胞的能量
Cuboid c = (Cuboid) shape;
for (int px = 0; px < c.xe; px++)
for (int py = 0; py < c.ye; py++)
for (int pz = 0; pz < c.ze; pz++) {
Cell cell = f.getCell(c.x + px, c.y + py, c.z + pz);
if (cell != null) {
pic.drawText(c.x + px, c.y + py, c.z + pz, "" + cell.energy, 1.5f);
}
}
/** Only call once after organ be created by new() method */
public Organ[] vary() { // 在下蛋时每个器官会调用这个方法,缺省返回一个类似自已的副本,子类通常要覆盖这个方法
Organ newOrgan = null;
try {
newOrgan = this.getClass().newInstance();
} catch (Exception e) {
throw new UnknownError("Can not make new Organ copy for " + this);
}
copyXYZR(this, newOrgan);
newOrgan.name = this.name;
newOrgan.fat = this.fat;
return new Organ[] { newOrgan };
}
}

@ -1,60 +0,0 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.Env;
/**
* Photon has direction and strength
*
* x,y,zmx,my,mz
* Cell
*
* @author Yong Zhu
* @since 2.0.2
*/
public class Photon {
public float x;
public float y;
public float z;
public float mx;
public float my;
public float mz;
public int organNo;// 每个光子是由哪个器官产生的,为-1表示它不是器官产生而是由细胞动态生成的反向光子信号
public int color;// 每个光子都有自已的颜色,由产生光子的器官的颜色来决定,颜色不重要,但能方便观察
public int activeNo;// 每一轮循环都有一个编号,光子走一格后就加上这个编号,同一个循环如果遇到相同编号的光子就跳过,防止光子被一直赶着走
public int energy;
public Photon() { // 缺省构造器
}
public Photon(int organNo, int color, float x, float y, float z, float mx, float my, float mz) {
this.x = x;
this.y = y;
this.z = z;
this.mx = mx;
this.my = my;
this.mz = mz;
this.organNo = organNo;
this.color = color;
}
public boolean isBackway() {// 是反向光子? 通常反向传播的光子不再参与在果冻细胞上挖洞
return organNo < 0;
}
/** Check if x,y,z out of frog's brain bound */
public boolean outBrainBound() {// 检查指定坐标是否超出frog脑空间界限
return x < 0 || x >= Env.FROG_BRAIN_XSIZE || y < 0 || y >= Env.FROG_BRAIN_YSIZE || z < 0
|| z >= Env.FROG_BRAIN_ZSIZE;
}
}

@ -12,8 +12,6 @@ package com.github.drinkjava2.frog.brain;
import java.io.Serializable;
import com.github.drinkjava2.frog.Frog;
/**
* Shape represents a 3d zone in brain
*
@ -26,7 +24,4 @@ public interface Shape extends Serializable {
/* Draw self on brain picture */
public void drawOnBrainPicture(BrainPicture pic); // 把自己在脑图上画出来
/* Organ will call this method to create cells or register organ in cells */
public void createCellsRegOrgan(Frog f, int orgNo); // 在Shape所代表的脑区内找到或创建Cell对象并将器官号orgNo登记在cell里
}

@ -0,0 +1,100 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain;
import java.io.Serializable;
import com.github.drinkjava2.frog.Env;
/**
* Zone represents a cube zone in brain
*
* @author Yong Zhu
* @since 1.0
*/
public class Zone implements Serializable { // zone 代表脑空间中的一块立方区域, 以x,y,z为中心 以r为边长的一半
private static final long serialVersionUID = 1L;
public float x;
public float y;
public float z;
public float r;// r为这个立方矩形边长的一半
public Zone() {
// 空构造器不能省
}
public Zone(float x, float y, float z, float r) {// 用x,y,z, r来构造
this.x = x;
this.y = y;
this.z = z;
this.r = r;
if (this.x < 0)
this.x = 0;
if (this.y < 0)
this.y = 0;
if (this.z < 0)
this.z = 0;
if (this.x > Env.FROG_BRAIN_XSIZE)
this.x = Env.FROG_BRAIN_XSIZE;
if (this.y > Env.FROG_BRAIN_YSIZE)
this.y = Env.FROG_BRAIN_YSIZE;
if (this.z > Env.FROG_BRAIN_ZSIZE)
this.z = Env.FROG_BRAIN_ZSIZE;
}
public Zone(Zone z) {// 用另一个Zone来构造
this.x = z.x;
this.y = z.y;
this.z = z.z;
this.r = z.r;
}
public boolean nearby(Zone o) {
if (o == null)
return false;
float dist = r + o.r;
return Math.abs(x - o.x) < dist && Math.abs(y - o.y) < dist && Math.abs(z - o.z) < dist;
}
public int roundX() {
return Math.round(x);
}
public int roundY() {
return Math.round(y);
}
public int roundZ() {
return Math.round(z);
}
public static void copyXYZ(Zone from, Zone to) {
to.x = from.x;
to.y = from.y;
to.z = from.z;
}
public static void copyXYZR(Zone from, Zone to) {
to.x = from.x;
to.y = from.y;
to.z = from.z;
to.r = from.r;
}
public void setXYZR(float x, float y, float z, float r) {
this.x = x;
this.y = y;
this.z = z;
this.r = r;
}
}

@ -10,39 +10,36 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import static com.github.drinkjava2.frog.Env.FROG_BRAIN_ZSIZE;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Active always active
* Active always keep active
*
* @author Yong Zhu
*
*/
public class Active extends Organ {// 这个器官的作用总是激活一个固定区,它有可能会被自然选择选中
private static final long serialVersionUID = 1L;
public int actEngery = 2;
public class Active extends Organ {// 以前的实验发现添加一个始终激活的区比用Hungry来驱动更能提高找食效率
public Active() {
this.shape = new Cuboid(15, 10, FROG_BRAIN_ZSIZE / 2 + 3, 1, 1, 1);
}
private static final long serialVersionUID = 1L;
public Organ[] vary(Frog f) {// 重写器官的very方法
// actEngery = RandomUtils.varyInLimit(actEngery, 1, 5);
// if (RandomUtils.percent(3f)) {
// Active a = new Active();
// Cuboid c = (Cuboid) a.shape;
// c.y--;
// return new Organ[] { this, a };
// }
return new Organ[] { this };
@Override
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
organOutputEnergy = 2f;
}
}
@Override
public void cellAct(Frog f, Cell c) {
c.energy -= actEngery;
public void active(Frog f) {
for (Cell cell : f.cells) {
if (cell.energy > 0)
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)
if (cell.input.nearby(this)) // if input zone near by happy zone
cell.energy += organOutputEnergy;
}
}
}

@ -1,51 +0,0 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import static com.github.drinkjava2.frog.Env.FROG_BRAIN_XSIZE;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
/**
* BigEye can see 8x8 square around of current frog
*
* @author Yong Zhu
*/
public class BigEye extends Organ {// 这个大眼睛是青蛙从上帝视角来观察产生一个8x8的图像区用来作为模式识别功能的输入区
private static final int EYE_RADIUS = 4;
private static final int cx = 6; // 中心点
private static final int cy = 6;
private static final int cz = FROG_BRAIN_XSIZE / 2; // 中层
private static final long serialVersionUID = 1L;
public BigEye() {
// 大眼晴位于脑的中部,模仿视神经通到脑的中部,而不是通到脑的皮层。视信号从脑的中部传到脑皮层的过程就是模式识别的筛选过程,筛选结果记录在脑皮层里。
// 模式识别的基本原理是反复发生的信号会到达并存贮在脑皮层(挖洞),不常发生的信号不会在脑皮层留下印象(或洞很快就自愈了)。
// 脑皮层的回忆原理是B角度入射的信号会触发脑皮层细胞原存有的A角度的洞信号从A洞开始沿A信号曾经射入的方向反射回去
this.shape = new Cuboid(cx - EYE_RADIUS, cy - EYE_RADIUS, cz, EYE_RADIUS * 2, EYE_RADIUS * 2, 1);
}
@Override
public void cellAct(Frog f, Cell c) {// 大眼睛根据虚拟环境是否有物体,激活视网膜细胞, 以及与它底层相邻的脑细胞(待加)
// 根据距中心点(cx,cy)的偏移,来映射虚拟环境的物体到视网膜上
if (Env.foundAnyThing(f.x + c.x - cx, f.y - c.y + cy))
c.addEnergy(30);
else
c.subEnergy(30);
// TODO激活眼下细胞让信号进入模式识别之旅并最终存贮在脑皮层细胞里,即金字塔的底部。
}
}

@ -15,21 +15,16 @@ import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Happy active after ate food
* Eat food at current x, y position
*/
public class Eat extends Organ { // Eat器官的作用就是如果位置与食物重合增加frog的能量
public class Eat extends Organ {// Eat这个类将食物转化为能量能量小于0则青蛙死掉
private static final long serialVersionUID = 1L;
public int actEngery = 1000;
public Organ[] vary(Frog f) {// 重写器官的very方法
return new Organ[] { this };
}
@Override
public void active(Frog f) {
if (Env.foundAndAteFood(f.x, f.y)) {
f.ateFood++;
f.energy += actEngery;
f.ateFood++;
f.energy += 1000;// 如果青蛙的坐标与食物重合吃掉food能量境加
}
}

@ -1,113 +0,0 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import static com.github.drinkjava2.frog.Env.FROG_BRAIN_XSIZE;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Eye can only see env material
*
* Eye便
*
* @author Yong Zhu
*/
public class Eye {// 这个眼睛是从青蛙视角来观察因为青蛙生活在二次元空间所以它只能观察上下左右4个方向有无食物
// 视距
private static final int cx = 5; // 中心点
private static final int cy = 15;
private static final int cz = FROG_BRAIN_XSIZE / 2; // 中层
public static class SeeUp extends Organ {// 这个感光细胞只能看到上方有没有物体
private static final long serialVersionUID = 1L;
public int seeDistance = 10;
public int addEng = 30;
public int subEng = 2;
public Organ[] vary(Frog f) {// 重写器官的very方法允许眼睛看到的距离随机进化
seeDistance = RandomUtils.varyInLimit(seeDistance, 5, 15);
addEng = RandomUtils.varyInLimit(addEng, 10, 30);
subEng = RandomUtils.varyInLimit(subEng, 1, 30);
return new Organ[] { this };
}
public SeeUp() {
shape = new Cuboid(cx, cy + 2, cz, 1, 1, 1);
}
public void cellAct(Frog f, Cell c) {// 如果上方有物体就激活视网膜细胞
for (int i = 1; i <= seeDistance; i++)
if (Env.foundAnyThing(f.x, f.y - i)) {
c.addEnergy(addEng);
return;
}
c.subEnergy(subEng);
}
}
public static class SeeDown extends SeeUp {// 这个感光细胞只能看到下方有没有物体
private static final long serialVersionUID = 1L;
public SeeDown() {
shape = new Cuboid(cx, cy - 2, cz, 1, 1, 1);
}
public void cellAct(Frog f, Cell c) {
for (int i = 1; i <= seeDistance; i++)
if (Env.foundAnyThing(f.x, f.y + i)) {
c.addEnergy(addEng);
return;
}
c.subEnergy(subEng);
}
}
public static class SeeLeft extends SeeUp {// 这个感光细胞只能看到左边有没有物体
private static final long serialVersionUID = 1L;
public SeeLeft() {
shape = new Cuboid(cx - 2, cy, cz, 1, 1, 1);
}
public void cellAct(Frog f, Cell c) {
for (int i = 1; i <= seeDistance; i++)
if (Env.foundAnyThing(f.x - i, f.y)) {
c.addEnergy(addEng);
return;
}
c.subEnergy(subEng);
}
}
public static class SeeRight extends SeeUp {// 这个感光细胞只能看到右边有没有物体
private static final long serialVersionUID = 1L;
public SeeRight() {
shape = new Cuboid(cx + 2, cy, cz, 1, 1, 1);
}
public void cellAct(Frog f, Cell c) {
for (int i = 1; i <= seeDistance; i++)
if (Env.foundAnyThing(f.x + i, f.y)) {
c.addEnergy(addEng);
return;
}
c.subEnergy(subEng);
}
}
}

@ -0,0 +1,100 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
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.Organ;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Eye can only see 4 direction
*
* @author Yong Zhu
* @since 1.0
*/
public class Eyes {
public static class SeeUp extends Organ {// 只能看到上方食物
private static final long serialVersionUID = 1L;
public int seeDistance; // 眼睛能看到的距离
@Override
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次
if (!initilized) {
initilized = true;
seeDistance = 8;
}
}
@Override
public Organ[] vary() {
seeDistance=RandomUtils.varyInLimit(seeDistance, 5, 20);
if (RandomUtils.percent(5)) { // 可视距离有5%的机率变异
seeDistance = seeDistance + 1 - 2 * RandomUtils.nextInt(2);
if (seeDistance < 1)
seeDistance = 1;
if (seeDistance > 50)
seeDistance = 50;
}
return new Organ[] { this };
}
@Override
public void active(Frog f) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x, f.y + i)) {
activeInput(f, 30);
return;
}
}
}
public static class SeeDown extends SeeUp {// 只能看到下方食物
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x, f.y - i)) {
activeInput(f, 30);
return;
}
}
}
public static class SeeLeft extends SeeUp {// 只能看到左方食物
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x - i, f.y)) {
activeInput(f, 30);
return;
}
}
}
public static class SeeRight extends SeeUp {// 只能看到右方食物
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x + i, f.y)) {
activeInput(f, 30);
return;
}
}
}
}

@ -10,54 +10,52 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import java.awt.Color;
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.Organ;
import com.github.drinkjava2.frog.brain.Zone;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Line is a line from cell1 to cell2
* Line
*
* OrganRandomConnectGroup
*
* @author Yong Zhu
* @since 2020-04-18
* @since 1.0
*/
public class Line extends Organ {// Line代表一个从cell1到cell2的神经元连接,energy表示连接能量
public class Line extends Organ {
private static final long serialVersionUID = 1L;
public int eng = 30;
public int fat = 0;
public int x1, y1, z1, x2, y2, z2;
public Zone inputZone; // 输入触突区
public Zone outputZone; // 输出触突区
public Line(Cell c1, Cell c2) {
this.x1 = c1.x;
this.y1 = c1.y;
this.z1 = c1.z;
this.x2 = c2.x;
this.y2 = c2.y;
this.z2 = c2.z;
@Override
public boolean allowBorrow() { // 是否允许在精子中将这个器官借出
return true;
}
public void active(Frog f) {// 重写active方法,line的作用就是在细胞c1,c2间传送能量(即信息)
if (!f.alive)
return;
if (RandomUtils.percent(5))
eng = RandomUtils.varyInLimit(eng, 1, 70);// 传输的能量也参与进化
Cell c1 = f.getCell1(this);
if (c1 == null)
return;
Cell c2 = f.getCell2(this);
if (c2 == null)
return;
if (c1.energy > eng) { // 为了保证能量(即熵)守恒,传出的能量要不大于输入能量
fat++;
c1.subEnergy(eng);
c2.addEnergy(eng);
}
@Override
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
inputZone= RandomUtils.randomZoneInOrgans(f);
outputZone = RandomUtils.randomZoneInOrgans(f);
}
this.fat = 0;// 每次fat清0因为遗传下来的fat不为0
Cell c=new Cell();
c.input= inputZone;
c.output=outputZone;
c.organ=this;
f.cells.add(c);
}
@Override
public Organ[] vary(Frog f) {
public Organ[] vary() {
organOutputEnergy = RandomUtils.varyInLimit(organOutputEnergy, -3, 3);
if (fat <= 0)// 如果胖值为0表示这个组的细胞没有用到可以小概率丢掉它了
if (RandomUtils.percent(30))
return new Organ[] {};
@ -66,9 +64,17 @@ public class Line extends Organ {// Line代表一个从cell1到cell2的神经元
return new Organ[] { this };
}
public void drawOnBrainPicture(Frog f, BrainPicture pic) {
pic.drawLine(this);
pic.drawPoint(this.x2 + .5f, this.y2 + .5f, this.z2 + .5f, 5);
pic.drawText((x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2, "" + eng, 1);
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (fat <= 0)
pic.setPicColor(Color.LIGHT_GRAY); // 没用到? 灰色
else if (organOutputEnergy <= 0)
pic.setPicColor(Color.BLUE);
else
pic.setPicColor(Color.red); // 用到了?红色
pic.drawLine(inputZone, outputZone);
pic.drawZone(this);
pic.setPicColor(Color.red);
}
}

@ -1,89 +0,0 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import static com.github.drinkjava2.frog.Env.FROG_BRAIN_ZSIZE;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
/**
* If move cell active, frog will move
*
* Move便
*
* @author Yong Zhu
*/
public class Move {// 因为青蛙生活在二次元所以只有上下左右4个运动方向
private static final int cx = 5;
private static final int cy = 15;
private static final int cz = FROG_BRAIN_ZSIZE / 2 + 3;
public static class MoveUp extends Organ {// 这个运动细胞激活,青蛙将向上移动
private static final long serialVersionUID = 1L;
public MoveUp() {
shape = new Cuboid(cx, cy + 2, cz, 1, 1, 1);
}
@Override
public void cellAct(Frog f, Cell c) {
if (c.inActive())
f.y--;
}
}
public static class MoveDown extends Organ {// 这个运动细胞激活,青蛙将向下移动
private static final long serialVersionUID = 1L;
public MoveDown() {
shape = new Cuboid(cx, cy - 2, cz, 1, 1, 1);
}
@Override
public void cellAct(Frog f, Cell c) {
if (c.inActive())
f.y++;
}
}
public static class MoveLeft extends Organ {// 这个运动细胞激活,青蛙将向左移动
private static final long serialVersionUID = 1L;
public MoveLeft() {
shape = new Cuboid(cx - 2, cy, cz, 1, 1, 1);
}
@Override
public void cellAct(Frog f, Cell c) {
if (c.inActive())
f.x--;
}
}
public static class MoveRight extends Organ {// 这个运动细胞激活,青蛙将向右移动
private static final long serialVersionUID = 1L;
public MoveRight() {
shape = new Cuboid(cx + 2, cy, cz, 1, 1, 1);
}
@Override
public void cellAct(Frog f, Cell c) {
if (c.inActive())
f.x++;
}
}
}

@ -0,0 +1,28 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Move down frog 1 unit if outputs of nerve cells active in this zone
*/
public class MoveDown extends Organ {
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
if (outputActive(f))
f.y++;
}
}

@ -0,0 +1,27 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Move left frog 1 unit if outputs of nerve cells active in this zone
*/
public class MoveLeft extends Organ {
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
if (outputActive(f))
f.x--;
}
}

@ -0,0 +1,29 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Move right frog 1 unit if outputs of nerve cells active in this zone
*/
public class MoveRight extends Organ {
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
if (outputActive(f))
f.x++;
}
}

@ -0,0 +1,28 @@
/*
* Copyright 2018 the original author or authors.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
* applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*/
package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Move up frog 1 unit if outputs of nerve cells active in this zone
*/
public class MoveUp extends Organ {
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
if (outputActive(f))
f.y--;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save