Temporary add brain3d pic

pull/2/head
Yong Zhu 6 years ago
parent 30fad204fa
commit 6be80b30f2

@ -1,5 +1,4 @@
## Frog | 人工生命
(Engish instruction see README_EN.md)
这是一个人工生命试验项目最终目标是创建“有自我意识表现”的模拟生命体技术架构基于02年提出的 [一个人工脑模型](一个人工脑模型.md)。
这个项目永远没有结束的时候,开始于模拟一个简单的生命体,然后是青蛙、狗......, 结束于有“自我意识表现”的人工脑,或者说,结束于被机器人代替人类的那一天。

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

@ -12,7 +12,7 @@ import javax.swing.JPanel;
import com.github.drinkjava2.frog.egg.Egg;
import com.github.drinkjava2.frog.egg.EggTool;
import com.github.drinkjava2.frog.objects.EnvObject;
import com.github.drinkjava2.frog.objects.LetterTester;
import com.github.drinkjava2.frog.objects.Food;
import com.github.drinkjava2.frog.objects.Material;
import com.github.drinkjava2.frog.util.RandomUtils;
@ -25,7 +25,7 @@ import com.github.drinkjava2.frog.util.RandomUtils;
@SuppressWarnings("all")
public class Env extends JPanel {
/** Speed of test */
public static final int SHOW_SPEED = 1; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
public static final int SHOW_SPEED = 10; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
/** Delete eggs at beginning of each run */
public static final boolean DELETE_EGGS = true;// 每次运行是否先删除保存的蛋
@ -39,7 +39,7 @@ 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 = 30; // frog的脑在X方向长度
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方向长度
@ -59,10 +59,10 @@ 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 = LetterTester.STR.length() * 2 * LetterTester.TIME;// 每轮测试步数,可调
public static final int STEPS_PER_ROUND = 1000;// 每轮测试步数,可调
public static int step;// 当前测试步数
public static final int FOOD_QTY = 100; // 食物数量, 可调
public static final int FOOD_QTY = 3000; // 食物数量, 可调
// 以下是程序内部变量,不要手工修改它们
public static boolean pause = false; // 暂停按钮按下将暂停测试
@ -73,7 +73,7 @@ public class Env extends JPanel {
public static List<Egg> eggs = new ArrayList<>(); // 这里存放新建或从磁盘载入上轮下的蛋,每个蛋可能生成几个青蛙,
public static EnvObject[] things = new EnvObject[] {new LetterTester()};// 所有外界物体如食物、字母测试工具都放在这个things里面
public static EnvObject[] things = new EnvObject[] {new Food()};// 所有外界物体如食物、字母测试工具都放在这个things里面
static {
System.out.println("唵缚悉波罗摩尼莎诃!"); // 杀生前先打印往生咒见码云issue#IW4H8

@ -20,9 +20,8 @@ import javax.imageio.ImageIO;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Hole;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.brain.Photon;
import com.github.drinkjava2.frog.brain.Shape;
import com.github.drinkjava2.frog.egg.Egg;
import com.github.drinkjava2.frog.objects.Material;
@ -48,7 +47,7 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
public int y; // frog在Env中的y坐标
public long energy = 10000000; // 青蛙的能量为0则死掉
public boolean alive = true; // 设为false表示青蛙死掉了将不参与计算和显示以节省时间
public int ateFood = 0;
public int ateFood = 0; // 青蛙曾吃过的食物总数,下蛋时如果两个青蛙能量相等,可以比数量
static Image frogImg;
static {
@ -89,22 +88,23 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
}
/** Set with given activeValue */
public void setCuboidVales(Cuboid o, boolean active) {// 激活长方体区域内的所有脑区
public void activeCellsInShape(Shape sp) {// 激活长方体区域内的所有脑区
if (!alive)
return;
for (int x = o.x; x < o.x + o.xe; x++)
if (cells[x] != null)
for (int y = o.y; y < o.y + o.ye; y++)
if (cells[x][y] != null)
for (int z = o.z; z < o.z + o.ze; z++)
if (cells[x][y][z] != null)
getOrCreateCell(x, y, z).hasInput = active;
if (sp instanceof Cuboid) {
Cuboid o = (Cuboid) sp;
for (int x = o.x; x < o.x + o.xe; x++)
if (cells[x] != null)
for (int y = o.y; y < o.y + o.ye; y++)
if (cells[x][y] != null)
for (int z = o.z; z < o.z + o.ze; z++)
if (cells[x][y][z] != null) {
getOrCreateCell(x, y, z).active();
}
}
}
private int activeNo = 0;// 每一帧光子只能走一步,用这个来作标记
public boolean active(Env v) {// 这个active方法在每一步循环都会被调用是脑思考的最小帧
activeNo++;
// 如果能量小于0、出界、与非食物的点重合则判死
if (!alive || energy < 0 || Env.outsideEnv(x, y) || Env.bricks[x][y] >= Material.KILLFROG) {
energy -= 100; // 死掉的青蛙也要消耗能量,确保淘汰出局
@ -115,18 +115,10 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
for (Organ o : organs)
o.active(this); // 调用每个器官的active方法 通常只用于执行器官的外界信息输入、动作输出,脑细胞的遍历不是在这一步
// 这里是最关键的脑细胞主循环,脑细胞负责捕获和发送光子,光子则沿它的矢量方向每次自动走一格,如果下一格是真空(即cell未初始化会继续走下去并衰减直到为0(为减少运算)
for (int i = 0; i < Env.FROG_BRAIN_XSIZE; i++) {
Env.checkIfPause(this);
if (cells[i] != null)
for (int j = 0; j < Env.FROG_BRAIN_YSIZE; j++)
if (cells[i][j] != null)
for (int k = 0; k < Env.FROG_BRAIN_ZSIZE; k++) {
Cell cell = cells[i][j][k];
if (cell != null)
cell.act(this,activeNo);
}
}
// 这里是最关键的脑细胞主循环依次调用每个器官的active方法每个器官各自负责调用各自区域通常是Cuboid)内的细胞的行为
for (Organ o : organs)
o.active(this);
return alive;
}
@ -145,7 +137,7 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
/** 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 (outBrainBound(x, y, z))
if (outBrainRange(x, y, z))
return null;
if (cells[x] == null)
cells[x] = new Cell[Env.FROG_BRAIN_YSIZE][];
@ -159,63 +151,10 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
return cell;
}
/** Check if x,y,z out of frog's brain bound */
public static boolean outBrainBound(int x, int y, int z) {// 检查指定坐标是否超出frog脑空间界限
/** 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
|| z >= Env.FROG_BRAIN_ZSIZE;
}
/** Photon always walk */
public void addAndWalk(Photon p) { // 添加光子的同时让它沿光子方向自动走一格
p.x += p.mx;
p.y += p.my;
p.z += p.mz;
int rx = Math.round(p.x);
int ry = Math.round(p.y);
int rz = Math.round(p.z);
if (Frog.outBrainBound(rx, ry, rz))
return;// 出界直接扔掉
Cell cell = getCell(rx, ry, rz);
if (cell != null)
cell.addPhoton(p);
}
/** Photon always walk */
public void addAndWalkAndDig(Photon p) { // 添加光子的同时让它沿光子方向自动走一格
p.x += p.mx;
p.y += p.my;
p.z += p.mz;
int rx = Math.round(p.x);
int ry = Math.round(p.y);
int rz = Math.round(p.z);
if (Frog.outBrainBound(rx, ry, rz))
return;// 出界直接扔掉
Cell cell = getCell(rx, ry, rz);
if (cell != null) {
cell.addPhoton(p);
cell.digHole(p);
}
}
// for test purpose, reset some values for prepare next training.
public void prepareNewTraining() {
for (int i = 0; i < Env.FROG_BRAIN_XSIZE; i++) {
if (cells[i] != null)
for (int j = 0; j < Env.FROG_BRAIN_YSIZE; j++)
if (cells[i][j] != null)
for (int k = 0; k < Env.FROG_BRAIN_ZSIZE; k++) {
Cell cell = cells[i][j][k];
if (cell != null) {
cell.deleteAllPhotons();
cell.hasInput = false;
cell.photonSum = 0;
if (cell.holes != null)
for (Hole h : cell.holes) {
h.age += 100;// 强迫洞的年龄增加,用这个方法来区分开不同批次的训练
}
}
}
}
}
}

@ -15,6 +15,7 @@ import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.plaf.ColorUIResource;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Env;
@ -54,7 +55,7 @@ public class BrainPicture extends JPanel {
super();
this.setLayout(null);// 空布局
this.brainDispWidth = brainDispWidth;
scale = 0.7f * brainDispWidth / brainWidth;
scale = 0.5f * brainDispWidth / brainWidth;
this.setBounds(x, y, brainDispWidth + 1, brainDispWidth + 1);
buffImg = new BufferedImage(Env.FROG_BRAIN_DISP_WIDTH, Env.FROG_BRAIN_DISP_WIDTH, BufferedImage.TYPE_INT_RGB);
g = buffImg.getGraphics();
@ -276,24 +277,9 @@ public class BrainPicture extends JPanel {
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) {// 只显示激活点
if (cell.hasInput && x == 0) {// 如果在左边,显示黑色大圆
setPicColor(Color.BLACK);
drawCellCenter(x, y, z, 0.6f);
} else if (z == Env.FROG_BRAIN_ZSIZE - 1 && cell.hasInput) {// 如果在顶上边,显示兰色大圆
setPicColor(Color.BLUE);
drawCellCenter(x, y, z, 0.6f);
}
if (cell.photonQty > 0) {// 如果在内部只显示有光子的cell
setPicColor(ColorUtils.colorByCode(cell.color));
float dia = 0.2f;
if (cell.color == 0)
dia = 0.3f;
if (x == xMask || y == yMask)
dia = 0.5f;
drawCellCenter(x, y, z, dia);
}
if (cell != null && cell.energy>10) {
setPicColor(ColorUtils.rainbowColor(cell.energy));
drawCellCenter(x, y, z, 0.6f);
}
}
}

@ -12,10 +12,6 @@ package com.github.drinkjava2.frog.brain;
import java.util.Arrays;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.util.ColorUtils;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Cell is the smallest unit of brain space, a Cell can have many actions and
* photons and holes and relations
@ -31,6 +27,9 @@ import com.github.drinkjava2.frog.util.RandomUtils;
* hebb
*
*
* 2020-2-28A
* B
*
* @author Yong Zhu
* @since 1.0
*/
@ -38,6 +37,7 @@ public class Cell {
public int x;
public int y;
public int z;
public float energy;
public Cell(int x, int y, int z) {
this.x = x;
@ -45,49 +45,21 @@ public class Cell {
this.z = z;
}
/** Active of current cell */
public boolean hasInput = false; // 这个细胞是否有外界信号(如光、声音)输入
public int[] organs = null; //// 每个Cell可以被多个Organ登记这里保存organ在蛋里的序号
public Photon[] photons = null;// 光子
public Hole[] holes = null;// 洞(即动态突触),洞由光子产生,洞由时间抹平
public Relation[] relations = null;// 洞的关联关系
public int color;// Cell的颜色取最后一次被添加的光子的颜色颜色不重要但能方便观察
public int[] organs = null; // 每个Cell可以被多个Organ登记这里保存organ在蛋里的序号
public int photonQty = 0; // 这个细胞里当前包含的光子总数
public Hole[] holes = null;// 洞(即动态突触),洞由光子产生,洞由时间抹平,洞的角度本身就是关联关系,角度越大,关联关系越大
public int photonSum = 0; // 这个细胞里曾经收到的光子总数
/** Active this cell, increase its energy value */
public void active() {// 激活这个细胞也就是说增加它的能量值最大到10000饱和
energy += 100;
if (energy > 10000)
energy = 10000;
}
/*-
* Each cell's act method will be called once at each loop step
*
* act
* )
* action,organs
*
*
*
* 穿穿
*
* 线()(沿线)
* +
*
*
*/
public void act(Frog f, int activeNo) {
if (organs == null)
return;
if (holes != null)
for (Hole h : holes) // 洞的年龄增加,目的是让年龄越接近的洞之间,绑定的概率和强度越大
h.age++;
for (int i = 0; i < organs.length; i++) {
Organ o = f.organs.get(organs[i]);
o.cellAct(f, this, activeNo);
}
public void deActive() {// 抑制这个细胞也就是说减小它的能量值最小到0
energy -= 300;
if (energy < 0)
energy = 0;
}
public void regOrgan(int orgNo) {// 每个Cell可以被多个Organ登记通常只在青蛙初始化器官时调用这个方法
@ -97,121 +69,4 @@ public class Cell {
organs[organs.length - 1] = orgNo;
}
public void addPhoton(Photon p) {// 每个cell可以存在多个光子
if (p == null)
return;
photonQty++;
photonSum++;
color = p.color; // Cell的颜色取最后一次被添加的光子的颜色
if (photons == null) {
photons = new Photon[] { p };// 创建数组
return;
} else
for (int i = 0; i < photons.length; i++) { // 找空位插入,尽量重复利用内存
if (photons[i] == null) {
photons[i] = p;
return; // 如找到就插入,返回
}
}
photons = Arrays.copyOf(photons, photons.length + 1);// 否则追加新光子到未尾
photons[photons.length - 1] = p;
}
public void digHole(Photon p) {// 根据光子来把洞挖大一点,同时,如果有洞和它年龄相近,将把它们绑定起来,如果已有绑定的洞,有可能在绑定的洞里撞出光子来
if (p == null || p.isBackway())// 反向的光子不参与挖坑
return;
if (holes == null) {// 如果没有坑,就新挖一个
holes = new Hole[] { new Hole(p) }; // 新挖的坑不参与绑定
return;
}
if (RandomUtils.percent(10)) // 这个机率纯粹是为了减少光子数,增加运行速度
for (int i = 0; i < holes.length; i++) { // 这部分很关键,光子如果与坑同向或角度相近,会在与坑绑定的坑上撞出新的光子反向飞回,注意只针对绑定的坑
Hole h = holes[i];
if (h != null) {
float r = h.angleCompare(p);
if (r < 0.05) {
if (RandomUtils.percent(h.size))
createBackPhoton(h); // 产生光子的机率与洞的大小有关
} else if (r > 0.1 && r < 0.5) { // 这个叫侧抑制,角度不等但相近的光子射过来会使洞变小
h.size -= 10;
if (h.size < 10)
h.size = 10;
}
}
}
Hole found = null;
for (int i = 0; i < holes.length; i++) { // 先看看已存在的洞是不是与光子同向,是的话就把洞挖大一点
Hole h = holes[i];
if (h != null && h.ifSimilarWay(p)) { // 找到了与入射光子同向的洞,实际上就是同一个波源发来的
found = h;
h.size += 10;
h.age = 0; // 为0表示这个洞被重新激活可以参与绑定
if (h.size > 100)
h.size = 100;
break;
}
}
if (found != null) { // 如果第二次扩洞,且光子和洞不是同一个器官产生的,这时可以把这个洞和其它洞关联起来了
for (Hole hole : holes) {
if (hole != found && found.organNo != hole.organNo && (Math.abs(found.age - hole.age) < 80)) {// TODO:不应用固定值
bind(found, hole);
}
}
}
if (found == null) {// 如果还没有找到旧坑,只好挖一个新坑到未尾
holes = Arrays.copyOf(holes, holes.length + 1);
holes[holes.length - 1] = new Hole(p);
}
}
private void createBackPhoton(Hole h) { // 根据给定的洞,把所有与它绑定的洞上撞出光子来
if (relations == null)
return;
for (Relation r : relations) {
Hole f = null;
if (h.equals(r.h1))
f = r.h2;// h2与h是一对绑定的
else if (h.equals(r.h2))
f = r.h1; // h1与h是一对绑定的
if (f != null) {
Photon back = new Photon(-1, ColorUtils.RED, f.x, f.y, f.z, -f.mx, -f.my, -f.mz);// 生成反向的光子
addPhoton(back);
// energy -= 90;
}
}
}
public void bind(Hole a, Hole b) {// 将两个坑绑定,以后只要有一个坑激活,另一个坑也会产生出光子
if (relations == null) {
relations = new Relation[] { new Relation(a, b) };
return;
}
for (Relation r : relations) {// 先看看是不是已绑过,绑过就把强度乘1.5
if ((r.h1 == a && r.h2 == b) || (r.h2 == a && r.h1 == b)) {
r.strength *= 1.5;
if (r.strength > 100000) // TODO: strength要有遗忘机制
r.strength = 100000;
return;
}
}
relations = Arrays.copyOf(relations, relations.length + 1);
relations[relations.length - 1] = new Relation(a, b);
}
public void removePhoton(int i) {// 删第几个光子
if (photons[i] != null) {
photons[i] = null;
photonQty--;
}
}
public void deleteAllPhotons() {
photons = null;
photonQty = 0;
}
}

@ -25,9 +25,7 @@ public class Hole {
public float mx; // mx,my,mz分别是光子砸出这个洞时的光子每单元移动方向在三个轴上的投影
public float my;
public float mz;
public int size = 50;// 洞的大小1~100这个size会按记忆曲线慢慢回复到0接近0后这个洞就被删除回收内存
public int age;// 洞的年龄,一直在增长但一个洞有完全同向的光子再次砸进来洞的年龄就归0
public int organNo;// 这里记录第一个撞出来这个洞的产子是由哪个器官产生出来的
public float size = 0;// 洞的大小收到光子会变大1.1倍直到饱和,平时会沿指数曲线消失
public Hole(Photon p) {
this.x = p.x;
@ -35,8 +33,7 @@ public class Hole {
this.z = p.z;
this.mx = p.mx;
this.my = p.my;
this.mz = p.mz;
this.organNo = p.organNo;
this.mz = p.mz;
}
public float angleCompare(Hole p) {// 比较洞与光子之间的角度差值

@ -81,13 +81,18 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
}
/** each step will call Organ's active methodd */
public void active(Frog f) { // 每一步测试都会调用active方法通常用于手动生成的器官自动生成的器官其行为仅由脑细胞来决定
// do nothing
public void active(Frog f) {// 每一步测试都会调用active方法它通常遍历每个细胞调用它们的cellAct方法
if (!f.alive)
return;
Cuboid c = (Cuboid) shape;
for (int px = 0; px < c.xe; px++)
for (int py = 0; py < c.ye; py++) {// 要做到近处的分辨率高,远处的分辨率低
cellAct(f, f.getOrCreateCell(c.x + px, c.y + py, c.z));
}
}
/** each step will call Organ's active methodd */
public void cellAct(Frog frog, Cell c, int activeNo) { // 每个细胞都会调用cellAct方法,这是针对细胞级别的方法,子类要覆盖它
public void cellAct(Frog f, Cell c) { // 每个细胞都会调用cellAct方法,这是针对细胞级别的方法,子类要覆盖它
}
/** Child class can override this method to drawing picture */

@ -1,31 +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;
/**
* Relation is the relationship betweeen 2 holes
*
* Relation
*
* @author Yong Zhu
* @since 2.0.2
*/
public class Relation {
public Hole h1;
public Hole h2;
public int strength = 1;
public Relation(Hole h1, Hole h2) {
this.h1 = h1;
this.h2 = h2;
}
}

@ -17,7 +17,7 @@ import com.github.drinkjava2.frog.Frog;
/**
* Shape represents a 3d zone in brain
*
* Shape,shape
* Shape,shapeCell
*
* @author Yong Zhu
* @since 2.0.2
@ -26,5 +26,6 @@ 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里
}

@ -1,81 +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 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.brain.Photon;
import com.github.drinkjava2.frog.util.ColorUtils;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Ear can accept sound input
*
*
*
* @author Yong Zhu
* @since 2.0.2
*/
@SuppressWarnings("all")
public class Ear extends Organ {// 耳朵位于脑的顶上,也是长方体
private static final long serialVersionUID = 1L;
public Ear() {
this.shape = new Cuboid(15, 5, Env.FROG_BRAIN_ZSIZE - 1, 1, 10, 1);// 手工固定耳区的大小
this.organName = "Ear";
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
this.color = ColorUtils.BLUE;
}
public void cellAct(Frog frog, Cell c, int activeNo) {
if (c.hasInput && RandomUtils.percent(40)) {// 随机数的作用是减少光子数,加快速度
for (float xx = -0.3f; xx <= 0.3f; xx += 0.15) {// 形成一个扇面向下发送
for (float yy = -1f; yy <= 1f; yy += 0.06) {
Photon p = new Photon(organNo, this.color, c.x, c.y, c.z, xx, yy, -1);
p.activeNo = activeNo;
frog.addAndWalk(p);// 光子不是直接添加,而是走一格后添加在相邻的细胞上
}
}
}
}
public void hearSound(Frog f, int code) {
Cuboid c = (Cuboid) this.shape;
f.getOrCreateCell(c.x, c.y + code, c.z).hasInput = true;
}
public int readcode(Frog f) {// 找出收取光子数最多的点
int temp = -10000;
int yPos = -1;
Cuboid c = (Cuboid) this.shape;
System.out.print("Ear received photons qty: ");
for (int y = 0; y < 10; y++) {
int sum = f.getOrCreateCell(c.x, c.y + y, c.z).photonSum;
System.out.print(sum + ",");
if (sum > temp) {
yPos = y;
temp = sum;
}
}
System.out.println();
return yPos;
}
/** 给这个耳朵听到一个字母,激活它的听觉输入区, 注意听觉输入区并不等于听觉成像区 */
public void hearNothing(Frog f) {
f.setCuboidVales((Cuboid) shape, false);
}
}

@ -10,14 +10,15 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import static com.github.drinkjava2.frog.Env.FROG_BRAIN_ZSIZE;
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.brain.Photon;
import com.github.drinkjava2.frog.objects.Material;
import com.github.drinkjava2.frog.util.ColorUtils;
import com.github.drinkjava2.frog.util.PixelsUtils;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Eye can only see env material
@ -25,54 +26,29 @@ import com.github.drinkjava2.frog.util.RandomUtils;
* @author Yong Zhu
*/
public class Eye extends Organ {// 眼睛是长方体
private static final int EYE_SIZE = 6;
private static final long serialVersionUID = 1L;
public Eye() {
this.shape = new Cuboid(0, 3, 2, 1, 13, 13);
this.shape = new Cuboid(3, 3, FROG_BRAIN_ZSIZE / 2, EYE_SIZE, EYE_SIZE, 1);// 眼晴位于脑的中部
this.organName = "Eye";
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
this.color = ColorUtils.GRAY;
}
public void cellAct(Frog frog, Cell c, int activeNo) {
if (c.hasInput && RandomUtils.percent(40)) {// 随机数的作用是减少光子数,加快速度
for (float yy = -0.1f; yy <= 0.1f; yy += 0.03) {// 形成一个扇面向右发送
for (float zz = -0.1f; zz <= 0.1f; zz += 0.03) {
Photon p = new Photon(organNo, this.color, c.x, c.y, c.z, 1.0f, yy, zz);
p.activeNo = activeNo; // 用这个activeNo防止一直被赶着走
frog.addAndWalk(p);// 光子不是直接添加,而是走一格后添加在相邻的细胞上
}
}
public void cellAct(Frog f, Cell c) {// 眼细胞的作用是根据食物激活视网膜和眼下皮层
f.x=0;f.y=0;
for (int i = 0; i < 2; i++) {
Env.bricks[i][0]=Material.FOOD;
Env.bricks[i][1]=Material.FOOD;
Env.bricks[i][32]=Material.FOOD;
}
if (Env.foundAnyThing(f.x - EYE_SIZE / 2 + c.x, f.y - EYE_SIZE / 2 + c.y))
c.active();
else
c.deActive();
}
/** Clear image on retina */
public void seeNothing(Frog f) {// 外界可以直接调用这个方法,清除视网膜图像
f.setCuboidVales((Cuboid) shape, false);
}
/**
* Accept a byte[x][y] array, active tubes located on eye's retina
*
*
*/
public void seeImage(Frog f, byte[][] pixels) {// 外界可以直接调用这个方法,硬塞一个象素图到视网膜上
if (!f.alive)
return;
int w = pixels.length;
int h = pixels[0].length;
Cuboid c = (Cuboid) shape;
// 在视网膜上产生字母像素点阵即激活这个脑视网膜所在的cells区然后由器官播种出的脑细胞负责将激活能量转为光子输送、存贮到其它位置
for (int px = 0; px < w; px++)
for (int py = 0; py < h; py++)
if (pixels[px][py] > 0)
f.getOrCreateCell(0, c.y + c.ye - px - 1, c.z + py).hasInput = true;
}
public void seeImageWithOffset(Frog f, byte[][] pixels, int xOff, int yOff) {// 外界硬塞一个象素图到视网膜上,并给出偏移量
byte[][] newPixels = PixelsUtils.offset(pixels, xOff, yOff);
seeImage(f, newPixels);
}
}

@ -1,58 +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 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.brain.Photon;
/**
* Move is a special organ the action move photon go to next cell
*
* MoveCell沿
*
* @author Yong Zhu
*/
public class Move extends Organ {
private static final long serialVersionUID = 1L;
public Move() {
super();
this.shape = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE - 5, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE);
this.organName = "Move";
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
}
public void cellAct(Frog frog, Cell c, int activeNo) {
if (c.x == 0 || c.z == Env.FROG_BRAIN_ZSIZE - 1) {// 但是对于输入区,将删除光子,并合计一共收到多少
if (c.photonQty > 0) {
c.photonSum += c.photonQty;
c.photons = null;
}
return;
}
if (c.photons != null) {
for (int ii = 0; ii < c.photons.length; ii++) {
Photon p = c.photons[ii];
if (p == null || p.activeNo == activeNo)// 同一轮新产生的光子或处理过的光子不再走了
continue;
p.activeNo = activeNo;
c.removePhoton(ii);
frog.addAndWalk(p); // 让光子自已往下走,走到哪就停到哪个细胞里
}
}
}
}

@ -1,57 +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 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.brain.Photon;
/**
* Move is a special organ the action move photon go to next cell
*
* MoveCell沿
*
* @author Yong Zhu
*/
public class MoveJelly extends Organ {
private static final long serialVersionUID = 1L;
public MoveJelly() {
super();
this.shape = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE - 5, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE);
this.organName = "MoveJelly";
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
}
public void cellAct(Frog frog, Cell c, int activeNo) {
if (c.x == 0 || c.z == Env.FROG_BRAIN_ZSIZE - 1) {// 但是对于输入区,将删除光子,并合计一共收到多少
if (c.photonQty > 0) {
c.photonSum += c.photonQty;
c.photons = null;
}
return;
}
if (c.photons != null) {
for (int ii = 0; ii < c.photons.length; ii++) {
Photon p = c.photons[ii];
if (p == null || p.activeNo == activeNo)// 同一轮新产生的光子或处理过的光子不再走了
continue;
p.activeNo = activeNo;
c.removePhoton(ii);
frog.addAndWalkAndDig(p); // 让光子自已往下走,走到哪就停到哪个细胞里,并且还在细胞上挖洞
}
}
}
}

@ -16,9 +16,7 @@ import java.util.List;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.brain.organ.Ear;
import com.github.drinkjava2.frog.brain.organ.Eye;
import com.github.drinkjava2.frog.brain.organ.MoveJelly;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
@ -37,9 +35,8 @@ public class Egg implements Serializable {
public List<Organ> organs = new ArrayList<>();// NOSONAR
public Egg() {// 无中生有,创建一个蛋,先有蛋,后有蛙
organs.add(new MoveJelly()); // MoveJelly即移动光子也是果冻记忆细胞本来可以分成两个器官的图省事
organs.add(new Eye()); // 眼是手工创建的,必有
organs.add(new Ear()); // 耳是手工创建的这个是用来测试ABCD字母识别的
//organs.add(new MoveJelly()); // MoveJelly即移动光子也是果冻记忆细胞本来可以分成两个器官的图省事
organs.add(new Eye()); // 眼是手工创建的,必有
}
/** Create egg from frog */

@ -1,66 +0,0 @@
/* Copyright 2018-2020 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.objects;
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.organ.Ear;
import com.github.drinkjava2.frog.brain.organ.Eye;
import com.github.drinkjava2.frog.util.StringPixelUtils;
/**
* ChineseTester used to test test recognition
*
*
*
* @author Yong Zhu
* @since 1.0
*/
public class LetterTester implements EnvObject {
public static final String STR = "一二三";
public static final int TIME = 120;
@Override
public void build() { // do nothing
}
@Override
public void destory() {// do nothing
}
@Override
public void active(int screen) {
Frog frog = Env.frogs.get(screen * Env.FROG_PER_SCREEN); // 这个测试只针对每屏的第一只青蛙,因为脑图固定只显示第一只青蛙
Eye eye = frog.findOrganByName("Eye");
Ear ear = frog.findOrganByName("Ear");
int index = Env.step / TIME;
if (Env.step % TIME == 0)
frog.prepareNewTraining();
if (index < STR.length()) {
BrainPicture.setNote("第" + (index + 1) + "个字训练");
ear.hearSound(frog, index);
eye.seeImageWithOffset(frog, StringPixelUtils.getSanserif12Pixels(STR.substring(index, index + 1)),0,0);
} else {
int index2 = index % STR.length();
BrainPicture.setNote("第" + (index2 + 1) + "个字识别");
eye.seeImageWithOffset(frog, StringPixelUtils.getSanserif12Pixels(STR.substring(index2, index2 + 1)),1,1);
if (Env.step % TIME > (TIME - 2)) {
int result = ear.readcode(frog);
System.out.println("Max=" + result+", 即 '"+STR.substring(result, result+1)+"'");
frog.prepareNewTraining();
}
}
}
}

@ -29,7 +29,7 @@ public class ColorUtils {
public static final int GRAY = 7;
private static final Color[] rainbow = new Color[] { Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.CYAN,
Color.BLUE, Color.MAGENTA,Color.GRAY };
Color.BLUE, Color.MAGENTA, Color.GRAY };
private static int nextColor = 0;
@ -51,20 +51,12 @@ public class ColorUtils {
}
public static Color rainbowColor(float i) { // 根据数值大小范围在8种彩虹色中取值
if (i == 0)
return Color.BLACK;
if (i == 1)
return Color.RED;
if (i <= 3)
return Color.ORANGE;
if (i <= 10)
return Color.YELLOW;
if (i <= 20)
return Color.GREEN;
return Color.GRAY;
if (i <= 30)
return Color.BLACK;
if (i <= 50)
return Color.CYAN;
if (i <= 100)
return Color.BLUE;
return Color.RED;
return Color.MAGENTA;
}
}

@ -22,7 +22,7 @@ import com.github.drinkjava2.frog.util.EggTool;
@SuppressWarnings("serial")
public class Env extends JPanel {
/** Speed of test */
public static final int SHOW_SPEED = 1; // 测试速度1~1000,可调, 数值越小,速度越慢
public static final int SHOW_SPEED = 5; // 测试速度1~1000,可调, 数值越小,速度越慢
public static final int ENV_WIDTH = 400; // 虚拟环境的宽度, 可调

@ -27,7 +27,7 @@ import com.github.drinkjava2.frog.util.RandomUtils;
@SuppressWarnings("all")
public class Env extends JPanel {
/** Speed of test */
public static final int SHOW_SPEED = 500; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
public static final int SHOW_SPEED = 100; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
/** Delete eggs at beginning of each run */
public static final boolean DELETE_EGGS = true;// 每次运行是否先删除保存的蛋
@ -36,7 +36,7 @@ public class Env extends JPanel {
public static final int FROG_PER_EGG = 4; // 每个蛋可以孵出几个青蛙
public static final int SCREEN = 1; // 分几屏测完
public static final int SCREEN = 2; // 分几屏测完
public static final int FROG_PER_SCREEN = EGG_QTY * FROG_PER_EGG / SCREEN; // 每屏上显示几个青蛙,这个数值由上面三个参数计算得来

@ -27,10 +27,10 @@ import com.github.drinkjava2.frog.util.RandomUtils;
@SuppressWarnings("all")
public class Env extends JPanel {
/** Speed of test */
public static final int SHOW_SPEED = 2000; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
public static final int SHOW_SPEED = 800; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
/** Delete eggs at beginning of each run */
public static final boolean DELETE_EGGS = false;// 每次运行是否先删除保存的蛋
public static final boolean DELETE_EGGS = true;// 每次运行是否先删除保存的蛋
public static final int EGG_QTY = 25; // 每轮下n个蛋可调只有最优秀的前n个青蛙们才允许下蛋

@ -90,10 +90,11 @@ public class Egg implements Serializable {
organs.add(new RFootFeelDown().setXYRN(800, 600, 30, "FeelDown"));// 底脚降下感受细胞
for (int i = 0; i <= 10; i++)
organs.add(new FootPosFeel().setXYRN(FootPosFeel.RFOOTPOSSTART_X + i * 30, 650, 10, "")); // 底脚位置感受细胞
for (int i = 0; i < 5; i++) {
organs.add(new LogicAnd().setXYRN(100+i*30, 10, 5, "")); // 底脚位置感受细胞
organs.add(new LogicNot().setXYRN(100+i*30, 50, 5, "")); // 底脚位置感受细胞
}
//for (int i = 0; i < 5; i++) {
// organs.add(new LogicAnd().setXYRN(100+i*30, 10, 5, "")); // 逻辑与器官,经测试没用上,暂排除
// organs.add(new LogicNot().setXYRN(100+i*30, 50, 5, "")); // 逻辑非器官,经测试没用上,暂排除
//}
// 以上器官就是FIXED_ORGAN_QTY值
FIXED_ORGAN_QTY = organs.size();

@ -12,11 +12,12 @@ hl330
陈凯文
chanvictoire
Ad
涤青
目前收入总额:278.77元
涤青
张四峰
目前收入总额:288.77元
支出(按时间顺序)
目前支出总额:0元
目前余额278.77元
目前余额288.77元
Loading…
Cancel
Save