Trap & Active & Chance

pull/1/head
Yong Zhu 6 years ago
parent 2add4630e9
commit b090d746be

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

File diff suppressed because one or more lines are too long

@ -10,8 +10,10 @@ import java.util.Random;
import javax.swing.JPanel;
import com.github.drinkjava2.frog.brain.group.RandomConnectGroup;
import com.github.drinkjava2.frog.egg.Egg;
import com.github.drinkjava2.frog.egg.EggTool;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Env is the living space of frog. draw it on JPanel
@ -22,7 +24,7 @@ import com.github.drinkjava2.frog.egg.EggTool;
@SuppressWarnings("serial")
public class Env extends JPanel {
/** Speed of test */
public static int SHOW_SPEED = 5; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
public static int SHOW_SPEED = 20; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
/** Delete eggs at beginning of each run */
public static final boolean DELETE_EGGS = true;// 每次运行是否先删除保存的蛋
@ -40,7 +42,7 @@ public class Env extends JPanel {
public static final int ENV_HEIGHT = ENV_WIDTH; // 虚拟环境高度, 可调,通常取正方形
/** Frog's brain display width on screen, not important */
public static final int FROG_BRAIN_DISP_WIDTH = 300; // Frog的脑图在屏幕上的显示大小,可调
public static final int FROG_BRAIN_DISP_WIDTH = 400; // Frog的脑图在屏幕上的显示大小,可调
/** Steps of one test round */
public static final int STEPS_PER_ROUND = 2000;// 每轮测试步数,可调
@ -58,6 +60,10 @@ public class Env extends JPanel {
private static final boolean[][] foods = new boolean[ENV_WIDTH][ENV_HEIGHT];// 食物数组定义
private static final int TRAP_WIDTH = 350; // 陷阱高, 0~200
private static final int TRAP_HEIGHT = 10; // 陷阱宽, 0~200
public List<Frog> frogs = new ArrayList<>();
public List<Egg> eggs;
@ -86,8 +92,17 @@ public class Env extends JPanel {
return !(x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT) && Env.foods[x][y];
}
public static boolean foundFoodOrOutEdge(int x, int y) {// 如果指定点看到食物或超出边界
return x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT || Env.foods[x][y];
public static boolean closeToEdge(Frog f) {// 青蛙靠近边界? 离死不远了
return f.x < 20 || f.y < 20 || f.x > (Env.ENV_WIDTH - 20) || f.y > (Env.ENV_HEIGHT - 20);
}
public static boolean inTrap(int x, int y) {// 如果指定点看到食物
return x >= ENV_WIDTH / 2 - TRAP_WIDTH / 2 && x <= ENV_WIDTH / 2 + TRAP_WIDTH / 2
&& y >= ENV_HEIGHT / 2 - TRAP_HEIGHT / 2 && y <= ENV_HEIGHT / 2 + TRAP_HEIGHT / 2;
}
public static boolean foundAnyThing(int x, int y) {// 如果指定点看到食物或超出边界
return x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT || Env.foods[x][y] || inTrap(x, y);
}
public static boolean foundAndDeleteFood(int x, int y) {// 如果x,y有食物将其清0返回true
@ -131,6 +146,14 @@ public class Env extends JPanel {
}
}
private void drawTrap(Graphics g) {// 所有走到陷阱边沿上的的青蛙都死掉
g.fillRect(ENV_HEIGHT / 2 - TRAP_WIDTH / 2, ENV_HEIGHT / 2 - TRAP_HEIGHT / 2, TRAP_WIDTH, TRAP_HEIGHT);
g.setColor(Color.white);
g.fillRect(ENV_HEIGHT / 2 - TRAP_WIDTH / 2 + 3, ENV_HEIGHT / 2 - TRAP_HEIGHT / 2 + 3, TRAP_WIDTH - 6,
TRAP_HEIGHT - 6);
g.setColor(Color.black);
}
static final NumberFormat format100 = NumberFormat.getPercentInstance();
static {
format100.setMaximumFractionDigits(2);
@ -154,10 +177,6 @@ public class Env extends JPanel {
}
}
public static boolean closeToEdge(Frog f) {// 青蛙靠近边界? 离死不远了
return f.x < 20 || f.y < 20 || f.x > (Env.WIDTH - 20) || f.y > (Env.HEIGHT - 20);
}
public void run() throws InterruptedException {
EggTool.loadEggs(this); // 从磁盘加载egg或新建一批egg
int round = 1;
@ -183,6 +202,13 @@ public class Env extends JPanel {
if (frog.active(this))
allDead = false;
for (Frog frog : frogs)
if (frog.alive && RandomUtils.percent(0.2f)) {// 有很小的机率在青蛙活着时就创建新的器官
RandomConnectGroup newConGrp = new RandomConnectGroup();
newConGrp.initFrog(frog);
frog.organs.add(newConGrp);
}
if (SHOW_SPEED > 0 && i % SHOW_SPEED != 0) // 画青蛙会拖慢速度
continue;
@ -197,13 +223,16 @@ public class Env extends JPanel {
frog.show(g);
if (firstFrog.alive) { // 开始显示第一个Frog的动态脑图
g.setColor(Color.red);
g.drawArc(firstFrog.x - 15, firstFrog.y - 15, 30, 30, 0, 360);
g.setColor(Color.BLACK);
if (Application.SHOW_FIRST_FROG_BRAIN) {
g.setColor(Color.red);
g.drawArc(firstFrog.x - 15, firstFrog.y - 15, 30, 30, 0, 360);
g.setColor(Color.BLACK);
}
if (DRAW_BRAIN_AFTER_STEPS > 0 && i % DRAW_BRAIN_AFTER_STEPS == 0)
Application.brainPic.drawBrainPicture(firstFrog);
}
drawTrap(g);
drawFood(g);
Graphics g2 = this.getGraphics();
g2.drawImage(buffImg, 0, 0, this);
@ -213,7 +242,7 @@ public class Env extends JPanel {
EggTool.layEggs(this);
t2 = System.currentTimeMillis();
Application.mainFrame.setTitle("Frog test round: " + round++ + ", 找食效率:" + foodFoundPercent()
+ ", time used: " + (t2 - t1) + " ms, first frog x=" + firstFrog.x + ", y=" + firstFrog.y);
+ ", time used: " + (t2 - t1) + " ms");
} while (true);
}
}

@ -40,8 +40,9 @@ public class Frog {
public int x; // frog在Env中的x坐标
public int y; // frog在Env中的y坐标
public long energy = 1000000; // 青蛙的能量为0则死掉
public long energy = 100000; // 青蛙的能量为0则死掉
public boolean alive = true; // 设为false表示青蛙死掉了将不参与计算和显示以节省时间
public int ateFood = 0;
static Image frogImg;
static {
@ -62,19 +63,14 @@ public class Frog {
}
public boolean active(Env v) {
if (Env.outsideEnv(x, y))
alive = false;
energy -= 20;
if (!alive || energy < 0) {// 如果能量小于0则死
if (!alive || energy < 0 || Env.outsideEnv(x, y) || Env.inTrap(x, y)) {// 如果能量小于0则死
energy -= 100; // 死掉的青蛙也要消耗能量,保证淘汰出局
alive = false;
return false;
}
for (Organ o : organs) { // 调用每个Organ的active方法
// energy -= o.organWasteEnergy; // 器官不是越多越好,每增加一个器官,要多消耗一点能量,通过这个方法防止器官无限增多
energy -= 20;
for (Organ o : organs)
o.active(this);
}
return alive;
}

@ -26,6 +26,11 @@ import com.github.drinkjava2.frog.Frog;
public class BrainPicture extends JPanel {
private float brainWidth; // real brain width
private int brainDispWidth; // screen display width
private Color color = Color.BLACK;
public void setColor(Color c) {
color = c;
}
public BrainPicture(int x, int y, float brainWidth, int brainDispWidth) {
super();
@ -35,7 +40,8 @@ public class BrainPicture extends JPanel {
this.setBounds(x, y, brainDispWidth + 1, brainDispWidth + 1);
}
public void drawZone(Graphics g, Zone z) {
public void drawZone( Zone z) {Graphics g = this.getGraphics();
g.setColor(color);
float rate = brainDispWidth / brainWidth;
int x = Math.round(z.x * rate);
int y = Math.round(z.y * rate);
@ -43,14 +49,16 @@ public class BrainPicture extends JPanel {
g.drawRect(x - radius, y - radius, radius * 2, radius * 2);
}
public void drawCircle(Graphics g, Zone z) {
public void drawCircle( Zone z) {Graphics g = this.getGraphics();
g.setColor(color);
float rate = brainDispWidth / brainWidth;
int x = Math.round(z.x * rate);
int y = Math.round(z.y * rate);
g.drawArc(x - 5, y - 5, 10, 10, 0, 360);
}
public void fillZone(Graphics g, Zone z) {
public void fillZone( Zone z) {Graphics g = this.getGraphics();
g.setColor(color);
float rate = brainDispWidth / brainWidth;
int x = Math.round(z.x * rate);
int y = Math.round(z.y * rate);
@ -58,7 +66,9 @@ public class BrainPicture extends JPanel {
g.fillRect(x - radius, y - radius, radius * 2, radius * 2);
}
public void drawLine(Graphics g, Zone z1, Zone z2) {
public void drawLine(Zone z1, Zone z2) {
Graphics g = this.getGraphics();
g.setColor(color);
float rate = brainDispWidth / brainWidth;
int x1 = Math.round(z1.x * rate);
int y1 = Math.round(z1.y * rate);
@ -67,7 +77,8 @@ public class BrainPicture extends JPanel {
g.drawLine(x1, y1, x2, y2);
}
public void drawText(Graphics g, Zone z, String text) {
public void drawText( Zone z, String text) {Graphics g = this.getGraphics();
g.setColor(color);
float rate = brainDispWidth / brainWidth;
int x = Math.round(z.x * rate);
int y = Math.round(z.y * rate);
@ -113,4 +124,5 @@ public class BrainPicture extends JPanel {
for (Organ organ : frog.organs)
organ.drawOnBrainPicture(frog, this); // each organ draw itself
}
}

@ -11,8 +11,8 @@
package com.github.drinkjava2.frog.brain;
import java.awt.Color;
import java.awt.Graphics;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Frog;
/**
@ -27,7 +27,8 @@ 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 organWasteEnergy = 0.05f; //
// 器官在每个测试循环中需要消耗青蛙多少能量,可以通过调节这个参数抑制器官数量无限增长
public float organActiveEnergy = 1; // 输出器官激活需要消耗每个脑细胞多少能量
public float organOutputEnergy = 2; // 感觉器官激活会给每个脑细胞增加多少能量
public boolean initilized; // 通过这个标记判断是否需要手工给定它的参数初值
@ -64,11 +65,12 @@ public class Organ extends Zone {
/** Child class can override this method to drawing picture */
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法
Graphics g = pic.getGraphics();// border
g.setColor(Color.BLACK); // 缺省是黑色
pic.drawZone(g, this);
if (!Application.SHOW_FIRST_FROG_BRAIN)
return;
pic.setColor(Color.BLACK); // 缺省是黑色
pic.drawZone(this);
if (this.name != null)
pic.drawText(g, this, String.valueOf(this.name));
pic.drawText(this, String.valueOf(this.name));
}
/** Only call once when frog created , Child class can override this method */

@ -11,7 +11,6 @@
package com.github.drinkjava2.frog.brain.group;
import java.awt.Color;
import java.awt.Graphics;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
@ -49,7 +48,7 @@ public class RandomConnectGroup extends Group {
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
//organWasteEnergy=.05f;
// organWasteEnergy=.05f;
x = Env.FROG_BRAIN_WIDTH / 2;
y = Env.FROG_BRAIN_WIDTH / 2;
r = Env.FROG_BRAIN_WIDTH / 2;
@ -83,19 +82,18 @@ public class RandomConnectGroup extends Group {
}
@Override
public void drawOnBrainPicture(Frog f,BrainPicture pic) {// 把自已这个器官在脑图上显示出来
Graphics g = pic.getGraphics();// border
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (fat <= 0)
g.setColor(Color.LIGHT_GRAY); // 没用到? 灰色
pic.setColor(Color.LIGHT_GRAY); // 没用到? 灰色
else
g.setColor(Color.red); // 用到了?红色
pic.drawZone(g, this);
pic.drawLine(g, inputZone, outputZone);
pic.drawZone(g, inputZone);
pic.fillZone(g, outputZone);
pic.setColor(Color.red); // 用到了?红色
pic.drawLine(inputZone, outputZone);
pic.drawZone(this);
pic.drawZone(inputZone);
pic.fillZone(outputZone);
if (fat > 0) {
g.setColor(Color.red);
pic.drawCircle(g, outputZone); // 如果胖了,表示激活过了,下次下蛋少不了这一组
pic.setColor(Color.red);
pic.drawCircle(outputZone); // 如果胖了,表示激活过了,下次下蛋少不了这一组
}
}

@ -0,0 +1,47 @@
/*
* 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.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Active always keep active
*
*
*/
public class Active extends Organ {//以前的实验发现添加一个始终激活的区比用Hungry来驱动更能提高找食效率
private static final long serialVersionUID = 1L;
@Override
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
organOutputEnergy = 2;
}
}
@Override
public void active(Frog f) {
for (Cell cell : f.cells) {
if (cell.energy > 0)
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)
for (Input input : cell.inputs)
if (input.nearby(this)) // if input zone near by happy zone
cell.energy += organOutputEnergy;
}
}
}

@ -0,0 +1,62 @@
/*
* 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.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Chance is a random number generator
*
*
*/
public class Chance extends Organ { // 至于这个器官能不能被选中,是另外一回事,听天由命了
private static final long serialVersionUID = 1L;
public int percent; // 初始化的机率为5%
@Override
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
percent = 5;
}
}
@Override
public Organ[] vary() {
if (RandomUtils.percent(5)) {
percent = percent + 1 - 2 * RandomUtils.nextInt(2);
if (percent < 1)
percent = 1;
if (percent > 98)
percent = 98;
}
return new Organ[] { this };
}
@Override
public void active(Frog f) {
if (RandomUtils.percent(percent)) {// 如果靠近边界,痛苦信号生成
for (Cell cell : f.cells) {
if (cell.energy > 0)
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)
for (Input input : cell.inputs)
if (input.nearby(this)) // if input zone nearby this zone
cell.energy += 30;
}
}
}
}

@ -23,8 +23,9 @@ public class Eat extends Organ {// Eat这个类将食物转化为能量能量
@Override
public void active(Frog f) {
if (Env.foundAndDeleteFood(f.x, f.y)) {
f.ateFood++;
// 所有的硬编码都是bug包括这个1000
f.energy += 1000;// 如果青蛙的坐标与食物重合吃掉food能量境加
f.energy += 1000;// 如果青蛙的坐标与食物重合吃掉food能量境加
// 能量境加青蛙感觉不到但是Happy区激活青蛙能感觉到因为Happy区是一个脑器官

@ -10,6 +10,7 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.BrainPicture;
@ -17,27 +18,31 @@ import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.brain.Zone;
import com.github.drinkjava2.frog.util.RandomUtils;
/**
* Eye is an organ can see environment, and active brain cells which inputs are
* located in eye range
* Eye can only see 4 direction
*
* @author Yong Zhu
* @since 1.0
*/
public class Eye extends Organ {// Eye类需要重构目前只有4个感光细胞不够Eye要改成Group的子类Eye只负责感光细胞的排列感光细胞自已负责变异
public class Eye extends Organ {// 这个Eye是老版的眼睛只能看到四个方向但它的调节距离会自动随机调整到一个最佳值这就是随机试错算法的一个应用
private static final long serialVersionUID = 1L;
public int seeDistance; // 眼睛能看到的距离
@Override
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次
if (!initilized) {
initilized = true;
organOutputEnergy = 30;
seeDistance = 8;
}
}
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (!Application.SHOW_FIRST_FROG_BRAIN)
return;
super.drawOnBrainPicture(f, pic);
float qRadius = r / 4;
float q3Radius = (float) (r * .75);
@ -45,14 +50,21 @@ public class Eye extends Organ {// Eye类需要重构目前只有4个感光
Zone seeDown = new Zone(x, y - q3Radius, qRadius);
Zone seeLeft = new Zone(x - q3Radius, y, qRadius);
Zone seeRight = new Zone(x + q3Radius, y, qRadius);
pic.drawZone(pic.getGraphics(), seeUp);
pic.drawZone(pic.getGraphics(), seeDown);
pic.drawZone(pic.getGraphics(), seeLeft);
pic.drawZone(pic.getGraphics(), seeRight);
pic.drawZone(seeUp);
pic.drawZone(seeDown);
pic.drawZone(seeLeft);
pic.drawZone(seeRight);
}
@Override
public Organ[] vary() {
if (RandomUtils.percent(5)) {
seeDistance = seeDistance + 1 - 2 * RandomUtils.nextInt(2);
if (seeDistance < 1)
seeDistance = 1;
if (seeDistance > 50)
seeDistance = 50;
}
return new Organ[] { this };
}
@ -72,29 +84,28 @@ public class Eye extends Organ {// Eye类需要重构目前只有4个感光
boolean foodAtLeft = false;
boolean foodAtRight = false;
int seeDist = 10;
for (int i = 1; i < seeDist; i++)
for (int i = 1; i < seeDistance; i++)
if (Env.foundFood(f.x, f.y + i)) {
seeFood = true;
foodAtUp = true;
break;
}
for (int i = 1; i < seeDist; i++)
for (int i = 1; i < seeDistance; i++)
if (Env.foundFood(f.x, f.y - i)) {
seeFood = true;
foodAtDown = true;
break;
}
for (int i = 1; i < seeDist; i++)
for (int i = 1; i < seeDistance; i++)
if (Env.foundFood(f.x - i, f.y)) {
seeFood = true;
foodAtLeft = true;
break;
}
for (int i = 1; i < seeDist; i++)
for (int i = 1; i < seeDistance; i++)
if (Env.foundFood(f.x + i, f.y)) {
seeFood = true;
foodAtRight = true;

@ -10,7 +10,11 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import java.awt.Color;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.BrainPicture;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
@ -22,6 +26,23 @@ public class Happy extends Organ { // Happy器官是进食后的产生的快感
private static final long serialVersionUID = 1L;
public float happy = 0; // happy初始值为0, 进食后将由eat器官增加happy值
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (!Application.SHOW_FIRST_FROG_BRAIN)
return;
if (happy > 0) {
pic.setColor(Color.red);
pic.fillZone(this);
} else {
pic.setColor(Color.white);
pic.fillZone(this);
pic.setColor(Color.BLACK);
pic.drawZone(this);
}
if (this.name != null)
pic.drawText(this, String.valueOf(this.name));
}
@Override
public void active(Frog f) {
if (happy > 0) {

@ -10,7 +10,11 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import java.awt.Color;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.BrainPicture;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
@ -25,11 +29,27 @@ public class Hungry extends Organ {
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次缺省啥也不干通常用于Organ类的初始化
if (!initilized) {
initilized = true;
//organWasteEnergy = 20f;
// organWasteEnergy = 20f;
organOutputEnergy = 2;
}
}
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (!Application.SHOW_FIRST_FROG_BRAIN)
return;
if (f.energy < 10000) {
pic.fillZone(this);
} else {
pic.setColor(Color.white);
pic.fillZone(this);
pic.setColor(Color.BLACK);
pic.drawZone(this);
}
if (this.name != null)
pic.drawText(this, String.valueOf(this.name));
}
@Override
public Organ[] vary() {
// if (RandomUtils.percent(20)) // 有20机率权重变化

@ -10,6 +10,7 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.BrainPicture;
@ -26,9 +27,9 @@ import com.github.drinkjava2.frog.util.RandomUtils;
* @author Yong Zhu
* @since 1.0
*/
public class NewEye extends Organ {// 这个眼睛有nxn个感光细胞可以看到青蛙周围nxn网络内有没有食物
public class NewEye extends Organ {// 这个新版的眼睛有nxn个感光细胞可以看到青蛙周围nxn网络内有没有食物
private static final long serialVersionUID = 1L;
public int n = 3; // 眼睛有n x n个感光细胞缺省是3x3点阵,会随机自动变异(加1或减1最小是1)
public int n = 3; // 眼睛有n x n个感光细胞 用随机试错算法自动变异(加1或减1最小是3x3)
@Override
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次缺省啥也不干通常用于Organ类的初始化
@ -40,6 +41,8 @@ public class NewEye extends Organ {// 这个眼睛有nxn个感光细胞可以
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (!Application.SHOW_FIRST_FROG_BRAIN)
return;
super.drawOnBrainPicture(f, pic);
float r2 = r / n; // r2是每个感光细胞的半径
float x0 = x - r;
@ -47,10 +50,10 @@ public class NewEye extends Organ {// 这个眼睛有nxn个感光细胞可以
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
Zone cell = new Zone(x0 + i * 2 * r2 + r2, y0 + j * 2 * r2 + r2, r2);
if (Env.foundFoodOrOutEdge(f.x - n / 2 + i, f.y - n / 2 + j))
pic.fillZone(pic.getGraphics(), cell);
if (Env.foundAnyThing(f.x - n / 2 + i, f.y - n / 2 + j))
pic.fillZone(cell);
else
pic.drawZone(pic.getGraphics(), cell);
pic.drawZone(cell);
}
}
}
@ -74,7 +77,7 @@ public class NewEye extends Organ {// 这个眼睛有nxn个感光细胞可以
float y0 = y - r; // x0,y0是眼睛的左上角
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (Env.foundFoodOrOutEdge(f.x - n / 2 + i, f.y - n / 2 + j)) {
if (Env.foundAnyThing(f.x - n / 2 + i, f.y - n / 2 + j)) {
Zone eyeCell = new Zone(x0 + i * 2 * r2 + r2, y0 + j * 2 * r2 + r2, r2);
for (Cell cell : f.cells)
for (Input input : cell.inputs)

@ -10,14 +10,18 @@
*/
package com.github.drinkjava2.frog.brain.organ;
import java.awt.Color;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.BrainPicture;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Input;
import com.github.drinkjava2.frog.brain.Organ;
/**
* Pain zone active after some bad thingg happen like close to edge, hurt...
* Pain zone active after some bad thing happen like close to edge, hurt...
*
*
*/
@ -29,16 +33,25 @@ public class Pain extends Organ { // Pain器官目前激活的条件是离边境
public void initFrog(Frog f) {
if (!initilized) {
initilized = true;
organOutputEnergy = 2;
organOutputEnergy = 5;
}
}
// @Override
// public Organ[] vary() {
// if (RandomUtils.percent(20)) // 有20机率权重变化
// organOutputEnergy = RandomUtils.vary(organOutputEnergy);
// return new Organ[] { this };
// }
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (!Application.SHOW_FIRST_FROG_BRAIN)
return;
if (Env.closeToEdge(f)) {
pic.fillZone(this);
} else {
pic.setColor(Color.white);
pic.fillZone(this);
pic.setColor(Color.BLACK);
pic.drawZone(this);
}
if (this.name != null)
pic.drawText(this, String.valueOf(this.name));
}
@Override
public void active(Frog f) {
@ -48,7 +61,7 @@ public class Pain extends Organ { // Pain器官目前激活的条件是离边境
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)
for (Input input : cell.inputs)
if (input.nearby(this)) // if input zone near by happy zone
if (input.nearby(this)) // if input zone nearby this zone
cell.energy += organOutputEnergy;
}
}

@ -1,14 +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.egg;
public class CellGroup {
}

@ -17,7 +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.group.Group;
import com.github.drinkjava2.frog.brain.group.RandomConnectGroup;
import com.github.drinkjava2.frog.brain.organ.Active;
import com.github.drinkjava2.frog.brain.organ.Chance;
import com.github.drinkjava2.frog.brain.organ.Eat;
import com.github.drinkjava2.frog.brain.organ.Eye;
import com.github.drinkjava2.frog.brain.organ.Happy;
@ -41,9 +42,9 @@ import com.github.drinkjava2.frog.util.RandomUtils;
* @since 1.0
*/
public class Egg implements Serializable {
// 为了缩短时间,这个程序随机生成的联结将只落在固定的器官上而不是漫天撒网(见4.12提交),这是程序的优化,实现的逻辑和随机漫天撒网定是相同的。
// 但是这个优化带来的问题是这个硬编码逻辑不能拷贝到将来的分形结构里去,而且下面这个 FIXED_ORGAN_QTY必须每次手工设定
public static int FIXED_ORGAN_QTY = 9;
// 为了缩短时间,这个程序随机生成的联结将只落在固定的器官上而不是漫天撒网(见4.12提交),这是程序的优化,实现的逻辑和随机漫天撒网定是相同的。
// 但是这个优化带来的问题是这是一个硬编码逻辑,不利于器官的优胜劣汰, 而且下面这个 FIXED_ORGAN_QTY必须每次手工设定,以后需要重构这块的代码
public static int FIXED_ORGAN_QTY = 11;
private static final long serialVersionUID = 1L;
@ -53,20 +54,21 @@ public class Egg implements Serializable {
public Egg() {// 无中生有,创建一个蛋,先有蛋,后有蛙
organs.add(new Happy().setXYRN(600, 700, 60, "Happy")); // Happy必须第一个加入
organs.add(new Hungry().setXYRN(300, 100, 100, "Hungry"));
organs.add(new Hungry().setXYRN(300, 100, 60, "Hungry"));
organs.add(new MoveUp().setXYRN(800, 100, 60, "Up"));
organs.add(new MoveDown().setXYRN(800, 400, 60, "Down"));
organs.add(new MoveLeft().setXYRN(700, 250, 60, "Left"));
organs.add(new MoveRight().setXYRN(900, 250, 60, "Right"));
organs.add(new Eye().setXYRN(100, 300, 100, "Eye"));
organs.add(new NewEye().setXYRN(200, 700, 200, "NewEye"));
organs.add(new Pain().setXYRN(800, 700, 60, "Pain")); // 痛苦在靠近边界时触发
organs.add(new Pain().setXYRN(800, 700, 60, "Pain")); // 痛苦在靠近边界时触发
organs.add(new Active().setXYRN(500, 100, 60, "Active")); // 永远激活
organs.add(new Chance().setXYRN(650, 100, 60, "Chance")); // 永远激活
// Pain对提高找食效率没有帮助将来要和记忆功能一起加入,我们的目标:不出界,吃光所有食物
// 以上为11个, 就是FIXED_ORGAN_QTY值
organs.add(new Eat().setXYRN(0, 0, 0, "Eat")); // EAT不是感觉或输出器官没有位置和大小
addRandomConnectionGroups();
}
/** Create egg from frog */
@ -74,12 +76,6 @@ public class Egg implements Serializable {
for (Organ organ : frog.organs)
for (Organ newOrgan : organ.vary())
organs.add(newOrgan);
addRandomConnectionGroups();
}
private void addRandomConnectionGroups() {// 每次下蛋时新建5个RandomConnectGroup实例
for (int i = 0; i < 5; i++)
organs.add(new RandomConnectGroup());
}
/**

@ -24,6 +24,8 @@ 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;
import com.github.drinkjava2.frog.brain.organ.Chance;
import com.github.drinkjava2.frog.brain.organ.Eye;
import com.github.drinkjava2.frog.util.FrogFileUtils;
/**
@ -53,14 +55,14 @@ public class EggTool {
+ org.organActiveEnergy + ", outputEnergy=" + org.organOutputEnergy);
}
System.out.print("First frog has " + first.organs.size() + " organs, energy=" + first.energy);
System.out.print(", Last frog has " + last.organs.size() + " organs, energy=" + last.energy);
System.out.println("1st frog has " + first.organs.size() + " organs, energy=" + first.energy + ", seeDist="
+ ((Eye) first.organs.get(6)).seeDistance + ", chance=" + ((Chance) first.organs.get(10)).percent);
System.out.println("Last frog has " + last.organs.size() + " organs, energy=" + last.energy);
try {
List<Egg> newEggs = new ArrayList<>();
for (int i = 0; i < Env.EGG_QTY; i++)
newEggs.add(new Egg(env.frogs.get(i)));
System.out.print(", organs =" + newEggs.get(0).organs.size() + ", ");
FileOutputStream fo = new FileOutputStream(Application.CLASSPATH + "eggs.ser");
ObjectOutputStream so = new ObjectOutputStream(fo);
@ -68,8 +70,8 @@ public class EggTool {
so.close();
env.eggs = newEggs;
System.out.println(
", Saved " + env.eggs.size() + " eggs to file '" + Application.CLASSPATH + "eggs.ser" + "'");
System.out
.println("Saved " + env.eggs.size() + " eggs to file '" + Application.CLASSPATH + "eggs.ser" + "'");
} catch (IOException e) {
System.out.println(e);
}
@ -88,6 +90,24 @@ public class EggTool {
});
}
// private static void sortFrogsOrderByEnergyDesc(Env env) {//
// 按吃到食物数量、剩余能量多少给青蛙排序
// Collections.sort(env.frogs, new Comparator<Frog>() {
// public int compare(Frog a, Frog b) {
// if (a.ateFood > b.ateFood)
// return -1;
// else if (a.ateFood == b.ateFood) {
// // if (a.energy > b.energy)
// // return -1;
// // if (a.energy < b.energy)
// // return 1;
// return 0;
// } else
// return 1;
// }
// });
// }
public static void deleteEggs() {
System.out.println("Delete exist egg file: '" + Application.CLASSPATH + "eggs.ser'");
FrogFileUtils.deleteFile(Application.CLASSPATH + "eggs.ser");

@ -1,14 +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.env;
public class CellGroup {
}

@ -47,8 +47,8 @@ public class RandomUtils {
}
public static boolean percent(int percent) {
return rand.nextInt(100) < percent;
public static boolean percent(float percent) {
return rand.nextFloat() * 100 < percent;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

File diff suppressed because one or more lines are too long

@ -46,12 +46,14 @@
主要做了一些清理,将所有器官移到单独的类里删除OrganDesc类。将一些类(如Applicaton移到根包下)移到不同的包下。这个版本是比较大的一个重构,最大的进步是将算法当成一个器官引入,当然,这个版本只存在一个随机连接两端的算法,以后会扩充。
另外顺手加上了Happy和Pain两个器官分别对应进食愉快感和痛苦感后者在靠近边界时激发。观查它的表现果然不出所料痛苦感立即生效有一些Frog移动到边界后就不再前进而是顺着边界溜下去了不傻但是Happy器官没有生效这也很显然因为Happy属于进食反射链的一部分在没有记忆器官算法引入之前是没有途径使用上进食奖励信号的。
### 2019-06-13, Commit: Happy & Pain
主要做了一些清理,将所有器官移到单独的类里删除OrganDesc类。将一些类(如Applicaton移到根包下)移到不同的包下。这个版本是比较大的一个重构,最大的进步是将算法当成一个器官引入,当然,这个版本只存在一个随机连接两端的算法,以后会扩充。
另外顺手加上了Happy和Pain两个器官分别对应进食愉快感和痛苦感后者在靠近边界时激发。观查它的表现果然不出所料痛苦感立即生效有一些Frog移动到边界后就不再前进而是顺着边界溜下去了不傻但是Happy器官没有生效这也很显然因为Happy属于进食反射链的一部分在没有记忆器官算法引入之前是没有途径使用上进食奖励信号的。
### 2019-06-26, Commit: Back to many connections
找食效率太低又改回到4.12的用连接数量代替权值这个逻辑权值这种人为设计的算法居然比不过随机试错失败。先暂时去掉Pain器官Pain的加入并没有提高找食效率必须与感光细胞合用才能知道是哪个方向的边界下个版本急需引入记忆功能也就是说要将感光细胞的活跃和痛苦器官的活跃关联起来。
### 2019-06-28, Commit: New eye & dynamic show brain 为了更方便青蛙看到边界又加了个新的眼睛它是一个可自进化的nxn点阵的眼睛将来会取代只有四个象素点(但能看得远)的老眼睛。到目前为止,依然还没有进行模式识别和记忆功能的开发。另外脑图可以动态显示了,用一个红圈标记出被动态跟踪显示的青蛙。另外每次运行前打印往生咒,以示对生命的尊重。
### 2019-07-28, Commit: Trap & Active & Chance
这还是一个常规版本,建立在随机连接、优胜劣汰基础上。主要有以下改动:
1. 在Env区中间加了一个陷阱区Trap以增加趣味性青蛙如果走到陷阱区就死掉结果自然选择的结果是青蛙会绕开陷阱区。
2. 青蛙增加一个Active器官它的作用是一直保持激活如果有神经元触突位于这个区就会驱动神经元兴奋这个器官经实践证明比Hungry器官驱动更能提高找食效率。
3. 青蛙增加一个Chance器官,它的作用是引入随机扰动,打破青蛙有时候围着一个食物打转就是吃不着的死循环。
从当前这个版本可以看出,实际上青蛙是有一定的记忆能力的,连接就=记忆只不过没有模式识别能力以后的工作将以模式识别为重点基本原理是见note中提到的仿照全息存储原理在思维区逆向成像。因为逆向成像的限制以后的版本所有的器官会被移到脑图的同一侧不再是随意分布在脑图上了这将是一个比较明显的改动。当然随机连接这个算法看起来比较有用以后还是可能保留的。
Loading…
Cancel
Save