Add snake done!

master
Yong Zhu 5 years ago
parent 4ecfe95db2
commit 4b65e66e2d

@ -1,3 +1,3 @@
call mvn clean compile
cd target\classes
java -classpath ".;*" com.github.drinkjava2.frog.Application
java -classpath ".;*" com.gitee.drinkjava2.frog.Application

@ -8,75 +8,65 @@
* 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;
package com.gitee.drinkjava2.frog;
import java.awt.Graphics;
import java.awt.Image;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.brain.organ.Line;
import com.github.drinkjava2.frog.egg.Egg;
import com.github.drinkjava2.frog.objects.Material;
import com.github.drinkjava2.frog.util.RandomUtils;
import com.gitee.drinkjava2.frog.brain.Cell;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.egg.Egg;
import com.gitee.drinkjava2.frog.objects.Material;
import com.gitee.drinkjava2.frog.organ.Line;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Frog = cells <br/>
* Animal = cells <br/>
* cells = actions + photons <br/>
*
* Frog's name is Sam.
* Animal's name is Sam.
*
* cellscell
* cellscell
*
* @author Yong Zhu
*
* @since 1.0
*/
public class Frog {// 这个程序大量用到public变量而不是getter/setter主要是为了编程方便和简洁但缺点是编程者需要小心维护各个变量
public abstract class Animal {// 这个程序大量用到public变量而不是getter/setter主要是为了编程方便和简洁但缺点是编程者需要小心维护各个变量
/** brain cells */
public List<Cell> cells = new ArrayList<>();
/** organs */
public List<Organ> organs = new ArrayList<>();
public int x; // frog在Env中的x坐标
public int y; // frog在Env中的y坐标
public int x; // animal在Env中的x坐标
public int y; // animal在Env中的y坐标
public long energy = 100000; // 青蛙的能量为0则死掉
public boolean alive = true; // 设为false表示青蛙死掉了将不参与计算和显示以节省时间
public int ateFood = 0; // 青蛙曾吃过的食物总数,下蛋时如果两个青蛙能量相等,可以比数量
public int no; // 青蛙在Env.frogs中的序号从1开始 会在运行期写到当前brick的最低位可利用Env.frogs.get(no-1)快速定位青蛙
public int no; // 青蛙在Env.animals中的序号从1开始 会在运行期写到当前brick的最低位可利用Env.animals.get(no-1)快速定位青蛙
static Image frogImg;
static {
try {
frogImg = ImageIO.read(new FileInputStream(Application.CLASSPATH + "frog.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
public Image animalImage;
public Frog(int x, int y, Egg egg) {// x, y 是虑拟环境的坐标
public Animal(int x, int y, Egg egg) {// x, y 是虑拟环境的坐标
this.x = x;
this.y = y;
for (Organ org : egg.organs)
organs.add(org);
}
public void initFrog() { // 初始化frog,通常只是调用每个organ的init方法
public void initAnimal() { // 初始化animal,通常只是调用每个organ的init方法
for (Organ org : organs)
org.initFrog(this);// 每个新器官初始化如果是Group类它们会生成许多脑细胞
org.initOrgan(this);// 每个新器官初始化如果是Group类它们会生成许多脑细胞
}
public void addRandomLines() {// 有一定机率在器官间生成随机的神经连线
if (alive && RandomUtils.percent(0.2f)) {// 有很小的机率在青蛙活着时就创建新的器官
Line line = new Line();
line.initilized = false;
line.initFrog(this);
line.initOrgan(this);
organs.add(line);
}
}
@ -99,11 +89,7 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
return alive;
}
public void show(Graphics g) {// 显示青蛙的图象
if (!alive)
return;
g.drawImage(frogImg, x - 8, y - 8, 16, 16, null);
}
public abstract void show(Graphics g);
@SuppressWarnings("unchecked")
public <T extends Organ> T findOrganByClass(Class<?> claz) {// 根据器官名寻找器官,但不是每个器官都有名字
@ -113,14 +99,14 @@ public class Frog {// 这个程序大量用到public变量而不是getter/setter
return null;
}
/** Check if x,y,z out of frog's brain range */
public static boolean outBrainRange(int x, int y, int z) {// 检查指定坐标是否超出frog脑空间界限
/** Check if x,y,z out of animal's brain range */
public static boolean outBrainRange(int x, int y, int z) {// 检查指定坐标是否超出animal脑空间界限
return x < 0 || x >= Env.FROG_BRAIN_XSIZE || y < 0 || y >= Env.FROG_BRAIN_YSIZE || z < 0
|| z >= Env.FROG_BRAIN_ZSIZE;
}
/** Print debug info */
public String debugInfo() {// 输出Frog调试内容
public String debugInfo() {// 输出Animal调试内容
StringBuilder sb = new StringBuilder();
for (int i = 0; i < organs.size(); i++) {
Organ o = organs.get(i);

@ -1,4 +1,4 @@
package com.github.drinkjava2.frog;
package com.gitee.drinkjava2.frog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -14,7 +14,7 @@ import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.github.drinkjava2.frog.brain.BrainPicture;
import com.gitee.drinkjava2.frog.brain.BrainPicture;
/**
* Application's main method start the program
@ -22,6 +22,7 @@ import com.github.drinkjava2.frog.brain.BrainPicture;
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class Application {
public static final String CLASSPATH;
@ -42,8 +43,8 @@ public class Application {
public static ActionListener pauseAction;
public static boolean selectFrog = true;
static private void checkIfShowBrainPicture(JButton button) {
if (Env.SHOW_FIRST_FROG_BRAIN) {
private static void checkIfShowBrainPicture(JButton button) {
if (Env.SHOW_FIRST_ANIMAL_BRAIN) {
button.setText("Hide brain");
int y = Env.ENV_HEIGHT + 120;
if (Env.FROG_BRAIN_DISP_WIDTH + 41 > y)
@ -56,7 +57,7 @@ public class Application {
}
}
public static void main(String[] args) throws InterruptedException {
public static void main(String[] args) {
mainFrame.setLayout(null);
mainFrame.setSize(Env.ENV_WIDTH + 20, Env.ENV_HEIGHT + 100); // 窗口大小
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭时退出程序
@ -78,9 +79,9 @@ public class Application {
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Env.SHOW_FIRST_FROG_BRAIN = !Env.SHOW_FIRST_FROG_BRAIN;
Env.SHOW_FIRST_ANIMAL_BRAIN = !Env.SHOW_FIRST_ANIMAL_BRAIN;
checkIfShowBrainPicture(button);
if (Env.SHOW_FIRST_FROG_BRAIN && Env.SNAKE_MODE) {
if (Env.SHOW_FIRST_ANIMAL_BRAIN && Env.SNAKE_MODE) {
radioFrog.setVisible(true);
radioSnake.setVisible(true);
} else {
@ -139,12 +140,12 @@ public class Application {
snakeModeCkBox.setBounds(buttonXpos, speedSlider.getY() + 25, 120, buttonHeight);
snakeModeCkBox.addActionListener(e -> {
Env.SNAKE_MODE = snakeModeCkBox.isSelected();
if (Env.SHOW_FIRST_FROG_BRAIN && Env.SNAKE_MODE) {
if (Env.SHOW_FIRST_ANIMAL_BRAIN && Env.SNAKE_MODE) {
radioFrog.setVisible(true);
radioSnake.setVisible(true);
} else {
radioFrog.setSelected(true);
selectFrog =true;
selectFrog = true;
radioFrog.setVisible(false);
radioSnake.setVisible(false);
}

@ -1,7 +1,4 @@
package com.github.drinkjava2.frog;
import static com.github.drinkjava2.frog.Env.ENV_HEIGHT;
import static com.github.drinkjava2.frog.Env.ENV_WIDTH;
package com.gitee.drinkjava2.frog;
import java.awt.Color;
import java.awt.Graphics;
@ -12,14 +9,13 @@ import java.util.List;
import javax.swing.JPanel;
import com.github.drinkjava2.frog.egg.Egg;
import com.github.drinkjava2.frog.egg.FrogEggTool;
import com.github.drinkjava2.frog.egg.SnakeEggTool;
import com.github.drinkjava2.frog.objects.EnvObject;
import com.github.drinkjava2.frog.objects.Food;
import com.github.drinkjava2.frog.objects.Material;
import com.github.drinkjava2.frog.snake.Snake;
import com.github.drinkjava2.frog.util.RandomUtils;
import com.gitee.drinkjava2.frog.egg.Egg;
import com.gitee.drinkjava2.frog.egg.FrogEggTool;
import com.gitee.drinkjava2.frog.egg.SnakeEggTool;
import com.gitee.drinkjava2.frog.objects.EnvObject;
import com.gitee.drinkjava2.frog.objects.Food;
import com.gitee.drinkjava2.frog.objects.Material;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Env is the living space of frog. draw it on JPanel
@ -29,6 +25,8 @@ import com.github.drinkjava2.frog.util.RandomUtils;
*/
@SuppressWarnings("all")
public class Env extends JPanel {
private static final long serialVersionUID = 1L;
/** Speed of test */
public static int SHOW_SPEED = 10; // 测试速度,-1000~1000,可调, 数值越小,速度越慢
@ -46,8 +44,8 @@ public class Env extends JPanel {
public static final int FROG_BRAIN_YSIZE = 1000; // frog的脑在Y方向长度
public static final int FROG_BRAIN_ZSIZE = 1000; // frog的脑在Z方向长度
/** SHOW first frog's brain structure */
public static boolean SHOW_FIRST_FROG_BRAIN = true; // 是否显示脑图在Env区的右侧
/** SHOW first animal's brain structure */
public static boolean SHOW_FIRST_ANIMAL_BRAIN = true; // 是否显示脑图在Env区的右侧
/** Draw first frog's brain after some steps */
public static int DRAW_BRAIN_AFTER_STEPS = 1; // 以此值为间隔动态画出脑图设为0则关闭这个动态脑图功能只显示一个静态、不闪烁的脑图
@ -74,12 +72,14 @@ public class Env extends JPanel {
public static boolean SNAKE_MODE = true; // 是否加小蛇加进来吃青蛙?
public static final int SNAKE_EGG_QTY = 5; // 每轮下n个蛇蛋可调只有最优秀的前n个蛇们才允许下蛋
public static final int SNAKE_EGG_QTY = 10; // 每轮下n个蛇蛋可调只有最优秀的前n个蛇们才允许下蛋
public static final int SNAKE_PER_EGG = 4; // 每个蛇蛋可以孵出几个蛇
// 以下是程序内部变量,不要手工修改它们
public static final int FROG_PER_SCREEN = FROG_EGG_QTY * FROG_PER_EGG / SCREEN; // 每屏显示几个青蛙,这个数值由其它常量计算得来
public static final int TOTAL_FROG_QTY = FROG_EGG_QTY * FROG_PER_EGG; // 蛇的总数
public static final int FROG_PER_SCREEN = TOTAL_FROG_QTY / SCREEN; // 每屏显示几个青蛙,这个数值由其它常量计算得来
public static int current_screen = 0;
@ -128,12 +128,12 @@ public class Env extends JPanel {
return x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT;
}
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 closeToEdge(Animal a) {// 靠近边界? 离死不远了
return a.x < 20 || a.y < 20 || a.x > (Env.ENV_WIDTH - 20) || a.y > (Env.ENV_HEIGHT - 20);
}
public static boolean foundAnyThing(int x, int y) {// 如果指定点看到任意东西或超出边界返回true
return x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT || Env.bricks[x][y] >= Material.VISIBLE;
public static boolean foundAnyThingOrOutEdge(int x, int y) {// 如果指定点看到任意东西或超出边界返回true
return x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT || Env.bricks[x][y] != 0;
}
public static boolean foundAndAteFood(int x, int y) {// 如果x,y有食物将其清0返回true
@ -145,9 +145,9 @@ public class Env extends JPanel {
return false;
}
public static boolean foundFrog(int x, int y) {// 如果指定点看到青蛙或超出边界返回true
public static boolean foundFrogOrOutEdge(int x, int y) {// 如果指定点看到青蛙或超出边界返回true
if (x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT)
return false;// 如果出界返回true
return true;// 如果出界返回true
int frogNo = Env.bricks[x][y] & Material.FROG_TAG;
if (frogNo > 0) {
Frog f = frogs.get(frogNo - 1);
@ -157,7 +157,7 @@ public class Env extends JPanel {
return false;
}
public static boolean foundAndAteFrog(int x, int y) {// TODO:优化寻找青蛙的速度,不要用循环 如果x,y有青蛙将其杀死返回true
public static boolean foundAndAteFrog(int x, int y) {// 如果x,y有青蛙将其杀死返回true
if (x < 0 || y < 0 || x >= ENV_WIDTH || y >= ENV_HEIGHT)
return false;// 如果出界返回false;
int frogNo = Env.bricks[x][y] & Material.FROG_TAG;
@ -250,14 +250,14 @@ public class Env extends JPanel {
}
private String frogAtedCount() {// 统计食蛙总数
return new StringBuilder("吃蛙率:").append(format100.format(Env.frog_ated * 1.00 / TOTAL_SNAKE_QTY)).toString();
return new StringBuilder("吃蛙率:").append(format100.format(Env.frog_ated * 1.00 / TOTAL_FROG_QTY)).toString();
}
public static void checkIfPause(Frog f) {
public static void checkIfPause(Animal a) {
if (pause)
do {
if (f != null) {
Application.brainPic.drawBrainPicture(f);
if (a != null) {
Application.brainPic.drawBrainPicture(a);
Application.brainPic.requestFocus();
}
sleep(100);
@ -296,19 +296,20 @@ public class Env extends JPanel {
for (int j = 0; j < FROG_PER_SCREEN; j++) {
Frog f = frogs.get(current_screen * FROG_PER_SCREEN + j);
f.initFrog(); // 初始化器官延迟到这一步,是因为脑细胞太占内存,而且当前屏测完后会清空
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.initFrog(); // 初始化器官延迟到这一步,是因为脑细胞太占内存,而且当前屏测完后会清空
s.initAnimal(); // 初始化器官延迟到这一步,是因为脑细胞太占内存,而且当前屏测完后会清空
Snake.setEnvSnakeMaterial(s); // 出现时就要设定蛇的材料在环境里,暂时用一条线代替
}
}
Frog showFrog = Application.selectFrog ? firstFrog : firstSnake;
Animal showFrog = Application.selectFrog ? firstFrog : firstSnake;
for (step = 0; step < STEPS_PER_ROUND; step++) {
for (EnvObject thing : things)// 调用食物、陷阱等物体的动作
thing.active(current_screen);
thing.active();
if (allDead)
break; // 青蛙全死光了就直接跳到下一轮,以节省时间
allDead = true;
@ -344,7 +345,7 @@ public class Env extends JPanel {
s.show(g);
}
if (SHOW_FIRST_FROG_BRAIN && showFrog != null) {
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);
@ -355,7 +356,7 @@ public class Env extends JPanel {
g2.drawImage(buffImg, 0, 0, this);
}
// System.out.println(showFrog.debugInfo());// 打印输出Frog调试内容
if (SHOW_FIRST_FROG_BRAIN)
if (SHOW_FIRST_ANIMAL_BRAIN)
Application.brainPic.drawBrainPicture(showFrog);
checkIfPause(firstFrog);
for (int j = 0; j < FROG_PER_SCREEN; j++) {
@ -371,11 +372,11 @@ public class Env extends JPanel {
sb.append(foodAtedCount());
Application.mainFrame.setTitle(sb.toString());
// for (EnvObject thing : things)// 去除食物、陷阱等物体
// thing.destory();
// for (EnvObject thing : things)// 去除食物、陷阱等物体
// thing.destory();
for (int i = 0; i < ENV_WIDTH; i++) {// 清除食物
for (int j = 0; j < ENV_HEIGHT; j++)
bricks[i][j]=0;
bricks[i][j] = 0;
}
}
round++;

@ -8,17 +8,14 @@
* 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.snake;
package com.gitee.drinkjava2.frog;
import java.awt.Graphics;
import java.awt.Image;
import java.io.FileInputStream;
import javax.imageio.ImageIO;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.egg.Egg;
import com.gitee.drinkjava2.frog.egg.Egg;
/**
* Snake has similar brain like Frog, snake eat frog <br>
@ -26,24 +23,21 @@ import com.github.drinkjava2.frog.egg.Egg;
*
* @since 1.0
*/
public class Snake extends Frog {
static Image snakeImg;
static {
public class Frog extends Animal {
public Frog(int x, int y, Egg egg) {
super(x, y, egg);
try {
snakeImg = ImageIO.read(new FileInputStream(Application.CLASSPATH + "snake.png"));
animalImage = ImageIO.read(new FileInputStream(Application.CLASSPATH + "frog.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
public Snake(int x, int y, Egg egg) {
super(x, y, egg);
}
@Override
public void show(Graphics g) {// 显示蛇的图象
if (!alive)
return;
g.drawImage(snakeImg, x - 16, y - 5, 18, 18, null);// 减去坐标保证蛇嘴巴显示在当前x,y处
g.drawImage(animalImage, x - 8, y - 8, 16, 16, null);// 减去坐标保证蛇嘴巴显示在当前x,y处
}
}

@ -0,0 +1,54 @@
/*
* 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.gitee.drinkjava2.frog;
import java.awt.Graphics;
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 <br>
* (Food)
*
* @since 1.0
*/
public class Snake extends Animal {
public Snake(int x, int y, Egg egg) {
super(x, y, egg);
try {
animalImage = ImageIO.read(new FileInputStream(Application.CLASSPATH + "snake.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void show(Graphics g) {// 显示蛇的图象
if (!alive)
return;
g.drawImage(animalImage, x - 16, y - 5, 18, 18, null);// 减去坐标保证蛇嘴巴显示在当前x,y处
}
public static void clearEnvSnakeMaterial(Animal snake) {// 这个方法清除Env中代表蛇的图像对应int的位
for (int i = -5; i < 6; i++)
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++)
Env.setMaterial(snake.x + i, snake.y - i, Material.SNAKE);
}
}

@ -1,9 +1,8 @@
package com.github.drinkjava2.frog.brain;
package com.gitee.drinkjava2.frog.brain;
import static java.awt.Color.BLACK;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
//import static java.awt.BLUE;
import static java.lang.Math.cos;
import static java.lang.Math.round;
import static java.lang.Math.sin;
@ -17,10 +16,10 @@ import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.util.ColorUtils;
import com.gitee.drinkjava2.frog.Animal;
import com.gitee.drinkjava2.frog.Application;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.util.ColorUtils;
/**
* BrainPicture show first frog's brain structure, for debug purpose only
@ -34,15 +33,17 @@ import com.github.drinkjava2.frog.util.ColorUtils;
*/
@SuppressWarnings("all")
public class BrainPicture extends JPanel {
private static final float d90 = (float) (Math.PI / 2);
private static final long serialVersionUID = 1L;
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 = d90 * .8f; // brain rotate on x axis
float yAngle = d90 / 4; // 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
int xMask = -1;// x Mask
int yMask = -1;// y Mask
@ -65,6 +66,7 @@ public class BrainPicture extends JPanel {
this.addMouseMotionListener(act);// 添加鼠标移动动作监听
keyAdapter = new KeyAdapter() {// 处理t,f,l,rx键盘命令
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:// Y切面向上
@ -96,23 +98,23 @@ public class BrainPicture extends JPanel {
zAngle = 0;
break;
case 'F':// 前视
xAngle = d90;
xAngle = D90;
yAngle = 0;
zAngle = 0;
break;
case 'L':// 左视
xAngle = d90;
yAngle = d90;
xAngle = D90;
yAngle = D90;
zAngle = 0;
break;
case 'R':// 右视
xAngle = d90;
yAngle = -d90;
xAngle = D90;
yAngle = -D90;
zAngle = 0;
break;
case 'X':// 斜视
xAngle = d90 * .8f;
yAngle = d90 / 4;
xAngle = D90 * .8f;
yAngle = D90 / 4;
zAngle = 0;
break;
default:
@ -124,35 +126,14 @@ public class BrainPicture extends JPanel {
}
public void drawZone(Zone o) {// 在脑图上画一个正立方体Zone框架视角是TopView
float x = o.x - o.r;
float y = o.y - o.r;
float z = o.z - o.r;
float e = o.r + o.r;
drawLine(x, y, z, x + e, y, z);// 画立方体的下面边
drawLine(x + e, y, z, x + e, y + e, z);
drawLine(x + e, y + e, z, x, y + e, z);
drawLine(x, y + e, z, x, y, z);
drawLine(x, y, z, x, y, z + e);// 画立方体的中间边
drawLine(x + e, y, z, x + e, y, z + e);
drawLine(x + e, y + e, z, x + e, y + e, z + e);
drawLine(x, y + e, z, x, y + e, z + e);
drawLine(x, y, z + e, x + e, y, z + e);// 画立方体的上面边
drawLine(x + e, y, z + e, x + e, y + e, z + e);
drawLine(x + e, y + e, z + e, x, y + e, z + e);
drawLine(x, y + e, z + e, x, y, z + e);
drawCuboid(o.x - o.r, o.y - o.r, o.z - o.h * .5f, o.r + o.r, o.r + o.r, o.h);
}
public void drawCuboid(Cuboid c) {// 在脑图上画一个长立方体框架视角是TopView
float x = c.x;
float y = c.y;
float z = c.z;
float xe = c.xe;
float ye = c.ye;
float ze = c.ze;
drawCuboid(c.x, c.y, c.z, c.xe, c.ye, c.ze);
}
public void drawCuboid(float x, float y, float z, float xe, float ye, float ze) {// 在脑图上画一个长立方体框架视角是TopView
drawLine(x, y, z, x + xe, y, z);// 画立方体的下面边
drawLine(x + xe, y, z, x + xe, y + ye, z);
drawLine(x + xe, y + ye, z, x, y + ye, z);
@ -213,9 +194,9 @@ public class BrainPicture extends JPanel {
z1 = z;
x = z1 * sin(yAngle) + x1 * cos(yAngle);// 绕y轴转
z = z1 * cos(yAngle) - x1 * sin(yAngle);
// z = z1 * cos(yAngle) - x1 * sin(yAngle);
x1 = x;
z1 = z;
// z1 = z;
x = x1 * cos(zAngle) - y1 * sin(zAngle);// 绕z轴转
y = x1 * sin(zAngle) + y1 * cos(zAngle);
@ -228,9 +209,9 @@ public class BrainPicture extends JPanel {
z2 = z;
x = z2 * sin(yAngle) + x2 * cos(yAngle);// 绕y轴转
z = z2 * cos(yAngle) - x2 * sin(yAngle);
// z = z2 * cos(yAngle) - x2 * sin(yAngle);
x2 = x;
z2 = z;
// z2 = z;
x = x2 * cos(zAngle) - y2 * sin(zAngle);// 绕z轴转
y = x2 * sin(zAngle) + y2 * cos(zAngle);
@ -249,7 +230,7 @@ public class BrainPicture extends JPanel {
}
/** 画点固定以top视角的角度所以只需要在x1,y1位置画一个点 */
public void drawPoint(float px1, float py1, float pz1, int diameter) {
public void drawPoint(float px1, float py1, float pz1, float r) {
double x1 = px1 - Env.FROG_BRAIN_XSIZE / 2;
double y1 = -py1 + Env.FROG_BRAIN_YSIZE / 2;// 屏幕的y坐标是反的显示时要正过来
double z1 = pz1 - Env.FROG_BRAIN_ZSIZE / 2;
@ -263,9 +244,9 @@ public class BrainPicture extends JPanel {
z1 = z;
x = z1 * sin(yAngle) + x1 * cos(yAngle);// 绕y轴转
z = z1 * cos(yAngle) - x1 * sin(yAngle);
// z = z1 * cos(yAngle) - x1 * sin(yAngle);
x1 = x;
z1 = z;
// z1 = z;
x = x1 * cos(zAngle) - y1 * sin(zAngle);// 绕z轴转
y = x1 * sin(zAngle) + y1 * cos(zAngle);
@ -273,8 +254,8 @@ public class BrainPicture extends JPanel {
y1 = y;
g.setColor(picColor);
g.fillOval((int) round(x1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + xOffset,
(int) round(y1) + Env.FROG_BRAIN_DISP_WIDTH / 2 + yOffset - diameter / 2, diameter, diameter);
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) {
@ -295,9 +276,9 @@ public class BrainPicture extends JPanel {
z1 = z;
x = z1 * sin(yAngle) + x1 * cos(yAngle);// 绕y轴转
z = z1 * cos(yAngle) - x1 * sin(yAngle);
// z = z1 * cos(yAngle) - x1 * sin(yAngle);
x1 = x;
z1 = z;
// z1 = z;
x = x1 * cos(zAngle) - y1 * sin(zAngle);// 绕z轴转
y = x1 * sin(zAngle) + y1 * cos(zAngle);
@ -313,8 +294,8 @@ 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(Frog f) {// 在这个方法里进行青蛙或蛇的三维脑结构的绘制,蛇是青蛙的子类,所以也可以当参数传进来
if (!Env.SHOW_FIRST_FROG_BRAIN || f == null || !f.alive)
public void drawBrainPicture(Animal a) {// 在这个方法里进行动物的三维脑结构的绘制,蛇是青蛙的子类,所以也可以当参数传进来
if (!Env.SHOW_FIRST_ANIMAL_BRAIN || a == null || !a.alive)
return;
g.setColor(WHITE);// 先清空旧图
g.fillRect(0, 0, brainDispWidth, brainDispWidth);
@ -326,14 +307,14 @@ public class BrainPicture extends JPanel {
drawText(0, 100, 0, "y");
drawText(0, 0, 100, "z");
for (Organ organ : f.organs)// 每个器官负责画出自已在脑图中的位置和形状
organ.drawOnBrainPicture(f, this); // each organ draw itself
for (Organ organ : a.organs)// 每个器官负责画出自已在脑图中的位置和形状
organ.drawOnBrainPicture(a, this); // each organ draw itself
setPicColor(RED);
drawLine(0, 0, 0, 1, 0, 0);
drawLine(0, 0, 0, 0, 1, 0);
drawLine(0, 0, 0, 0, 0, 1);
for (Cell cell : f.cells) {
for (Cell cell : a.cells) {
if (cell != null && cell.energy > 20) {
setPicColor(ColorUtils.grayColor(cell.energy));// 用灰度表示活跃度
if (cell.body != null)
@ -389,6 +370,10 @@ public class BrainPicture extends JPanel {
this.picColor = color;
}
public Color getPicColor() {
return picColor;
}
public int getxOffset() {
return xOffset;
}

@ -8,7 +8,7 @@
* 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;
package com.gitee.drinkjava2.frog.brain;
/**
* Cell is the basic unit of frog's brain

@ -8,7 +8,7 @@
* 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;
package com.gitee.drinkjava2.frog.brain;
/**
* Cuboid represents a rectangular prism 3d zone in brain
@ -22,18 +22,18 @@ package com.github.drinkjava2.frog.brain;
public class Cuboid implements Shape {
private static final long serialVersionUID = 1L;
public int x;// x,y,z是长方体的左下角坐标
public int y;
public int z;
public int xe;// xe,ye,ze分别是长方体三边长
public int ye;
public int ze;
public float x;// x,y,z是长方体的左下角坐标
public float y;
public float z;
public float xe;// xe,ye,ze分别是长方体三边长
public float ye;
public float ze;
public Cuboid() {
// 空构造器不能省
}
public Cuboid(int x, int y, int z, int xe, int ye, int ze) {// 用x,y,z,r来构造
public Cuboid(float x, float y, float z, float xe, float ye, float ze) {// 用x,y,z,r来构造
this.x = x;
this.y = y;
this.z = z;

@ -1,4 +1,4 @@
package com.github.drinkjava2.frog.brain;
package com.gitee.drinkjava2.frog.brain;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
@ -34,6 +34,7 @@ public class MouseAction implements MouseListener, MouseWheelListener, MouseMoti
buttonPressed = 0;
x = e.getPoint().x;
y = e.getPoint().y;
brainPic.requestFocus();
}
@Override

@ -8,12 +8,12 @@
* 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;
package com.gitee.drinkjava2.frog.brain;
import java.awt.Color;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Animal;
/**
* Organ is a part of frog, organ can be saved in egg
@ -38,32 +38,31 @@ public class Organ extends Zone {
}
/** Only call once when frog created , Child class can override this method */
public void initFrog(Frog f) { // 仅在Frog生成时会调用一次
public void initOrgan(Animal a) { // 仅在Animal生成时会调用一次
}
/** Each loop step call active method, Child class can override this method */
public void active(Frog f) { // 这是器官级别的方法,每个步长调用一次
public void active(Animal a) { // 这是器官级别的方法,每个步长调用一次
}
/** Each loop step call active method, Child class can override this method */
public void active(Frog f, Cell c) { // 这是Cell级别的方法每个步长、每个细胞都要调用一次
public void active(Animal a, Cell c) { // 这是Cell级别的方法每个步长、每个细胞都要调用一次
}
/** If active in this organ's zone? */
public boolean outputActive(Frog f) { // 如果细胞能量>organActiveEnergy,则细胞能量减少返回true(激活)标志
for (Cell cell : f.cells)
if (cell.energy > organActiveEnergy)
if (this.nearby(cell.output)) {
cell.organ.fat++;
cell.energy -= 30;//
return true;
}
public boolean outputActive(Animal a) { // 如果细胞能量>organActiveEnergy,则细胞能量减少返回true(激活)标志
for (Cell cell : a.cells)
if (cell.energy > organActiveEnergy && this.nearby(cell.output)) {
cell.organ.fat++;
cell.energy -= 30;//
return true;
}
return false;
}
/** If active in this organ's zone? */
public void activeInput(Frog f, float energy) { // 如果一个细胞输入触突位于这个器官内,则细胞能量增加激活
for (Cell cell : f.cells)
public void activeInput(Animal a, float energy) { // 如果一个细胞输入触突位于这个器官内,则细胞能量增加激活
for (Cell cell : a.cells)
if (cell.energy < 100)
if (this.nearby(cell.input)) {
cell.energy += energy;
@ -72,15 +71,15 @@ public class Organ extends Zone {
}
/** Set X, Y, Radius, name of current Organ */
public Organ setXYZRN(float x, float y, float z, float r, String name) {
this.setXYZR(x, y, z, r);
public Organ setXYZRHN(float x, float y, float z, float r, float h, String name) {
this.setXYZRH(x, y, z, r, h);
this.name = name;
return this;
}
/** Child class can override this method to drawing picture */
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法
if (!Env.SHOW_FIRST_FROG_BRAIN)
public void drawOnBrainPicture(Animal a, BrainPicture pic) {// 把自已这个器官在脑图上显示出来,子类可以重写这个方法
if (!Env.SHOW_FIRST_ANIMAL_BRAIN)
return;
pic.setPicColor(Color.BLACK); // 缺省是黑色
pic.drawZone(this);
@ -96,7 +95,7 @@ public class Organ extends Zone {
} catch (Exception e) {
throw new UnknownError("Can not make new organ copy for " + this);
}
copyXYZR(this, newOrgan);
copyXYZRH(this, newOrgan);
newOrgan.name = this.name;
newOrgan.fat = this.fat;
return new Organ[] { newOrgan };

@ -8,7 +8,7 @@
* 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;
package com.gitee.drinkjava2.frog.brain;
import java.io.Serializable;

@ -8,25 +8,29 @@
* 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;
package com.gitee.drinkjava2.frog.brain;
import java.io.Serializable;
import com.github.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Env;
/**
* Zone represents a cube zone in brain
* Zone represents a cuboid zone in brain, but x,y,z is in the center
*
* Zonex,y,zrh
*
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class Zone implements Serializable { // zone 代表脑空间中的一块立方区域, 以x,y,z为中心 以r为边长的一半
private static final long serialVersionUID = 1L;
public float x;
public float y;
public float z;
public float r;// r为这个立方矩形边长的一半
public float r;// r为这个立方矩形上边长的一半
public float h;// h为这个立方矩形厚度
public Zone() {
// 空构造器不能省
@ -37,6 +41,27 @@ public class Zone implements Serializable { // zone 代表脑空间中的一块
this.y = y;
this.z = z;
this.r = r;
this.h = r + r;
if (this.x < 0)
this.x = 0;
if (this.y < 0)
this.y = 0;
if (this.z < 0)
this.z = 0;
if (this.x > Env.FROG_BRAIN_XSIZE)
this.x = Env.FROG_BRAIN_XSIZE;
if (this.y > Env.FROG_BRAIN_YSIZE)
this.y = Env.FROG_BRAIN_YSIZE;
if (this.z > Env.FROG_BRAIN_ZSIZE)
this.z = Env.FROG_BRAIN_ZSIZE;
}
public Zone(float x, float y, float z, float r, float h) {// 用x,y,z, r来构造
this.x = x;
this.y = y;
this.z = z;
this.r = r;
this.h = h;
if (this.x < 0)
this.x = 0;
if (this.y < 0)
@ -56,13 +81,15 @@ public class Zone implements Serializable { // zone 代表脑空间中的一块
this.y = z.y;
this.z = z.z;
this.r = z.r;
this.h = z.h;
}
public Zone(Zone a, Zone b) {// 用两个Zone来构造新的zone位于两个zone的中间
this.x = (a.x + b.x) / 2;
this.y = (a.y + b.y) / 2;
this.z = (a.z + b.z) / 2-10 ;
this.r = (a.r + b.r) / 2;
this.z = (a.z + b.z) / 2 - 20; // -20表示它是下一层的连线
this.r = 5;
this.h = (a.h + b.h) / 2;
}
public boolean nearby(Zone o) {
@ -72,6 +99,11 @@ public class Zone implements Serializable { // zone 代表脑空间中的一块
return Math.abs(x - o.x) < dist && Math.abs(y - o.y) < dist && Math.abs(z - o.z) < dist;
}
public boolean nearby(float x, float y, float z, float r) {
float dist = this.r + r;
return Math.abs(this.x - x) < dist && Math.abs(this.y - y) < dist && Math.abs(this.z - z) < dist;
}
public int roundX() {
return Math.round(x);
}
@ -84,24 +116,20 @@ public class Zone implements Serializable { // zone 代表脑空间中的一块
return Math.round(z);
}
public static void copyXYZ(Zone from, Zone to) {
to.x = from.x;
to.y = from.y;
to.z = from.z;
}
public static void copyXYZR(Zone from, Zone to) {
public static void copyXYZRH(Zone from, Zone to) {
to.x = from.x;
to.y = from.y;
to.z = from.z;
to.r = from.r;
to.h = from.h;
}
public void setXYZR(float x, float y, float z, float r) {
public void setXYZRH(float x, float y, float z, float r, float h) {
this.x = x;
this.y = y;
this.z = z;
this.r = r;
this.h = h;
}
public String debugInfo() {

@ -8,15 +8,16 @@
* 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;
package com.gitee.drinkjava2.frog.egg;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.util.RandomUtils;
import com.gitee.drinkjava2.frog.Animal;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Egg is the static structure description of frog, can save as file, to build a
@ -33,14 +34,13 @@ public class Egg implements Serializable {
public List<Organ> organs = new ArrayList<>();// NOSONAR
public Egg() {// 无中生有,创建一个蛋,先有蛋,后有蛙
public Egg() {// 无中生有,创建一个蛋,先有蛋,后有蛙
}
/** Create egg from frog */
public Egg(Frog frog) { // 青蛙下蛋每个青蛙的器官会创建自已的副本或变异可以是0或多个
for (Organ organ : frog.organs)
for (Organ newOrgan : organ.vary())
organs.add(newOrgan);
public Egg(Animal a) { // 下蛋每个器官会创建自已的副本或变异可以是0或多个
for (Organ organ : a.organs)
organs.addAll(Arrays.asList(organ.vary()));
}
/**

@ -8,7 +8,7 @@
* 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;
package com.gitee.drinkjava2.frog.egg;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -19,21 +19,24 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
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.Active;
import com.github.drinkjava2.frog.brain.organ.Eyes;
import com.github.drinkjava2.frog.brain.organ.Mouth;
import com.github.drinkjava2.frog.brain.organ.Moves;
import com.github.drinkjava2.frog.util.LocalFileUtils;
import com.gitee.drinkjava2.frog.Animal;
import com.gitee.drinkjava2.frog.Application;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Frog;
import com.gitee.drinkjava2.frog.organ.Active;
import com.gitee.drinkjava2.frog.organ.frog.FrogBigEye;
import com.gitee.drinkjava2.frog.organ.frog.FrogEyes;
import com.gitee.drinkjava2.frog.organ.frog.FrogMouth;
import com.gitee.drinkjava2.frog.organ.frog.FrogMoves;
import com.gitee.drinkjava2.frog.util.LocalFileUtils;
/**
* EggTool save eggs to disk
* FrogEggTool save/load frog eggs to file
*
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class FrogEggTool {
/**
@ -65,8 +68,8 @@ public class FrogEggTool {
}
private static void sortFrogsOrderByEnergyDesc() {// 按能量多少给青蛙排序
Collections.sort(Env.frogs, new Comparator<Frog>() {
public int compare(Frog a, Frog b) {
Collections.sort(Env.frogs, new Comparator<Animal>() {
public int compare(Animal a, Animal b) {
if (a.energy > b.energy)
return -1;
else if (a.energy == b.energy)
@ -103,16 +106,19 @@ public class FrogEggTool {
for (int j = 0; j < Env.FROG_EGG_QTY; j++) {
Egg egg = new Egg();
float r = 40;
egg.organs.add(new Mouth().setXYZRN(0, 0, 0, 0, "Eat")); // Mouth不是感觉或输出器官没有位置和大小
egg.organs.add(new Active().setXYZRN(500, 600, 500, r, "Active")); // 永远激活
egg.organs.add(new Moves.MoveUp().setXYZRN(800, 100, 500, r, "Up"));
egg.organs.add(new Moves.MoveDown().setXYZRN(800, 400, 500, r, "Down"));
egg.organs.add(new Moves.MoveLeft().setXYZRN(700, 250, 500, r, "Left"));
egg.organs.add(new Moves.MoveRight().setXYZRN(900, 250, 500, r, "Right"));
egg.organs.add(new Eyes.SeeUp().setXYZRN(200, 300 + 90, 500, r, "SeeUp"));
egg.organs.add(new Eyes.SeeDown().setXYZRN(200, 300 - 90, 500, r, "SeeDown"));
egg.organs.add(new Eyes.SeeLeft().setXYZRN(200 - 90, 300, 500, r, "SeeLeft"));
egg.organs.add(new Eyes.SeeRight().setXYZRN(200 + 90, 300, 500, r, "SeeRight"));
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 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"));
egg.organs.add(new FrogMoves.MoveLeft().setXYZRHN(700, 450, 500, r, h, "Left"));
egg.organs.add(new FrogMoves.MoveRight().setXYZRHN(900, 450, 500, r, h, "Right"));
egg.organs.add(new FrogEyes.SeeUp().setXYZRHN(200, 500 + 90, 500, r, h, "SeeUp"));
egg.organs.add(new FrogEyes.SeeDown().setXYZRHN(200, 500 - 90, 500, r, h, "SeeDown"));
egg.organs.add(new FrogEyes.SeeLeft().setXYZRHN(200 - 90, 500, 500, r, h, "SeeLeft"));
egg.organs.add(new FrogEyes.SeeRight().setXYZRHN(200 + 90, 500, 500, r, h, "SeeRight"));
Env.frog_eggs.add(egg);
}
System.out.println("Fail to load frog egg file '" + Application.CLASSPATH + "frog_eggs.ser" + "', created "

@ -8,7 +8,7 @@
* 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;
package com.gitee.drinkjava2.frog.egg;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -19,21 +19,23 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.github.drinkjava2.frog.Application;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.brain.organ.Active;
import com.github.drinkjava2.frog.snake.Snake;
import com.github.drinkjava2.frog.snake.brain.organ.SnakeEyes;
import com.github.drinkjava2.frog.snake.brain.organ.SnakeMouth;
import com.github.drinkjava2.frog.snake.brain.organ.SnakeMoves;
import com.github.drinkjava2.frog.util.LocalFileUtils;
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.SnakeEyes;
import com.gitee.drinkjava2.frog.organ.snake.SnakeMouth;
import com.gitee.drinkjava2.frog.organ.snake.SnakeMoves;
import com.gitee.drinkjava2.frog.util.LocalFileUtils;
/**
* EggTool save eggs to disk
* SnakeEggTool save/load snake eggs to file
*
* @author Yong Zhu
* @since 1.0
*/
@SuppressWarnings("all")
public class SnakeEggTool {
/**
@ -103,17 +105,20 @@ public class SnakeEggTool {
Env.snake_eggs.clear();
for (int j = 0; j < Env.SNAKE_EGG_QTY; j++) {
Egg egg = new Egg();
float r = 40;
egg.organs.add(new SnakeMouth().setXYZRN(0, 0, 0, 0, "Eat")); // SnakeMouth不是感觉或输出器官没有位置和大小
egg.organs.add(new Active().setXYZRN(500, 600, 500, 5, "Active")); // 永远激活
egg.organs.add(new SnakeMoves.MoveUp().setXYZRN(800, 100, 500, r, "Up"));
egg.organs.add(new SnakeMoves.MoveDown().setXYZRN(800, 400, 500, r, "Down"));
egg.organs.add(new SnakeMoves.MoveLeft().setXYZRN(700, 250, 500, r, "Left"));
egg.organs.add(new SnakeMoves.MoveRight().setXYZRN(900, 250, 500, r, "Right"));
egg.organs.add(new SnakeEyes.SeeUp().setXYZRN(200, 300 + 90, 500, r, "SeeUp"));
egg.organs.add(new SnakeEyes.SeeDown().setXYZRN(200, 300 - 90, 500, r, "SeeDown"));
egg.organs.add(new SnakeEyes.SeeLeft().setXYZRN(200 - 90, 300, 500, r, "SeeLeft"));
egg.organs.add(new SnakeEyes.SeeRight().setXYZRN(200 + 90, 300, 500, r, "SeeRight"));
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 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"));
egg.organs.add(new SnakeMoves.MoveLeft().setXYZRHN(700, 450, 500, r, h, "Left"));
egg.organs.add(new SnakeMoves.MoveRight().setXYZRHN(900, 450, 500, r, h, "Right"));
egg.organs.add(new SnakeEyes.SeeUp().setXYZRHN(200, 500 + 90, 500, r, h, "SeeUp"));
egg.organs.add(new SnakeEyes.SeeDown().setXYZRHN(200, 500 - 90, 500, r, h, "SeeDown"));
egg.organs.add(new SnakeEyes.SeeLeft().setXYZRHN(200 - 90, 500, 500, r, h, "SeeLeft"));
egg.organs.add(new SnakeEyes.SeeRight().setXYZRHN(200 + 90, 500, 500, r, h, "SeeRight"));
Env.snake_eggs.add(egg);
}
System.out.println("Fail to load snake egg file '" + Application.CLASSPATH + "snake_eggs.ser"

@ -8,7 +8,7 @@
* 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;
package com.gitee.drinkjava2.frog.objects;
/**
* EnvObject means some virtual object in Env
@ -22,5 +22,5 @@ public interface EnvObject {
public void destory();// 从Env中清除本身物体只在每屏测试完成后调用一次
public void active(int screen); // 每个步长都会调用一次这个方法
public void active(); // 每个步长都会调用一次这个方法
}

@ -8,15 +8,15 @@
* 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;
package com.gitee.drinkjava2.frog.objects;
import static com.github.drinkjava2.frog.Env.ENV_HEIGHT;
import static com.github.drinkjava2.frog.Env.ENV_WIDTH;
import static com.github.drinkjava2.frog.Env.FOOD_QTY;
import static com.github.drinkjava2.frog.Env.bricks;
import static com.gitee.drinkjava2.frog.Env.ENV_HEIGHT;
import static com.gitee.drinkjava2.frog.Env.ENV_WIDTH;
import static com.gitee.drinkjava2.frog.Env.FOOD_QTY;
import static com.gitee.drinkjava2.frog.Env.bricks;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.util.RandomUtils;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Food randomly scatter on Env
@ -66,7 +66,7 @@ public class Food implements EnvObject {
}
@Override
public void active(int screen) {
public void active() {
if (!Env.FOOD_CAN_MOVE)// 如果食物不能移动
return;
if (RandomUtils.percent(96))// 用机率来调整食物(苍蝇)的速度

@ -8,7 +8,7 @@
* 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;
package com.gitee.drinkjava2.frog.objects;
import java.awt.Color;
@ -20,7 +20,7 @@ import java.awt.Color;
* @author Yong Zhu
* @since 1.0
*/
public class Material {
public class Material {// NOSONAR
public static final int FROG_TAG = 0b11111111111111; // 16383 小于等于16384的位数用来标记青蛙序号可利用Env.frogs.get(no-1)快速定位青蛙
@ -33,24 +33,20 @@ public class Material {
return origin;
}
// public static final int NO = 0; // nothing
public static final int VISIBLE = nextLeftShift(); // if visible to frog
public static final int SEESAW = nextLeftShift();
public static final int FOOD = nextLeftShift();
public static final int FLY1 = nextLeftShift();// FLY1苍蝇是一种会移动的Food
public static final int FLY2 = nextLeftShift();// FLY2苍蝇是一种会移动的Food
public static final int FLY3 = nextLeftShift();// FLY3苍蝇是一种会移动的Food
public static final int FLY4 = nextLeftShift();// FLY4苍蝇是一种会移动的Food
public static final int ANY_FOOD = FOOD + FLY1 + FLY2 + FLY3 + FLY4;// ANY_FOOD是几种FOOD的位叠加
public static final int SNAKE = nextLeftShift(); // 蛇的图形
public static final int SNAKE = nextLeftShift(); // 蛇的图形
public static final int KILLFROG = nextLeftShift(); // if>=KILLFROG will kill frog
public static final int BRICK = nextLeftShift();// brick will kill frog
public static final int TRAP = nextLeftShift(); // trap will kill frog
// 大于INVISIBLE的材料不显示在环境里但有可能被青蛙或蛇看到这是为了简化模式识别蛇显示为蛇图形但实际上目前它在环境中用一根线条来代表以简化模型
public static Color color(int material) {
if ((material & TRAP) > 0)
return Color.LIGHT_GRAY;

@ -0,0 +1,53 @@
/* 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.gitee.drinkjava2.frog.objects;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.Frog;
/**
* Trap will kill all frogs inside of it, if frog's position has material and
* it's not food, frog will die
*
* @author Yong Zhu
* @since 2019-08-05
*/
@SuppressWarnings("all")
public class Trap implements EnvObject {
private static final int X1 = Env.ENV_WIDTH / 2 - 350 / 2; // 陷阱左上角
private static final int Y1 = Env.ENV_HEIGHT / 2 - 20 / 2; // 陷阱左上角
private static final int X2 = Env.ENV_WIDTH / 2 + 350 / 2; // 陷阱右下角
private static final int Y2 = Env.ENV_HEIGHT / 2 + 20 / 2; // 陷阱右下角
@Override
public void build() {
for (int x = X1; x <= X2; x++)
for (int y = Y1; y <= Y2; y++)
Env.setMaterial(x, y, Material.TRAP);
}
@Override
public void destory() {
for (int x = X1; x <= X2; x++)
for (int y = Y1; y <= Y2; y++)
Env.clearMaterial(x, y, Material.TRAP);
}
@Override
public void active() {
}
public static boolean inTrap(Frog f) {
return f.x >= X1 && f.x <= X2 && f.y >= Y1 && f.y <= Y2;
}
}

@ -8,11 +8,11 @@
* 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;
package com.gitee.drinkjava2.frog.organ;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.Animal;
import com.gitee.drinkjava2.frog.brain.Cell;
import com.gitee.drinkjava2.frog.brain.Organ;
/**
* Active always keep active
@ -24,7 +24,7 @@ public class Active extends Organ {// 以前的实验发现添加一个始终激
private static final long serialVersionUID = 1L;
@Override
public void initFrog(Frog f) {
public void initOrgan(Animal a) {
if (!initilized) {
initilized = true;
organOutputEnergy = 2f;
@ -32,8 +32,8 @@ public class Active extends Organ {// 以前的实验发现添加一个始终激
}
@Override
public void active(Frog f) {
for (Cell cell : f.cells) {
public void active(Animal a) {
for (Cell cell : a.cells) {
if (cell.energy > 0)
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)

@ -0,0 +1,60 @@
/*
* 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.gitee.drinkjava2.frog.organ;
import com.gitee.drinkjava2.frog.Animal;
import com.gitee.drinkjava2.frog.brain.Cell;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.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 initOrgan(Animal 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(Animal f) {
if (RandomUtils.percent(percent)) {// 如果靠近边界,痛苦信号生成
for (Cell cell : f.cells) {
if (cell.energy > 0)
cell.energy--;
if (cell.energy < Cell.MAX_ENERGY_LIMIT)
if (cell.input.nearby(this)) // if input zone nearby this zone
cell.energy += 30;
}
}
}
}

@ -8,31 +8,38 @@
* 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;
package com.gitee.drinkjava2.frog.organ;
import java.awt.Color;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.BrainPicture;
import com.github.drinkjava2.frog.brain.Cell;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.brain.Zone;
import com.github.drinkjava2.frog.util.RandomUtils;
import com.gitee.drinkjava2.frog.Animal;
import com.gitee.drinkjava2.frog.brain.BrainPicture;
import com.gitee.drinkjava2.frog.brain.Cell;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.brain.Zone;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Line
* Line is a line between 2 organs or 2 lines
*
* OrganRandomConnectGroup
* Organ,Organ线RandomConnectGroup
* ()() Linelinebody
*
* Line<br>
* 1. Line() 2.
* 线线 3.
*
*
* @author Yong Zhu
* @since 1.0
*/
public class Line extends Organ {
private static final long serialVersionUID = 1L;
public Zone inputZone; // 输入触突区
public Zone outputZone; // 输出触突区
public Zone bodyZone; // 输出触突区
public Zone inputZone; // NOSONAR 输入触突区
public Zone outputZone; // NOSONAR 输出触突区
public Zone bodyZone; // NOSONAR 细胞本体所在位置本体的作用是可以接收其它line的输出信号
@Override
public boolean allowBorrow() { // 是否允许在精子中将这个器官借出
@ -40,11 +47,11 @@ public class Line extends Organ {
}
@Override
public void initFrog(Frog f) {
public void initOrgan(Animal a) {
if (!initilized) {
initilized = true;
inputZone = RandomUtils.randomZoneInOrgans(f);
outputZone = RandomUtils.randomZoneInOrgans(f);
inputZone = RandomUtils.randomZoneInOrgans(a);
outputZone = RandomUtils.randomZoneInOrgans(a);
bodyZone = new Zone(inputZone, outputZone);
}
this.fat = 0;// 每次fat清0因为遗传下来的fat不为0
@ -53,20 +60,20 @@ public class Line extends Organ {
c.output = outputZone;
c.body = bodyZone;
c.organ = this;
f.cells.add(c);
a.cells.add(c);
}
/** Line如果input是另一个line的body吸收能量 Line如果output是另一个line的body,放出能量 */
public void active(Frog f, Cell c) {
if (RandomUtils.percent(95)) //这个会严重影响速度,所以降低它的机率
@Override
public void active(Animal a, Cell c) {
if (RandomUtils.percent(95)) // TODO: 待优化 这个会严重影响速度,所以降低它的机率
return;
for (Cell cell : f.cells) {
if (cell.energy > organActiveEnergy)
if (c.input.nearby(cell.body)) {
c.organ.fat++;
cell.energy -= organActiveEnergy;
c.energy += organActiveEnergy;
}
for (Cell cell : a.cells) {
if (cell.energy > organActiveEnergy && c.input.nearby(cell.body)) {
c.organ.fat++;
cell.energy -= organActiveEnergy;
c.energy += organActiveEnergy;
}
if (c.energy >= organOutputEnergy && c.output.nearby(cell.body)) {
c.energy -= organOutputEnergy;
cell.energy += organOutputEnergy;
@ -77,16 +84,15 @@ public class Line extends Organ {
@Override
public Organ[] vary() {
organOutputEnergy = RandomUtils.varyInLimit(organOutputEnergy, -3, 3);
if (fat <= 0)// 如果胖值为0表示这个组的细胞没有用到可以小概率丢掉它了
if (RandomUtils.percent(30))
return new Organ[] {};
if (fat <= 0 && RandomUtils.percent(30))// 如果胖值为0表示这个组的细胞没有用到可以小概率丢掉它了
return new Organ[] {};
if (RandomUtils.percent(3)) // 有3%的几率丢掉它,防止这个器官数量只增不减
return new Organ[] {};
return new Organ[] { this };
}
@Override
public void drawOnBrainPicture(Frog f, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
public void drawOnBrainPicture(Animal a, BrainPicture pic) {// 把自已这个器官在脑图上显示出来
if (fat <= 0)
pic.setPicColor(Color.LIGHT_GRAY); // 没用到? 灰色
else if (organOutputEnergy <= 0)

@ -0,0 +1,94 @@
/*
* 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.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.Cell;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.brain.Zone;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* FrogBigEye is an organ can see anything in environment, and active brain
* cells which inputs are located in eye range
*
*
*
* @author Yong Zhu
* @since 1.0
*/
public class FrogBigEye extends Organ {// 这个新版的眼睛有nxn个感光细胞可以看到青蛙周围nxn网络内有没有食物
private static final long serialVersionUID = 1L;
public int n = 3; // NOSONAR 眼睛有n x n个感光细胞 用随机试错算法自动变异(加1或减1最小是3x3最大是12)
@Override
public void initOrgan(Animal a) { // 仅在Frog生成时这个方法会调用一次
if (!initilized) {
initilized = true;
organOutputEnergy = 30;
}
}
@Override
public Organ[] vary() {
if (RandomUtils.percent(5)) {
n = n + 1 - 2 * RandomUtils.nextInt(2);
if (n < 3)
n = 3;
if (n > 12)
n = 12;
}
return new Organ[] { this };
}
@Override
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是眼睛的左上角
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, z, r2, h);
if (Env.foundAnyThingOrOutEdge(a.x - n / 2 + i, a.y + n / 2 - j)) {
Color old = pic.getPicColor();
pic.setPicColor(Color.RED);
pic.drawPoint(x0 + i * 2 * r2 + r2, y0 + j * 2 * r2 + r2, z, r2);
pic.setPicColor(old);
}
pic.drawZone(cell);
}
}
}
@Override
public void active(Animal a) {// 如果看到食物就激活对应脑区的所有输入触突
float r2 = r / n; // r2是每个感光细胞的半径
float x0 = x - r;
float y0 = y - r; // x0,y0是眼睛的左上角
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (Env.foundAnyThingOrOutEdge(a.x - n / 2 + i, a.y - n / 2 + j)) {
for (Cell cell : a.cells)
if (cell.input.nearby(x0 + i * 2 * r2 + r2, y0 + j * 2 * r2 + r2, z, r2))
cell.energy += organOutputEnergy;
}
}
}
}
}

@ -8,12 +8,12 @@
* 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;
package com.gitee.drinkjava2.frog.organ.frog;
import com.github.drinkjava2.frog.Env;
import com.github.drinkjava2.frog.Frog;
import com.github.drinkjava2.frog.brain.Organ;
import com.github.drinkjava2.frog.util.RandomUtils;
import com.gitee.drinkjava2.frog.Animal;
import com.gitee.drinkjava2.frog.Env;
import com.gitee.drinkjava2.frog.brain.Organ;
import com.gitee.drinkjava2.frog.util.RandomUtils;
/**
* Eye can only see 4 direction
@ -21,14 +21,14 @@ import com.github.drinkjava2.frog.util.RandomUtils;
* @author Yong Zhu
* @since 1.0
*/
public class Eyes {
public class FrogEyes {
public static class SeeUp extends Organ {// 只能看到上方食物
private static final long serialVersionUID = 1L;
public int seeDistance; // 眼睛能看到的距离
@Override
public void initFrog(Frog f) { // 仅在Frog生成时这个方法会调用一次
public void initOrgan(Animal a) { // 仅在生成时这个方法会调用一次
if (!initilized) {
initilized = true;
seeDistance = 8;
@ -37,7 +37,7 @@ public class Eyes {
@Override
public Organ[] vary() {
seeDistance=RandomUtils.varyInLimit(seeDistance, 5, 20);
seeDistance = RandomUtils.varyInLimit(seeDistance, 5, 20);
if (RandomUtils.percent(5)) { // 可视距离有5%的机率变异
seeDistance = seeDistance + 1 - 2 * RandomUtils.nextInt(2);
if (seeDistance < 1)
@ -49,10 +49,10 @@ public class Eyes {
}
@Override
public void active(Frog f) {
public void active(Animal a) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x, f.y + i)) {
activeInput(f, 30);
if (Env.foundAnyThingOrOutEdge(a.x, a.y + i)) {
activeInput(a, 30);
return;
}
}
@ -62,10 +62,10 @@ public class Eyes {
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
public void active(Animal a) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x, f.y - i)) {
activeInput(f, 30);
if (Env.foundAnyThingOrOutEdge(a.x, a.y - i)) {
activeInput(a, 30);
return;
}
}
@ -75,10 +75,10 @@ public class Eyes {
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
public void active(Animal a) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x - i, f.y)) {
activeInput(f, 30);
if (Env.foundAnyThingOrOutEdge(a.x - i, a.y)) {
activeInput(a, 30);
return;
}
}
@ -88,10 +88,10 @@ public class Eyes {
private static final long serialVersionUID = 1L;
@Override
public void active(Frog f) {
public void active(Animal a) {
for (int i = 1; i < seeDistance; i++)
if (Env.foundAnyThing(f.x + i, f.y)) {
activeInput(f, 30);
if (Env.foundAnyThingOrOutEdge(a.x + i, a.y)) {
activeInput(a, 30);
return;
}
}

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

Loading…
Cancel
Save