diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/Animal.java b/core/src/main/java/com/gitee/drinkjava2/frog/Animal.java index b8ac026..3059c0a 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/Animal.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/Animal.java @@ -71,11 +71,15 @@ public abstract class Animal {// 这个程序大量用到public变量而不是ge } } - public boolean active(Env v) {// 这个active方法在每一步循环都会被调用,是脑思考的最小帧 + public boolean active() {// 这个active方法在每一步循环都会被调用,是脑思考的最小帧 // 如果能量小于0、出界、与非食物的点重合则判死 - if (!alive || energy < 0 || Env.outsideEnv(x, y) || Env.bricks[x][y] >= Material.KILLFROG) { + if (!alive) { energy -= 1000; // 死掉的青蛙也要消耗能量,确保淘汰出局 - alive = false; + return false; + } + if (energy < 0 || Env.outsideEnv(x, y) || Env.bricks[x][y] >= Material.KILL_ANIMAL) { + energy -= 1000; + kill(); return false; } energy -= 20; @@ -89,7 +93,9 @@ public abstract class Animal {// 这个程序大量用到public变量而不是ge return alive; } - public abstract void show(Graphics g); + public abstract void show(Graphics g);// 显示青蛙或蛇,子类要重写这个方法 + + public abstract void kill();// 杀死青蛙或蛇,子类要重写这个方法 @SuppressWarnings("unchecked") public T findOrganByClass(Class claz) {// 根据器官名寻找器官,但不是每个器官都有名字 diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/Application.java b/core/src/main/java/com/gitee/drinkjava2/frog/Application.java index 179d6a2..e0dc1af 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/Application.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/Application.java @@ -50,7 +50,7 @@ public class Application { if (Env.FROG_BRAIN_DISP_WIDTH + 41 > y) y = Env.FROG_BRAIN_DISP_WIDTH + 41; mainFrame.setSize(Env.ENV_WIDTH + Env.FROG_BRAIN_DISP_WIDTH + 25, y); - brainPic.requestFocus(); + brainPic.requestFocus(); } else { button.setText("Show brain"); mainFrame.setSize(Env.ENV_WIDTH + 20, Env.ENV_HEIGHT + 120); @@ -69,18 +69,20 @@ public class Application { int buttonHeight = 22; int buttonXpos = Env.ENV_WIDTH / 2 - buttonWidth / 2; - // select frog or snake 显示青蛙或蛇的脑图 + // select frog or snake 显示青蛙或蛇的RadioButton JRadioButton radioFrog = new JRadioButton("Frog"); radioFrog.setBounds(buttonXpos + buttonWidth + 10, Env.ENV_HEIGHT + 8, 50, buttonHeight); - radioFrog.addActionListener(e -> selectFrog = radioFrog.isSelected()); + radioFrog.addActionListener(e -> { + selectFrog = radioFrog.isSelected(); + checkIfShowBrainPicture(button); + }); JRadioButton radioSnake = new JRadioButton("Snake"); button.setBounds(buttonXpos, Env.ENV_HEIGHT + 8, buttonWidth, buttonHeight); ActionListener al = new ActionListener() { @Override - public void actionPerformed(ActionEvent arg0) { + public void actionPerformed(ActionEvent arg0) {//显示或隐藏脑图 Env.SHOW_FIRST_ANIMAL_BRAIN = !Env.SHOW_FIRST_ANIMAL_BRAIN; - checkIfShowBrainPicture(button); if (Env.SHOW_FIRST_ANIMAL_BRAIN && Env.SNAKE_MODE) { radioFrog.setVisible(true); radioSnake.setVisible(true); @@ -88,15 +90,18 @@ public class Application { radioFrog.setVisible(false); radioSnake.setVisible(false); } + checkIfShowBrainPicture(button); } - }; checkIfShowBrainPicture(button); button.addActionListener(al); mainFrame.add(button); radioSnake.setBounds(buttonXpos + buttonWidth + 60, Env.ENV_HEIGHT + 8, 80, buttonHeight); - radioSnake.addActionListener(e -> selectFrog = radioFrog.isSelected()); + radioSnake.addActionListener(e -> { + selectFrog = radioFrog.isSelected(); + checkIfShowBrainPicture(button); + }); ButtonGroup btnGroup = new ButtonGroup(); btnGroup.add(radioFrog); btnGroup.add(radioSnake); @@ -104,7 +109,7 @@ public class Application { mainFrame.add(radioFrog); mainFrame.add(radioSnake); - JButton stopButton = new JButton("Pause");// 按钮,暂停或继续 + JButton stopButton = new JButton("Pause");// 暂停或继续按钮 stopButton.setBounds(buttonXpos, Env.ENV_HEIGHT + 35, buttonWidth, buttonHeight); pauseAction = new ActionListener() { @Override @@ -121,7 +126,8 @@ public class Application { stopButton.addActionListener(pauseAction); mainFrame.add(stopButton); - final JSlider speedSlider = new JSlider(1, 10, (int) Math.round(Math.sqrt(Env.SHOW_SPEED))); // 速度条 + // 速度条 + final JSlider speedSlider = new JSlider(1, 10, (int) Math.round(Math.sqrt(Env.SHOW_SPEED))); speedSlider.setBounds(buttonXpos - 50, stopButton.getY() + 25, buttonWidth + 100, buttonHeight); ChangeListener slideAction = new ChangeListener() { @Override @@ -136,6 +142,7 @@ public class Application { label.setBounds(buttonXpos - 90, stopButton.getY() + 23, 100, buttonHeight); mainFrame.add(label); + // 允许加入蛇进来 JCheckBox snakeModeCkBox = new JCheckBox("Snake Mode"); snakeModeCkBox.setBounds(buttonXpos, speedSlider.getY() + 25, 120, buttonHeight); snakeModeCkBox.addActionListener(e -> { diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/Env.java b/core/src/main/java/com/gitee/drinkjava2/frog/Env.java index bca502c..0adec4b 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/Env.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/Env.java @@ -9,6 +9,7 @@ import java.util.List; import javax.swing.JPanel; +import com.gitee.drinkjava2.frog.brain.BrainPicture; import com.gitee.drinkjava2.frog.egg.Egg; import com.gitee.drinkjava2.frog.egg.FrogEggTool; import com.gitee.drinkjava2.frog.egg.SnakeEggTool; @@ -28,7 +29,7 @@ public class Env extends JPanel { private static final long serialVersionUID = 1L; /** Speed of test */ - public static int SHOW_SPEED = 10; // 测试速度,-1000~1000,可调, 数值越小,速度越慢 + public static int SHOW_SPEED = 1; // 测试速度,-1000~1000,可调, 数值越小,速度越慢 /** Delete eggs at beginning of each run */ public static final boolean DELETE_FROG_EGGS = true;// 每次运行是否先删除保存的青蛙蛋 @@ -74,7 +75,7 @@ public class Env extends JPanel { public static final int SNAKE_EGG_QTY = 10; // 每轮下n个蛇蛋,可调,只有最优秀的前n个蛇们才允许下蛋 - public static final int SNAKE_PER_EGG = 4; // 每个蛇蛋可以孵出几个蛇 + public static final int SNAKE_PER_EGG = 2; // 每个蛇蛋可以孵出几个蛇 // 以下是程序内部变量,不要手工修改它们 public static final int TOTAL_FROG_QTY = FROG_EGG_QTY * FROG_PER_EGG; // 蛇的总数 @@ -148,13 +149,10 @@ public class Env extends JPanel { public static boolean foundFrogOrOutEdge(int x, int y) {// 如果指定点看到青蛙或超出边界,返回true if (x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT) return true;// 如果出界返回true - int frogNo = Env.bricks[x][y] & Material.FROG_TAG; - if (frogNo > 0) { - Frog f = frogs.get(frogNo - 1); - if (f.alive) - return true; - } - return false; + if ((Env.bricks[x][y] & Material.FROG_TAG) > 0) + return true; + else + return false; } public static boolean foundAndAteFrog(int x, int y) {// 如果x,y有青蛙,将其杀死,返回true @@ -165,7 +163,7 @@ public class Env extends JPanel { Frog f = frogs.get(frogNo - 1); if (f.alive) { Env.frog_ated++; - f.alive = false; + f.kill(); return true; } } @@ -213,7 +211,8 @@ public class Env extends JPanel { } for (int j = 0; j < loop; j++) { Egg zygote = new Egg(snake_eggs.get(i), snake_eggs.get(RandomUtils.nextInt(snake_eggs.size()))); - snakes.add(new Snake(RandomUtils.nextInt(ENV_WIDTH), RandomUtils.nextInt(ENV_HEIGHT), zygote)); + Snake s = new Snake(RandomUtils.nextInt(ENV_WIDTH), RandomUtils.nextInt(ENV_HEIGHT), zygote); + snakes.add(s); } } } @@ -253,13 +252,11 @@ public class Env extends JPanel { return new StringBuilder("吃蛙率:").append(format100.format(Env.frog_ated * 1.00 / TOTAL_FROG_QTY)).toString(); } - public static void checkIfPause(Animal a) { + public static void checkIfPause() { if (pause) do { - if (a != null) { - Application.brainPic.drawBrainPicture(a); - Application.brainPic.requestFocus(); - } + Application.brainPic.drawBrainPicture(); + Application.brainPic.requestFocus(); sleep(100); } while (pause); } @@ -272,6 +269,11 @@ public class Env extends JPanel { } } + public static Animal getShowAnimal() { + return Application.selectFrog ? frogs.get(current_screen * FROG_PER_SCREEN) + : snakes.get(current_screen * SNAKE_PER_SCREEN); + } + public void run() { FrogEggTool.loadFrogEggs(); // 从磁盘加载蛙egg,或新建一批egg if (SNAKE_MODE) @@ -291,22 +293,19 @@ public class Env extends JPanel { for (EnvObject thing : things) // 创建食物、陷阱等物体 thing.build(); boolean allDead = false; - Frog firstFrog = frogs.get(current_screen * FROG_PER_SCREEN); - Snake firstSnake = null; for (int j = 0; j < FROG_PER_SCREEN; j++) { Frog f = frogs.get(current_screen * FROG_PER_SCREEN + j); f.initAnimal(); // 初始化器官延迟到这一步,是因为脑细胞太占内存,而且当前屏测完后会清空 } if (SNAKE_MODE && !snakes.isEmpty()) { - firstSnake = snakes.get(current_screen * SNAKE_PER_SCREEN); for (int j = 0; j < SNAKE_PER_SCREEN; j++) { Snake s = snakes.get(current_screen * SNAKE_PER_SCREEN + j); s.initAnimal(); // 初始化器官延迟到这一步,是因为脑细胞太占内存,而且当前屏测完后会清空 Snake.setEnvSnakeMaterial(s); // 出现时就要设定蛇的材料在环境里,暂时用一条线代替 } } - Animal showFrog = Application.selectFrog ? firstFrog : firstSnake; + for (step = 0; step < STEPS_PER_ROUND; step++) { for (EnvObject thing : things)// 调用食物、陷阱等物体的动作 thing.active(); @@ -315,13 +314,13 @@ public class Env extends JPanel { allDead = true; for (int j = 0; j < FROG_PER_SCREEN; j++) { Frog f = frogs.get(current_screen * FROG_PER_SCREEN + j); - if (f.active(this))// 调用青蛙的Active方法,并返回是否还活着 + if (f.active())// 调用青蛙的Active方法,并返回是否还活着 allDead = false; } if (SNAKE_MODE && !snakes.isEmpty()) for (int j = 0; j < SNAKE_PER_SCREEN; j++) { Snake s = snakes.get(current_screen * SNAKE_PER_SCREEN + j); - s.active(this);// snake唯一作用就是吃小蛇 + s.active();// snake唯一作用就是吃小蛇 } if (SHOW_SPEED > 0 && step % SHOW_SPEED != 0) // 用是否跳帧画图的方式来控制速度 @@ -345,20 +344,23 @@ public class Env extends JPanel { s.show(g); } - if (SHOW_FIRST_ANIMAL_BRAIN && showFrog != null) { - g.setColor(Color.red); - g.drawArc(showFrog.x - 15, showFrog.y - 15, 30, 30, 0, 360); - g.setColor(Color.BLACK); + if (SHOW_FIRST_ANIMAL_BRAIN) {// 在showAnimal上画一个红圈 + Animal showAnimal = getShowAnimal(); + if (showAnimal != null) { + g.setColor(Color.red); + g.drawArc(showAnimal.x - 15, showAnimal.y - 15, 30, 30, 0, 360); + g.setColor(Color.BLACK); + } } if (DRAW_BRAIN_AFTER_STEPS > 0 && step % DRAW_BRAIN_AFTER_STEPS == 0) - Application.brainPic.drawBrainPicture(showFrog); + Application.brainPic.drawBrainPicture(); Graphics g2 = this.getGraphics(); g2.drawImage(buffImg, 0, 0, this); } // System.out.println(showFrog.debugInfo());// 打印输出Frog调试内容 if (SHOW_FIRST_ANIMAL_BRAIN) - Application.brainPic.drawBrainPicture(showFrog); - checkIfPause(firstFrog); + Application.brainPic.drawBrainPicture(); + checkIfPause(); for (int j = 0; j < FROG_PER_SCREEN; j++) { Frog f = frogs.get(current_screen * FROG_PER_SCREEN + j); f.cells = null; // 清空frog脑细胞所占用的内存 diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/Frog.java b/core/src/main/java/com/gitee/drinkjava2/frog/Frog.java index 9fe5593..2189ec7 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/Frog.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/Frog.java @@ -16,6 +16,7 @@ import java.io.FileInputStream; import javax.imageio.ImageIO; import com.gitee.drinkjava2.frog.egg.Egg; +import com.gitee.drinkjava2.frog.objects.Material; /** * Snake has similar brain like Frog, snake eat frog
@@ -34,6 +35,12 @@ public class Frog extends Animal { } } + @Override + public void kill() {// 杀死蛙 + this.alive = false; + Env.clearMaterial(x, y, Material.FROG_TAG); + } + @Override public void show(Graphics g) {// 显示蛇的图象 if (!alive) diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/Snake.java b/core/src/main/java/com/gitee/drinkjava2/frog/Snake.java index 48ef5b9..5e6b823 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/Snake.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/Snake.java @@ -35,6 +35,12 @@ public class Snake extends Animal { } } + @Override + public void kill() {// 杀死蛇 + this.alive = false; + Env.clearMaterial(x, y, Material.SNAKE); + } + @Override public void show(Graphics g) {// 显示蛇的图象 if (!alive) @@ -43,12 +49,16 @@ public class Snake extends Animal { } public static void clearEnvSnakeMaterial(Animal snake) {// 这个方法清除Env中代表蛇的图像对应int的位 - for (int i = -5; i < 6; i++) + for (int i = 0; i <= 5; i++) { Env.clearMaterial(snake.x + i, snake.y - i, Material.SNAKE); + Env.clearMaterial(snake.x + i, snake.y + i, Material.SNAKE); + } } public static void setEnvSnakeMaterial(Animal snake) {// 这个方法清除Env中代表蛇的图像对应int的位 - for (int i = -5; i < 6; i++) + for (int i = 0; i <= 5; i++) { Env.setMaterial(snake.x + i, snake.y - i, Material.SNAKE); + Env.setMaterial(snake.x + i, snake.y + i, Material.SNAKE); + } } } diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/brain/BrainPicture.java b/core/src/main/java/com/gitee/drinkjava2/frog/brain/BrainPicture.java index ba8b185..2230737 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/brain/BrainPicture.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/brain/BrainPicture.java @@ -254,8 +254,9 @@ public class BrainPicture extends JPanel { y1 = y; g.setColor(picColor); - g.fillOval(round((float) x1 + Env.FROG_BRAIN_DISP_WIDTH / 2 + xOffset-r*scale*.5f), - round((float) y1 + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset-r*scale*.5f), round(r*scale), round(r*scale)); + g.fillOval(round((float) x1 + Env.FROG_BRAIN_DISP_WIDTH / 2 + xOffset - r * scale * .5f), + round((float) y1 + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset - r * scale * .5f), round(r * scale), + round(r * scale)); } public void drawText(float px1, float py1, float pz1, String text) { @@ -294,8 +295,11 @@ public class BrainPicture extends JPanel { private static Cuboid brain = new Cuboid(0, 0, 0, Env.FROG_BRAIN_XSIZE, Env.FROG_BRAIN_YSIZE, Env.FROG_BRAIN_ZSIZE); - public void drawBrainPicture(Animal a) {// 在这个方法里进行动物的三维脑结构的绘制,蛇是青蛙的子类,所以也可以当参数传进来 - if (!Env.SHOW_FIRST_ANIMAL_BRAIN || a == null || !a.alive) + public void drawBrainPicture() {// 在这个方法里进行动物的三维脑结构的绘制,蛇是青蛙的子类,所以也可以当参数传进来 + if (!Env.SHOW_FIRST_ANIMAL_BRAIN) + return; + Animal a = Env.getShowAnimal(); // 显示第一个青蛙或蛇 + if (a == null || !a.alive) return; g.setColor(WHITE);// 先清空旧图 g.fillRect(0, 0, brainDispWidth, brainDispWidth); diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/egg/FrogEggTool.java b/core/src/main/java/com/gitee/drinkjava2/frog/egg/FrogEggTool.java index 18e269a..594d256 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/egg/FrogEggTool.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/egg/FrogEggTool.java @@ -108,7 +108,7 @@ public class FrogEggTool { float r = 40; float h = 3; egg.organs.add(new FrogMouth().setXYZRHN(0, 0, 0, 0, h, "Eat")); // Mouth不是感觉或输出器官,没有位置和大小 - egg.organs.add(new FrogBigEye().setXYZRHN(190, 90, 500, r * 2, h, "BigEye"));// 大眼睛,永远加在第一位 + egg.organs.add(new FrogBigEye().setXYZRHN(190, 90, 500, r * 2, h, "FrogBigEye"));// 大眼睛,永远加在第一位 egg.organs.add(new Active().setXYZRHN(500, 600, 500, r, h, "Active")); // 永远激活 egg.organs.add(new FrogMoves.MoveUp().setXYZRHN(800, 300, 500, r, h, "Up")); egg.organs.add(new FrogMoves.MoveDown().setXYZRHN(800, 600, 500, r, h, "Down")); diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/egg/SnakeEggTool.java b/core/src/main/java/com/gitee/drinkjava2/frog/egg/SnakeEggTool.java index 80cfa9c..4e53154 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/egg/SnakeEggTool.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/egg/SnakeEggTool.java @@ -23,7 +23,7 @@ import com.gitee.drinkjava2.frog.Application; import com.gitee.drinkjava2.frog.Env; import com.gitee.drinkjava2.frog.Snake; import com.gitee.drinkjava2.frog.organ.Active; -import com.gitee.drinkjava2.frog.organ.frog.FrogBigEye; +import com.gitee.drinkjava2.frog.organ.snake.SnakeBigEye; import com.gitee.drinkjava2.frog.organ.snake.SnakeEyes; import com.gitee.drinkjava2.frog.organ.snake.SnakeMouth; import com.gitee.drinkjava2.frog.organ.snake.SnakeMoves; @@ -108,7 +108,7 @@ public class SnakeEggTool { float r = 30; float h = 3; egg.organs.add(new SnakeMouth().setXYZRHN(0, 0, 0, 0, h, "Eat")); // SnakeMouth不是感觉或输出器官,没有位置和大小 - egg.organs.add(new FrogBigEye().setXYZRHN(190, 90, 500, r * 2, h, "BigEye"));// 大眼睛,永远加在第1位 + egg.organs.add(new SnakeBigEye().setXYZRHN(190, 90, 500, r * 2, h, "SnakeBigEye"));// 大眼睛,永远加在第1位 egg.organs.add(new Active().setXYZRHN(500, 600, 500, r, h, "Active")); // 永远激活 egg.organs.add(new SnakeMoves.MoveUp().setXYZRHN(800, 300, 500, r, h, "Up")); egg.organs.add(new SnakeMoves.MoveDown().setXYZRHN(800, 600, 500, r, h, "Down")); diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/objects/Material.java b/core/src/main/java/com/gitee/drinkjava2/frog/objects/Material.java index 798d525..c26197f 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/objects/Material.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/objects/Material.java @@ -41,7 +41,7 @@ public class Material {// NOSONAR public static final int ANY_FOOD = FOOD + FLY1 + FLY2 + FLY3 + FLY4;// ANY_FOOD是几种FOOD的位叠加 public static final int SNAKE = nextLeftShift(); // 蛇的图形 - public static final int KILLFROG = nextLeftShift(); // if>=KILLFROG will kill frog + public static final int KILL_ANIMAL = nextLeftShift(); // if>=KILLFROG will kill animal public static final int BRICK = nextLeftShift();// brick will kill frog public static final int TRAP = nextLeftShift(); // trap will kill frog diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/organ/frog/FrogEyes.java b/core/src/main/java/com/gitee/drinkjava2/frog/organ/frog/FrogEyes.java index 7a90734..78b865a 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/organ/frog/FrogEyes.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/organ/frog/FrogEyes.java @@ -10,8 +10,11 @@ */ package com.gitee.drinkjava2.frog.organ.frog; +import java.awt.Color; + import com.gitee.drinkjava2.frog.Animal; import com.gitee.drinkjava2.frog.Env; +import com.gitee.drinkjava2.frog.brain.BrainPicture; import com.gitee.drinkjava2.frog.brain.Organ; import com.gitee.drinkjava2.frog.util.RandomUtils; @@ -26,6 +29,7 @@ public class FrogEyes { public static class SeeUp extends Organ {// 只能看到上方食物 private static final long serialVersionUID = 1L; public int seeDistance; // 眼睛能看到的距离 + public transient boolean seeSomeThing = false; @Override public void initOrgan(Animal a) { // 仅在生成时这个方法会调用一次 @@ -48,13 +52,28 @@ public class FrogEyes { return new Organ[] { this }; } + @Override + public void drawOnBrainPicture(Animal a, BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法 + if (!Env.SHOW_FIRST_ANIMAL_BRAIN) + return; + if (seeSomeThing) + pic.setPicColor(Color.RED); // 缺省是黑色 + else + pic.setPicColor(Color.BLACK); // 缺省是黑色 + pic.drawZone(this); + if (this.name != null) + pic.drawText(x, y, z, String.valueOf(this.name)); + } + @Override public void active(Animal a) { for (int i = 1; i < seeDistance; i++) if (Env.foundAnyThingOrOutEdge(a.x, a.y + i)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } @@ -66,8 +85,10 @@ public class FrogEyes { for (int i = 1; i < seeDistance; i++) if (Env.foundAnyThingOrOutEdge(a.x, a.y - i)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } @@ -79,8 +100,10 @@ public class FrogEyes { for (int i = 1; i < seeDistance; i++) if (Env.foundAnyThingOrOutEdge(a.x - i, a.y)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } @@ -92,8 +115,10 @@ public class FrogEyes { for (int i = 1; i < seeDistance; i++) if (Env.foundAnyThingOrOutEdge(a.x + i, a.y)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeBigEye.java b/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeBigEye.java index deeef0d..2c51974 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeBigEye.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeBigEye.java @@ -34,7 +34,6 @@ public class SnakeBigEye extends FrogBigEye {// 这个新版的眼睛有nxn个 public void drawOnBrainPicture(Animal a, BrainPicture pic) {// 把自已这个器官在脑图上显示出来 if (!Env.SHOW_FIRST_ANIMAL_BRAIN) return; - super.drawOnBrainPicture(a, pic); float r2 = r / n; // r2是每个感光细胞的半径 float x0 = x - r; float y0 = y - r; // x0,y0是眼睛的左上角 diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeEyes.java b/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeEyes.java index 4946718..cb4c8a7 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeEyes.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/organ/snake/SnakeEyes.java @@ -10,10 +10,9 @@ */ package com.gitee.drinkjava2.frog.organ.snake; -import com.gitee.drinkjava2.frog.Env; import com.gitee.drinkjava2.frog.Animal; -import com.gitee.drinkjava2.frog.brain.Organ; -import com.gitee.drinkjava2.frog.util.RandomUtils; +import com.gitee.drinkjava2.frog.Env; +import com.gitee.drinkjava2.frog.organ.frog.FrogEyes; /** * SnakeEyes can only see 4 direction's frog @@ -25,9 +24,8 @@ import com.gitee.drinkjava2.frog.util.RandomUtils; */ public class SnakeEyes { - public static class SeeUp extends Organ {// 只能看到上方青蛙 + public static class SeeUp extends FrogEyes.SeeUp {// 只能看到上方青蛙 private static final long serialVersionUID = 1L; - public int seeDistance; // 眼睛能看到的距离 @Override public void initOrgan(Animal a) { // 仅在Snake生成时这个方法会调用一次 @@ -37,26 +35,15 @@ public class SnakeEyes { } } - @Override - public Organ[] vary() { - seeDistance = RandomUtils.varyInLimit(seeDistance, 5, 20); - if (RandomUtils.percent(5)) { // 可视距离有5%的机率变异 - seeDistance = seeDistance + 1 - 2 * RandomUtils.nextInt(2); - if (seeDistance < 1) - seeDistance = 1; - if (seeDistance > 50) - seeDistance = 50; - } - return new Organ[] { this }; - } - @Override public void active(Animal a) { for (int i = 1; i < seeDistance; i++) if (Env.foundFrogOrOutEdge(a.x, a.y + i)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } @@ -68,8 +55,10 @@ public class SnakeEyes { for (int i = 1; i < seeDistance; i++) if (Env.foundFrogOrOutEdge(a.x, a.y - i)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } @@ -81,8 +70,10 @@ public class SnakeEyes { for (int i = 1; i < seeDistance; i++) if (Env.foundFrogOrOutEdge(a.x - i, a.y)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } @@ -94,8 +85,10 @@ public class SnakeEyes { for (int i = 1; i < seeDistance; i++) if (Env.foundFrogOrOutEdge(a.x + i, a.y)) { activeInput(a, 30); + seeSomeThing = true; return; } + seeSomeThing = false; } } diff --git a/core/src/main/java/com/gitee/drinkjava2/frog/util/RandomUtils.java b/core/src/main/java/com/gitee/drinkjava2/frog/util/RandomUtils.java index 987e97c..6899c4e 100644 --- a/core/src/main/java/com/gitee/drinkjava2/frog/util/RandomUtils.java +++ b/core/src/main/java/com/gitee/drinkjava2/frog/util/RandomUtils.java @@ -54,14 +54,11 @@ public class RandomUtils { throw new IllegalArgumentException("Can not call randomPosInRandomOrgan method when has no organ"); Organ o = null; if (percent(10)) {// 增加选中大眼睛的机率,因为里面感光细胞多 - for (Organ og : a.organs) { - if (og instanceof FrogBigEye) { - o = og; - break; - } - } + Organ og = a.organs.get(1);// 第1个通常设定为大眼睛 + if (og instanceof FrogBigEye) // 如果是蛙或蛇眼 + o = og; } - if (o == null) + if (o == null)// 有时候大眼晴没被程序员加进来,这时o为null o = a.organs.get(1 + RandomUtils.nextInt(a.organs.size() - 1)); // 跳过第一个器官 if (o instanceof Line) { return randomZoneInZone(((Line) o).bodyZone); diff --git a/版本提交记录.md b/版本提交记录.md index 9dde541..3c5c206 100644 --- a/版本提交记录.md +++ b/版本提交记录.md @@ -186,7 +186,7 @@ git reset --hard ae34b07e 可以转回到2019-08-04提交的分组测试的找 T:顶视 F:前视 L:左视 R:右视 X:斜视 方向键:剖视 空格:暂停 鼠标操作:缩放旋转平移 ### 2019-11-26 commit: Chinese test -这次更新用汉字"对酒当歌人生几何"来测试模式识别,优化了一下程序,目前这个图像识别基本没有容错性,图像像素多的会干拢像素少的文字的识别。下面考虑拉大听力信号间隔,以及引入侧抑制等机制(如果一个洞中砸进了光子,但是却和这个洞不同向,有可能产生负值的反向光子,这个负值与角度差有关),这和算法上的侧抑制很象,世界上的道理都是相通的。以后算法上的卷积、深度学习等现成的成果,也可以考虑融入进来,用图形化表示。反过来说,目前以算法进行的神经网络研究,如果借签这个项目的基本思路,把输入输出器官和适应环境进化做为重点,采用遗传淘汰的方式调整算法架构本身,尽量减少人为的设计,最后达到的行为表现可能和这个人工生命项目是一致的。我走图形化是没办法,因为基础差,但是精通算法的人如果明白我的意思,也可能很快做出表现比较复杂的人工生命来,毕竟算法研究已经到了很高的水平了,是现成的。 +这次更新用汉字"对酒当歌人生几何"来测试模式识别,优化了一下程序,目前这个图像识别基本没有容错性,图像像素多的会干拢像素少的文字的识别。下面考虑拉大听力信号间隔,以及引入侧抑制等机制(如果一个洞中砸进了光子,但是却和这个洞不同向,有可能产生负值的反向光子,这个负值与角度差有关),这和算法上的侧抑制很象,世界上的道理都是相通的。以后算法上的卷积、深度学习等现成的成果,也可以考虑融入进来,用图形化表示。反过来说,目前以算法进行的神经网络研究,如果借签这个项目的基本思路,把输入输出器官和适应环境进化做为重点,采用遗传淘汰的方式调整算法架构本身,尽量减少人为的设计,最后达到的行为表现可能和这个人工生命项目是一致的。我走图形化是没办法,因为基础差,但是精通算法的人如果明白我的意思,也可能很快做出表现比较复杂的人工生命来,毕竟算法研究已经到了很高的水平了,是现成的。 ### 2019-12-05 commit: add history folder 重整理了一下目录,将当前工作版本放在core目录下, 比较重大的历史版本放在history目录下,以方便初学者直接运行各个历史版本,而不需要使用git reset命令去手工回到以前的历史版本。同时,如果有未完成的子功能研究(如模式识别,见005_letter_test目录),也可以开一个子目录在history里,以后有时间再去慢慢研究这个子功能。 @@ -197,4 +197,6 @@ T:顶视 F:前视 L:左视 R:右视 X:斜视 方向键:剖视 空格: 基本思路是小蛇是有形状的,青蛙要能进化到看到小蛇就跑开,这样就开始正式引入了模式识别 ### 2020-06-19 正式完成加入小蛇进来,有多处bug改进 -蛇只能看到青蛙,青蛙只能看到蛇的图形。并改core目录下项目包名从github到gitee(码云),负值连线、中间连线引入,用一条斜线来暂时代替蛇的图形,好开始模式识别。 \ No newline at end of file +蛇只能看到青蛙,青蛙只能看到蛇的图形。并改core目录下项目包名从github到gitee(码云),负值连线、中间连线引入,用一条斜线来暂时代替蛇的图形,好开始模式识别。 + +### 2020-06-20 更正SnakeBigEye的bug,并显示为两条线代表蛙的图像(或舌头),便于简化模式别。 \ No newline at end of file