pull/1/head
Yong Zhu 5 years ago
parent 0ace11050a
commit 4d048cdb35

File diff suppressed because one or more lines are too long

@ -11,11 +11,10 @@ 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.Material;
import com.github.drinkjava2.frog.objects.EnvObject;
import com.github.drinkjava2.frog.util.RandomUtils;
import com.github.drinkjava2.frog.util.StringPixelUtils;
/**
* Env is the living space of frog. draw it on JPanel
@ -39,10 +38,10 @@ 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 Room */ // 脑空间是个三维Room数组,为节约内存,仅在用到数组元素时才去初始化这维,按需分配内存
/** 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_YSIZE = 20; // frog的脑在Y方向长度
public static final int FROG_BRAIN_ZSIZE = 20; // frog的脑在Z方向长度
public static final int FROG_BRAIN_ZSIZE = 25; // frog的脑在Z方向长度
/** SHOW first frog's brain structure */
public static boolean SHOW_FIRST_FROG_BRAIN = true; // 是否显示脑图在Env区的右侧
@ -60,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 = 2000;// 每轮测试步数,可调
public static final int STEPS_PER_ROUND = 100;// 每轮测试步数,可调
public static int step;// 当前测试步数
public static final int FOOD_QTY = 100; // 食物数量, 可调
@ -76,7 +75,7 @@ public class Env extends JPanel {
public static EnvObject[] things = new EnvObject[] { new LetterTester() };// 所有外界物体如食物、字母测试工具都放在这个things里面
static {
static {
System.out.println("唵缚悉波罗摩尼莎诃!"); // 杀生前先打印往生咒见码云issue#IW4H8
if (DELETE_EGGS)
EggTool.deleteEggs();
@ -242,7 +241,7 @@ public class Env extends JPanel {
Application.brainPic.drawBrainPicture(firstFrog);
for (int j = 0; j < FROG_PER_SCREEN; j++) {
Frog f = frogs.get(screen * FROG_PER_SCREEN + j);
f.rooms = null; // 清空frog脑细胞所占用的内存
f.cells = null; // 清空frog脑细胞所占用的内存
}
Application.mainFrame.setTitle(new StringBuilder("Round: ").append(round).append(", screen:")
.append(screen).append(", ").append(foodFoundCountText()).append(", 用时: ")

@ -20,23 +20,23 @@ import javax.imageio.ImageIO;
import com.github.drinkjava2.frog.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.brain.Room;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.egg.Egg;
import com.github.drinkjava2.frog.objects.Material;
/**
* Frog = organs + rooms <br/>
* rooms = brain cells + photons <br/>
* Frog = organs + cells <br/>
* cells = brain cells + photons <br/>
* organs = cell parameters + cell actions
*
* Organroomsroom
* Organcellscell
*
* @author Yong Zhu
* @since 1.0
*/
public class Frog {
/** brain rooms */
public Room[][][] rooms;// 一开始不要初始化只在调用getRoom方法时才初始化相关维以节约内存
/** brain cells */
public Cell[][][] cells;// 一开始不要初始化只在调用getCell方法时才初始化相关维以节约内存
/** organs */
public List<Organ> organs = new ArrayList<>();
@ -65,7 +65,7 @@ public class Frog {
public void initFrog() {// 仅在测试之前调用这个方法初始化frog以节约内存测试完成后要清空units释放内存
try {
rooms = new Room[Env.FROG_BRAIN_XSIZE][][]; // 为了节约内存先只初始化三维数组的x维另两维用到时再分配
cells = new Cell[Env.FROG_BRAIN_XSIZE][][]; // 为了节约内存先只初始化三维数组的x维另两维用到时再分配
} catch (OutOfMemoryError e) {
System.out.println("OutOfMemoryError found for frog, force it die.");
this.alive = false;
@ -89,22 +89,28 @@ public class Frog {
if (!alive)
return;
for (int x = o.x; x < o.x + o.xe; x++)
for (int y = o.y; y < o.y + o.ye; y++)
for (int z = o.z; z < o.z + o.ze; z++)
getRoom(x, y, z).setActive(active);
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).setActive(active);
}
/** Calculate organ activity by add all organ rooms' active value together */
public float getCuboidActiveTotalValue(Cuboid o) {// 遍历长方体区域所在room,将它们的激活值汇总返回
/** Calculate organ activity by add all organ cells' active value together */
public float getCuboidActiveTotalValue(Cuboid o) {// 遍历长方体区域所在cell,将它们的激活值汇总返回
float activity = 0;
for (int x = o.x; x < o.x + o.xe; x++)
for (int y = o.y; y < o.y + o.ye; y++)
for (int z = o.z; z < o.z + o.ze; z++)
activity += this.getRoom(x, y, z).getActive();
activity += this.getOrCreateCell(x, y, z).getActive();
return activity;
}
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,12 +121,17 @@ public class Frog {
for (Organ o : organs)
o.active(this); // 调用每个器官的active方法 通常只用于执行器官的外界信息输入、动作输出,脑细胞的遍历不是在这一步
// 这里是最关键的脑细胞主循环,脑细胞负责捕获和发出光子,光子则沿它的矢量方向每次自动走一格,如果下一格是真空(即数组room元素未初始化会继续走下去并衰减(为减少运算)直到能量为0
// 这里是最关键的脑细胞主循环,脑细胞负责捕获和发送光子,光子则沿它的矢量方向每次自动走一格,如果下一格是真空(即cell未初始化会继续走下去并衰减直到为0(为减少运算)
for (int i = 0; i < Env.FROG_BRAIN_XSIZE; i++)
for (int j = 0; j < Env.FROG_BRAIN_YSIZE; j++)
for (int k = 0; k < Env.FROG_BRAIN_ZSIZE; k++) {
//TODO 脑细胞主循环
}
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.getActions() != null)
cell.execute(this, activeNo, i, j, k);// 调用cell的方法来进行这个运算
}
return alive;
}
@ -130,23 +141,32 @@ public class Frog {
g.drawImage(frogImg, x - 8, y - 8, 16, 16, null);
}
/** Check if room exist */
public boolean existRoom(int x, int y, int z) {// 检查指定坐标room是否存在
return rooms[x] != null && rooms[x][y] != null && rooms[x][y][z] != null;
/** Check if cell exist */
public Cell getCell(int x, int y, int z) {// 返回指定脑ssf坐标的cell 如果不存在返回null
if (cells[x] == null || cells[x][y] == null)
return null;
return cells[x][y][z];
}
/** Get a room in position (x,y,z), if not exist, create a new one */
public Room getRoom(int x, int y, int z) {// 获取指定坐标的Room如果为空则在指定位置新建Room
if (rooms[x] == null)
rooms[x] = new Room[Env.FROG_BRAIN_YSIZE][];
if (rooms[x][y] == null)
rooms[x][y] = new Room[Env.FROG_BRAIN_ZSIZE];
if (rooms[x][y][z] == null) {
Room unit = new Room();
rooms[x][y][z] = unit;
return unit;
} else
return rooms[x][y][z];
/** 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))
return null;
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();
cells[x][y][z] = cell;
}
return cell;
}
/** Check if x,y,z out of frog's brain bound */
public static boolean outBrainBound(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;
}
}

@ -11,21 +11,18 @@
package com.github.drinkjava2.frog.brain;
/**
* CellAction defines cell action
* Action is the action of cell, one cell can have multiple actions
*
* CellActionact
* ActionCellaction
*
* @author Yong Zhu
* @since 2.0.2
*/
public interface CellAction {
public class Action {
public Organ organ; // 细胞属于哪个器官
public Action(Organ organ) {// Action不保存在蛋里不需要定义空构造器
this.organ = organ;
}
/**
* Each cell's act method will be called once at each loop step
*
* actact
* )
*
*/
public void act(Cell cell, int x, int y, int z);
}

@ -1,14 +1,8 @@
package com.github.drinkjava2.frog.brain;
import static java.awt.Color.BLACK;
import static java.awt.Color.BLUE;
import static java.awt.Color.CYAN;
import static java.awt.Color.GREEN;
import static java.awt.Color.MAGENTA;
import static java.awt.Color.ORANGE;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
import static java.awt.Color.YELLOW;
//import static java.awt.BLUE;
import static java.lang.Math.cos;
import static java.lang.Math.round;
@ -16,29 +10,35 @@ import static java.lang.Math.sin;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.util.ColorUtils;
/**
* BrainPicture show first frog's brain structure, for debug purpose only
*
* 3
* tflr,x5
*
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class BrainPicture extends JPanel {
private static final float d90 = (float) (Math.PI / 2);
Color picColor = RED;
int brainDispWidth; // screen display piexls width
float scale; // brain scale
int xOffset = 0; // brain display x offset compare to screen
int yOffset = 0; // brain display y offset compare to screen
float xAngle = (float) (Math.PI / 2.5); // brain rotate on x axis
float yAngle = -(float) (Math.PI / 8); // brain rotate on y axis
float xAngle = d90 * .8f; // brain rotate on x axis
float yAngle = d90 / 4; // brain rotate on y axis
float zAngle = 0;// brain rotate on z axis
public BrainPicture(int x, int y, float brainWidth, int brainDispWidth) {
@ -48,9 +48,42 @@ public class BrainPicture extends JPanel {
scale = 0.7f * brainDispWidth / brainWidth;
this.setBounds(x, y, brainDispWidth + 1, brainDispWidth + 1);
MouseAction act = new MouseAction(this);
this.addMouseListener(act);
this.addMouseWheelListener(act);
this.addMouseMotionListener(act);
this.addMouseListener(act); // 添加鼠标动作监听
this.addMouseWheelListener(act);// 添加鼠标滚轮动作监听
this.addMouseMotionListener(act);// 添加鼠标移动动作监听
this.setFocusable(true);
addKeyListener(new KeyAdapter() {// 处理t,f,l,rx键盘命令
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case 'T':// 顶视
xAngle = 0;
yAngle = 0;
zAngle = 0;
break;
case 'F':// 前视
xAngle = d90;
yAngle = 0;
zAngle = 0;
break;
case 'L':// 左视
xAngle = d90;
yAngle = d90;
zAngle = 0;
break;
case 'R':// 右视
xAngle = d90;
yAngle = -d90;
zAngle = 0;
break;
case 'X':// 斜视
xAngle = d90 * .8f;
yAngle = d90 / 4;
zAngle = 0;
break;
default:
}
}
});
}
public void drawCuboid(Cuboid c) {// 在脑图上画一个长立方体框架视角是TopView
@ -78,8 +111,8 @@ public class BrainPicture extends JPanel {
}
public void drawCone(Cone c) {// 在脑图上画一个锥体视角是TopView
drawLine(c.x1, c.y1, c.z1, c.x2, c.y2, c.z2);// 画锥体的中心线
//TODO 画出锥体的上下面
drawLine(c.x1, c.y1, c.z1, c.x2, c.y2, c.z2);// 画锥体的中心线
// TODO 画出锥体的上下面
}
/*-
@ -145,11 +178,16 @@ public class BrainPicture extends JPanel {
(int) round(y2) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset);
}
/** 画出Room的中心点 */
public void drawRoomCenter(float x, float y, float z) {
/** 画出cell的中心点通常用来显示器官的激活区 */
public void drawCellCenter(float x, float y, float z) {
drawPoint(x + 0.5f, y + 0.5f, z + 0.5f, (int) Math.max(1, Math.round(scale * .7)));
}
/** 画出cell的中心小点通常用来显示光子 */
public void drawCellSmallCenter(float x, float y, float z) {
drawPoint(x + 0.5f, y + 0.5f, z + 0.5f, (int) Math.max(1, Math.round(scale * .15)));
}
/** 画点固定以top视角的角度所以只需要在x1,y1位置画一个点 */
public void drawPoint(float px1, float py1, float pz1, int diameter) {
double x1 = px1 - Env.FROG_BRAIN_XSIZE / 2;
@ -180,33 +218,6 @@ public class BrainPicture extends JPanel {
(int) round(y1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset - diameter / 2, diameter, diameter);
}
private static final Color[] rainbow = new Color[] { RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA };
private static int nextColor = 0;
public static Color nextRainbowColor() {
if (nextColor == rainbow.length)
nextColor = 0;
return rainbow[nextColor++];
}
public static Color rainbowColor(float i) {
if (i == 0)
return BLACK;
if (i == 1)
return RED;
if (i <= 3)
return ORANGE;
if (i <= 10)
return YELLOW;
if (i <= 20)
return GREEN;
if (i <= 50)
return CYAN;
if (i <= 100)
return BLUE;
return MAGENTA;
}
private static Cuboid brain = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE);
public void drawBrainPicture(Frog f) {// 在这个方法里进行青蛙三维脑结构的绘制
@ -229,14 +240,20 @@ 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.rooms[x] != null)
for (int x = 0; x < Env.FROG_BRAIN_XSIZE; x++) {// 开始画整个脑空间的光子和激活点阵图
if (f.cells[x] != null)
for (int y = 0; y < Env.FROG_BRAIN_YSIZE; y++) {
if (f.rooms[x][y] != null)
if (f.cells[x][y] != null)
for (int z = 0; z < Env.FROG_BRAIN_ZSIZE; z++) {
if (f.existRoom(x, y, z) && f.getRoom(x, y, z).getActive() > 0) {
setPicColor(rainbowColor(f.getRoom(x, y, z).getActive()));
drawRoomCenter(x, y, z);
Cell cell = f.getCell(x, y, z);
if (cell != null) {
if (cell.getActive() > 0) {
setPicColor(ColorUtils.rainbowColor(cell.getActive()));
drawCellCenter(x, y, z);
} else if (cell.getPhotonQty() > 0) {
setPicColor(ColorUtils.colorByCode(cell.getColor()));
drawCellSmallCenter(x, y, z);
}
}
}
}

@ -10,35 +10,136 @@
*/
package com.github.drinkjava2.frog.brain;
import java.util.Arrays;
import com.github.drinkjava2.frog.Frog;
/**
* Cell is the basic unit of frog's brain
*
* Cell()orgran
* Cell
*
* synapses
*
*
* synapse
* Cell is the smallest unit of brain space, a Cell can have many actions and
* photons
*
* OrganOrgan)
* CellOrgan
* 使);360
* Cell(Action)(Photon)frogcells
*
* @author Yong Zhu
* @since 2.0.2
* @since 1.0
*/
public class Cell {// Cell是脑神经元将来脑里会有上亿个脑细胞为节约内存不重要的、与细胞状态无关的参数都存放在Organ类中去了。
public class Cell {
/** Active of current cell */
private float active = 0; // 这个cell的激活程度允许是负值,它反映了在这个小立方体里所有光子的能量汇总值
private Action[] actions = null;
private Photon[] photons = null;
private int color;// Cell的颜色取最后一次被添加的光子的颜色颜色不重要但能方便观察
private int photonQty = 0;
public Action[] getActions() {// 为了节约内存仅在访问actions时创建它的实例
if (actions == null)
actions = new Action[] {};
return actions;
}
public Photon[] getPhotons() {// 为了节约内存仅在访问photons时创建它的实例
if (photons == null)
photons = new Photon[] {};
return photons;
}
public void addAction(Action cell) {// 每个Cell可以存在多个行为通常只在青蛙初始化器官时调用这个方法
if (actions == null)
actions = new Action[] {};
actions = Arrays.copyOf(actions, actions.length + 1);
actions[actions.length - 1] = cell;
}
public Cell(Organ organ) {// Cell不保存在蛋里不需要定义空构造器
this.organ = organ;
public void addPhoton(Photon p) {// 每个cell空间可以存在多个光子
if (p == null)
return;
p.energy *= .78;
if (p.energy < 0.1)
return;
photonQty++;
color = p.color; // Cell的颜色取最后一次被添加的光子的颜色
if (photons == null)
photons = new Photon[] {};// 创建数组
else
for (int i = 0; i < photons.length; i++) { // 找空位插入
if (photons[i] == null || photons[i].energy < 0.1) {
photons[i] = p;
return; // 如找到就插入,返回
}
}
photons = Arrays.copyOf(photons, photons.length + 1);// 否则追加新光子到未尾
photons[photons.length - 1] = p;
}
/** energy of cell, energy got from food */
public float energy = 0; // 每个细胞当前的能量值
public void removePhoton(int i) {// 删第几个光子
if (photons[i] != null) {
photons[i] = null;
photonQty--;
}
}
/** Photon always walk */
public void photonWalk(Frog f, Photon p) { // 光子自已会走到下一格,如果下一格为空,继续走,直到能量耗尽或出界
if (p.energy < 0.1)
return;// 能量小的光子直接扔掉
if (p.outBrainBound())
return; //// 出界的光子直接扔掉
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 = f.getCell(rx, ry, rz);
if (cell != null) {
cell.addPhoton(p);
} else {
// p.energy *= .6;// 真空中也要乘一个衰减系数,防止它走太远,占用计算资源
photonWalk(f, p);// 递归一直走下去直到遇到cell或出界
}
}
/** Move photons and call cell's execute method */
public void execute(Frog f, int activeNo, int x, int y, int z) {// 主运行方法,进行实际的脑细经元的行为和光子移动
if (actions != null)
for (Action action : actions)
CellActions.act(f, activeNo, this, action, x, y, z); // 调用每个细胞的act方法处理掉所在cell的光子
// 剩下的光子自已会走到下一格,光子自己是会走的,而且是直线传播
if (photons != null)
for (int i = 0; i < photons.length; i++) {
Photon p = photons[i];
if (p == null || p.activeNo == activeNo)// 同一轮新产生的光子或处理过的光子不再走了
continue;
p.activeNo = activeNo;
removePhoton(i);// 原来的位置的先清除去除它的Java对象引用
photonWalk(f, p); // 让光子自已往下走
}
}
public float getActive() {// 获取cell的激活度
return active;
}
/** Organ index in egg */
public Organ organ; // 细胞属于哪个器官
public void setActive(float active) {// 设cell的激活度
this.active = active;
}
public int getPhotonQty() {// 获取cell里的总光子数
return photonQty;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public Synapse[] synapses; // 动态触突, 详见上面解说,通常是只在最活跃的几个光子输入信号的来源方向上建立动态触突
}

@ -11,11 +11,12 @@
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* CellActions have many cell action stored
*
* CellActionsacttype
* CellActionsacttype
*
* @author Yong Zhu
* @since 2.0.2
@ -25,7 +26,7 @@ public class CellActions {
/*-
* Each cell's act method will be called once at each loop step
*
* actact
* act
* )
*
*
@ -36,10 +37,29 @@ public class CellActions {
*
*
*/
public void act(Frog f, int type, Cell cell, int x, int y, int z) {
switch (type) { //添加细胞的行为,这是硬编码
case Organ.EYE:
public static void act(Frog f, int actionNo, Cell cell, Action action, int x, int y, int z) {
Organ o = action.organ;
switch (o.type) { // 添加细胞的行为,这是硬编码
case Organ.EYE: // 如果是视网膜细胞它的行为是将Cell的激活值转化为向右的多个光子发散出去模拟波源
if (cell.getActive() > 0 && RandomUtils.percent(30)) {
for (float yy = -0.3f; yy <= 0.3f; yy += 0.1) {// 形成一个扇面向右发送
for (float zz = -0.3f; zz <= 0.3f; zz += 0.1) {
cell.addPhoton(new Photon(o.color, x, y, z, 1.0f, yy, zz, 100f));
}
}
}
break;
case Organ.EAR: // 如果是听力细胞它的行为是将cell的激活能量转化为向下的多个光子发散出去模拟波源
if (cell.getActive() > 0 && RandomUtils.percent(30)) {
for (float xx = -0.3f; xx <= 0.3f; xx += 0.13) {// 形成一个扇面向下发送
for (float yy = -0.3f; yy <= 0.3f; yy += 0.13) {
cell.addPhoton(new Photon(o.color, x, y, z, xx, yy, -1, 100f));
}
}
}
break;
case Organ.DYNAMIC:// 如果是动态细胞,它的行为是。。。比较复杂,一言难尽。
break;
default:

@ -55,8 +55,14 @@ public class Cone implements Shape {
}
@Override
public void fillCells(Frog f, Organ o) {
public void fillCellsWithAction(Frog f, Organ o) {
// TODO 待添加Cone形器官播种脑细胞的代码
}
@Override
public void createCells(Frog f, Organ o) {
// TODO 待添加Cone形器官createCells的代码
}
}

@ -59,12 +59,20 @@ public class Cuboid implements Shape {
}
@Override
public void fillCells(Frog f, Organ o) {
public void fillCellsWithAction(Frog f, Organ o) {
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.getRoom(i, j, k).addCell(new Cell(o));
Cell cell = f.getOrCreateCell(i, j, k);
if (cell != null)
cell.addAction(new Action(o));
}
}
public void createCells(Frog f, Organ o) {
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);
}
}

@ -25,8 +25,8 @@ import com.github.drinkjava2.frog.util.RandomUtils;
* ,
*
*
*
* ,
*
* ,
*
*
*
@ -54,13 +54,15 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
private static final long serialVersionUID = 1L;
// 以下是各种器官类型每个神经元都属于一个器官每个器官都有一个type类型参数
public static final int EYE = 1;// 眼细胞会根据room激活度产生发散到各个方向的光子
public static final int EAR = 2;// 耳细胞,类似眼细胞,不同点是为了简化脑内听觉区和输入区混用一个区所以它也可吸收光子倒过来激活room
public static final int EMPTY = 0;// 空细胞,不处理光子
public static final int EYE = 1;// 眼细胞会根据cell激活度产生发散到各个方向的光子
public static final int EAR = 2;// 耳细胞,类似眼细胞,不同点是为了简化脑内听觉区和输入区混用一个区所以它也可吸收光子倒过来激活cell
public static final int CORE = 3; // 什么触突都没有光溜溜的细胞但它也有可能根据r半径来中转光子
public static final int DYNAMIC = 4; // 只有动态触突的细胞,它忽略静态触突参数
public static final int STATIC = 5; // 只有静态触突的细胞,它忽略动态触突参数
public static final int MIX = 6; // 同时具有静态和动态触突的细胞
public static final int TYPE_QTY = 7;// 所有的type都是预先写好在这里的自动生成的type也只能在写好的type里选一个
public int color = 1;// 这个不重要表示它生成的光子的显示在脑图中的颜色号见ColorUtils
public float fat = 0;// 细胞活跃多则fat值大如果fat值很低则这个器官被丢弃的可能性加大这个值很重要它使得孤岛器官被淘汰
public boolean allowVary;// 是否允许变异,有一些器官是手工创建的,在项目初级阶段禁止它们参与变异和生存竟争。
@ -73,7 +75,7 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
public Shape shape; // 器官的形状,不同的形状要写出不同的播种行为
public float cellDistance; // 细胞播种间隔,每隔多少个room放一个细胞
public float cellDistance; // 细胞播种间隔,每隔多少个cell放一个action
public float centerDensityRate; // 中心相对于边沿的细胞播种密度比为1时为均匀分布
@ -142,7 +144,9 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
/** Only call once when frog created , Child class can override this method */
public void init(Frog f) { // 在青蛙生成时会调用这个方法,进行一些初始化,通常是根据参数来播种脑细胞
// 这里是器官播种脑细胞的具体代码,对于手工生成的器官可以重写这个方法对于自动生成的器官必须根据type和shape等来播种要写死在这里
// 里是器官播种脑细胞的具体代码,对于手工生成的器官也可以重写这个方法对于自动生成的器官必须根据type和shape等来播种要写死在这里
if (shape != null)
shape.fillCellsWithAction(f, this); // 先均匀播种脑细胞试试
}
/** each step will call Organ's active methodd */
@ -156,7 +160,7 @@ public class Organ implements Serializable, Cloneable {// 因为要保存在蛋
return;// 如果没有形状,就不画
if (!Env.SHOW_FIRST_FROG_BRAIN || !f.alive) // 如果不允许画或青蛙死了,就直接返回
return;
pic.setPicColor(Color.LIGHT_GRAY); // 缺省是
pic.setPicColor(Color.LIGHT_GRAY); // 缺省是
shape.drawOnBrainPicture(pic);
}

@ -10,28 +10,46 @@
*/
package com.github.drinkjava2.frog.brain;
import com.github.drinkjava2.frog.Env;
/**
* Photon has direction and strength
*
* x,y,z(1)
* x,y,zmx,my,mz
* Cell
*
* @author Yong Zhu
* @since 2.0.2
*/
public class Photon {
public float x;// 用单位向量的形式表示矢量方向x,y,z的平方和必须为1
public float x;
public float y;
public float z;
public float mx;
public float my;
public float mz;
public float energy;
public int color;// 每个光子都有自已的颜色,与产生光子的器官的颜色来决定,颜色不重要,但能方便观察
public int activeNo;// 每一轮循环都有一个编号,光子走一格后就加上这个编号,同一个循环如果遇到相同编号的光子就不跳过,防止光子被一直赶着走多步
public Photon() { // 缺省构造器
}
public Photon(float x, float y, float z, float energy) {
public Photon(int color, float x, float y, float z, float mx, float my, float mz, float energy) {
this.x = x;
this.y = y;
this.z = z;
this.mx = mx;
this.my = my;
this.mz = mz;
this.energy = energy;
this.color = color;
}
/** 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;
}
}

@ -1,75 +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 java.util.Arrays;
/**
* Room is the smallest unit of brain space, a room can have 0~n cells and 0~n
* photons
*
* Room(Cell)(Photon)frogrooms
* RoomCube, Room
*
* @author Yong Zhu
* @since 1.0
*/
public class Room {
/** Activity of current room */
private float active = 0; // 这个立方体的激活程度,允许是负值,它反映了在这个小立方体里所有光子的能量汇总值,room总是随时间自动衰减
private Cell[] cells = null;
private Photon[] photons = null;
public Cell[] getCells() {// 为了节约内存仅在访问cells时创建它的实例
if (cells == null)
cells = new Cell[] {};
return cells;
}
public Photon[] getPhotons() {// 为了节约内存仅在访问photons时创建它的实例
if (photons == null)
photons = new Photon[] {};
return photons;
}
public void addCell(Cell cell) {// 每个方格空间可以存在多个脑细胞
if (cells == null)
cells = new Cell[] {};
cells = Arrays.copyOf(cells, cells.length + 1);
cells[cells.length - 1] = cell;
}
public void addPhoton(Photon p) {// 每个方格空间可以存在多个光子
if (photons == null)
photons = new Photon[] {};
for (Photon old : photons)
if (old.energy < 0.01 && p.energy > -0.01) {// 如果能量没有了,用新的代替空位
old.x = p.x;
old.y = p.y;
old.z = p.z;
old.energy = p.energy;
return;
}
photons = Arrays.copyOf(photons, photons.length + 1);// 否则追加新光子到未尾
photons[cells.length - 1] = p;
}
public float getActive() {
return active;
}
public void setActive(float active) {
this.active = active;
}
}

@ -24,7 +24,9 @@ import com.github.drinkjava2.frog.Frog;
*/
public interface Shape extends Serializable {
/* Draw self on brain picture */
public void drawOnBrainPicture(BrainPicture pic); //把自己在脑图上画出来
public void fillCells(Frog f, Organ o); //根据给定organ的参数在shape所代表的脑区内播种脑细胞
public void drawOnBrainPicture(BrainPicture pic); // 把自己在脑图上画出来
public void fillCellsWithAction(Frog f, Organ o); // 根据给定organ的参数在shape所代表的脑区内添加脑细胞并加入对应细胞的行为
public void createCells(Frog f, Organ o); // 在organ所代表的脑区内仅创建空的Cell对象
}

@ -0,0 +1,44 @@
/*
* 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.brain.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Dynamic organ fill cells with dynamic type action
*
* Dynamicdynamic
*
* ()
* 穿
*
* Dynamic)
* OutofMemoryException),
*
*
* @author Yong Zhu
*/
public class Dynamic extends Organ {
private static final long serialVersionUID = 1L;
public Dynamic() {
super();
this.shape = new Cuboid(8, 5, 5, Env.FROG_BRAIN_XSIZE / 2 + 2, Env.FROG_BRAIN_YSIZE / 2 + 5,
Env.FROG_BRAIN_ZSIZE / 2);
this.organName = "Ether";
this.type = Organ.DYNAMIC; // DYNAMIC就是动态触突细胞
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
}
}

@ -26,34 +26,31 @@ import com.github.drinkjava2.frog.brain.Organ;
@SuppressWarnings("all")
public class Ear extends Organ {// 耳朵也是长方体,我为什么要用也?
private static final long serialVersionUID = 1L;
public int n = 18; // 眼睛有n x n个感光细胞 用随机试错算法自动变异(加1或减1最小是3x3)
public Cuboid a = new Cuboid(10, 10, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Cuboid b = new Cuboid(10, 15, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Cuboid c = new Cuboid(15, 10, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Cuboid d = new Cuboid(15, 15, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Cuboid a = new Cuboid(12, 10, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Cuboid b = new Cuboid(12, 15, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Cuboid c = new Cuboid(17, 10, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Cuboid d = new Cuboid(17, 15, Env.FROG_BRAIN_ZSIZE - 1, 3, 3, 1);
public Ear() {
this.shape = new Cuboid(10, 10, Env.FROG_BRAIN_ZSIZE - 1, 8, 8, 1);
this.shape = new Cuboid(12, 10, Env.FROG_BRAIN_ZSIZE - 1, 8, 8, 1);// 手工固定耳区的大小
this.type = Organ.EAR;
this.organName = "ear";
this.allowVary = false;
this.allowBorrow = false;
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
this.color = 5;// blue see ColorUtils
}
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法
super.drawOnBrainPicture(f, pic);
super.drawOnBrainPicture(f, pic); // 父类方法显示shape形状
pic.drawCuboid(a);// 显示abcd位置在脑图上
pic.drawCuboid(b);
pic.drawCuboid(c);
pic.drawCuboid(d);
}
public void init(Frog f) { // 重写父类方法,播种听力输入细胞,它会将听力区的激活转变成固定向下发散的多个光子,摸拟波源
shape.fillCells(f, this);
}
/** 给这个耳朵听到一个字母,激活它的听觉输入区, 注意听觉输入区并不等于脑内虚拟听觉成像区,但是第一版...先共用一个区吧 */
public void hearSound(Frog f, String letter) {
f.setCuboidVales(getCuboidByStr(letter), 20);
f.setCuboidVales(getCuboidByStr(letter), 80);
}
/** 给这个耳朵听到一个字母,激活它的听觉输入区, 注意听觉输入区并不等于听觉成像区 */

@ -0,0 +1,42 @@
/*
* 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.Cuboid;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Empty is a special organ has no cell, only used as media for photon
*
* Emptycellcell
*
* @author Yong Zhu
*/
public class Empty extends Organ {
private static final long serialVersionUID = 1L;
public Empty() {
super();
this.shape = new Cuboid(2, 2, 2, Env.FROG_BRAIN_XSIZE-4, Env.FROG_BRAIN_YSIZE-4, Env.FROG_BRAIN_ZSIZE-4);
this.organName = "Empty";
this.type = Organ.EMPTY; // Empty这个器官并不播种cell,它存在的唯一目的只是充当光子媒介,否则光子会一直走下去消失
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
}
@Override
public void init(Frog f) {// 覆盖父类方法不添加cell的action只是创建空的cell
shape.createCells(f, this);
}
}

@ -1,53 +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;
/**
* Ether is a special organ, it fill all rooms with dynamic type cells
*
* Ether)roomdynamic
*
* ()
* 穿
*
*
* OutofMemoryException),
*
*
* @author Yong Zhu
*/
public class Ether extends Organ {
private static final long serialVersionUID = 1L;
public Ether() {
super();
this.shape = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE);
this.organName = "Ether";
this.type = Organ.DYNAMIC;
this.allowVary = false;
this.allowBorrow = false;
}
public void init(Frog f) { // 重写父类方法,均匀播种脑细胞
for (int x = 0; x < Env.FROG_BRAIN_XSIZE; x++)
for (int y = 0; y < Env.FROG_BRAIN_YSIZE; y++)
for (int z = 0; z < Env.FROG_BRAIN_ZSIZE; z++) {
f.getRoom(x, y, z).addCell(new Cell(this));
}
}
}

@ -24,18 +24,11 @@ public class Eye extends Organ {// 眼睛是长方体
public Eye() {
this.shape = new Cuboid(0, 5, 5, 1, 10, 10);
this.type = Organ.EYE;
this.organName = "eye";
this.allowVary = false;
this.allowBorrow = false;
}
public void init(Frog f) { // 重写父类方法,播种视网膜细胞,它会将视网膜的激活转变成固定向右发散的多个光子,摸拟波源
shape.fillCells(f, this);
}
/** each step will call Organ's active methodd */
public void active(Frog f) { // 每一步测试都会调用active方法通常用于手动生成的器官
// do nothing
this.allowVary = false;// 不允许变异
this.allowBorrow = false;// 不允许借出
this.color = 0;// red, see ColorUtils
}
/**
@ -50,11 +43,11 @@ public class Eye extends Organ {// 眼睛是长方体
int h = pixels[0].length;
Cuboid c = (Cuboid) shape;
// 在视网膜上产生字母像素点阵,即激活这个脑视网膜所在的rooms区然后由器官播种出的脑细胞负责将激活能量转为光子输送、存贮到其它位置
// 在视网膜上产生字母像素点阵,即激活这个脑视网膜所在的cells区然后由器官播种出的脑细胞负责将激活能量转为光子输送、存贮到其它位置
for (int px = 0; px < w; px++)
for (int py = 0; py < h; py++)
if (pixels[px][py] > 0)
f.getRoom(0, c.y + c.ye - px, c.z + py).setActive(20);
f.getOrCreateCell(0, c.y + c.ye - px, c.z + py).setActive(100);
}
}

@ -17,6 +17,8 @@ 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.Empty;
import com.github.drinkjava2.frog.brain.organ.Dynamic;
import com.github.drinkjava2.frog.brain.organ.Eye;
import com.github.drinkjava2.frog.util.RandomUtils;
@ -38,7 +40,8 @@ public class Egg implements Serializable {
public Egg() {// 无中生有,创建一个蛋,先有蛋,后有蛙
organs.add(new Eye()); // 眼是手工创建的,必有
organs.add(new Ear()); // 耳是手工创建的这个是用来测试ABCD字母识别的
organs.add(Organ.randomCuboidOrgan());
organs.add(new Empty()); // Empty什么都不干只用来作光子媒介
organs.add(new Dynamic()); // Dynamic具有动态触突
}
/** Create egg from frog */
@ -61,17 +64,17 @@ public class Egg implements Serializable {
if (RandomUtils.percent(70)) // 70%的情况下不作为, x就是受精卵
return;
// 从y里借一个organ替换掉原来位置的organ相当于DNA级别的片段切换它要求一个随机位置的Organ都允许替换allowBorrow
int yOrganSize = y.organs.size();
if (yOrganSize > 0) {
int i = RandomUtils.nextInt(yOrganSize);
Organ o = y.organs.get(i);
if (o.allowBorrow) {
if (organs.size() > i && organs.get(i).allowBorrow)
organs.set(i, o);// 用y里的organ替换掉x里的organ,模拟受精
}
}
if (RandomUtils.percent(50))// 有50%的机率随机会产生新的器官
organs.add(Organ.randomCuboidOrgan());
// int yOrganSize = y.organs.size();
// if (yOrganSize > 0) {
// int i = RandomUtils.nextInt(yOrganSize);
// Organ o = y.organs.get(i);
// if (o.allowBorrow) {
// if (organs.size() > i && organs.get(i).allowBorrow)
// organs.set(i, o);// 用y里的organ替换掉x里的organ,模拟受精
// }
// }
// if (RandomUtils.percent(50))// 有50%的机率随机会产生新的器官
// organs.add(Organ.randomCuboidOrgan());
if (RandomUtils.percent(organs.size())) {// 器官会随机丢失,并且机率与器官数量成正比,防止器官无限增长
int i = RandomUtils.nextInt(organs.size());
if (organs.get(i).allowBorrow)

@ -52,11 +52,11 @@ public class LetterTester implements EnvObject {
Ear ear = firstFrog.findOrganByName("ear");
if (Env.step < Env.STEPS_PER_ROUND / 2) {// 前半段同时还要激活与这个字母对应脑区(听觉输入区)
if (Env.step < Env.STEPS_PER_ROUND / 5*4) {// 前半段同时还要激活与这个字母对应脑区(听觉输入区)
ear.hearSound(firstFrog, letter);
} else if (Env.step == Env.STEPS_PER_ROUND / 2) {// 在中段取消字母对应脑区的激活
} else if (Env.step == Env.STEPS_PER_ROUND / 5*4) {// 在中段取消字母对应脑区的激活
ear.hearNothing(firstFrog);
} else if (Env.step > Env.STEPS_PER_ROUND / 2) {// 后半段要检测这个字母区是否能收到光子信号
} else if (Env.step > Env.STEPS_PER_ROUND / 5*4) {// 后半段要检测这个字母区是否能收到光子信号
if (firstFrog.getCuboidActiveTotalValue(ear.getCuboidByStr(letter)) > 0)
firstFrog.energy += 100;
//TODO 然后还要检测其它的区必须没有这个字母的区活跃

@ -0,0 +1,68 @@
/* 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.util;
import static java.awt.Color.BLACK;
import static java.awt.Color.BLUE;
import static java.awt.Color.CYAN;
import static java.awt.Color.GREEN;
import static java.awt.Color.MAGENTA;
import static java.awt.Color.ORANGE;
import static java.awt.Color.RED;
import static java.awt.Color.YELLOW;
import java.awt.Color;
/**
* Color Utilities used in this project
*
* @author Yong Zhu
* @since 1.0
*/
public class ColorUtils {
private static final Color[] rainbow = new Color[] { RED, ORANGE, YELLOW, GREEN, CYAN, BLUE, MAGENTA };
private static int nextColor = 0;
private ColorUtils() {// default private constr
}
public static int nextColorCode() {
return nextColor++;
}
public static Color nextRainbowColor() {// 返回下一个彩虹色
if (nextColor == rainbow.length)
nextColor = 0;
return rainbow[nextColor++];
}
public static Color colorByCode(int i) {// 数值取模后返回一个固定彩虹色
return rainbow[i % 7];
}
public static Color rainbowColor(float i) { // 根据数值大小范围在8种彩虹色中取值
if (i == 0)
return BLACK;
if (i == 1)
return RED;
if (i <= 3)
return ORANGE;
if (i <= 10)
return YELLOW;
if (i <= 20)
return GREEN;
if (i <= 50)
return CYAN;
if (i <= 100)
return BLUE;
return MAGENTA;
}
}

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