From 3de63a30da957e5a75e1f44addd6ceb23b1e637e Mon Sep 17 00:00:00 2001 From: 13766800364 <13766800364@qq.com> Date: Thu, 9 Oct 2025 16:08:43 +0800 Subject: [PATCH] Add File --- .../gitee/drinkjava2/frog/brain/Cells.java | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 history/011_yinyan_eatfood/src/main/java/com/gitee/drinkjava2/frog/brain/Cells.java diff --git a/history/011_yinyan_eatfood/src/main/java/com/gitee/drinkjava2/frog/brain/Cells.java b/history/011_yinyan_eatfood/src/main/java/com/gitee/drinkjava2/frog/brain/Cells.java new file mode 100644 index 0000000..9b0024d --- /dev/null +++ b/history/011_yinyan_eatfood/src/main/java/com/gitee/drinkjava2/frog/brain/Cells.java @@ -0,0 +1,140 @@ +/* + * 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.brain; + +import com.gitee.drinkjava2.frog.Animal; +import com.gitee.drinkjava2.frog.Env; +import com.gitee.drinkjava2.frog.util.Logger; +import com.gitee.drinkjava2.frog.util.RandomUtils; + +/** + * Cells代表不同的脑细胞参数,对应每个参数,用8叉树算法生成不同的细胞。 + * 每个脑细胞用一个long来存储,所以最多允许64个基因位, 有时一个参数由多个基因位决定。每个基因位都由一个单独的阴阳8叉树控制,多个基因就组成了一个8叉树阵列 + * 基因+分裂算法=结构 + * 基因+分裂算法+遗传算法=结构的进化 + * 这个类里定义每个基因位的掩码, 脑结构的所有参数,都要用基因来控制。开始时可以有常量、魔数,但以后都放到基因里去自动进化。 + * + * + * @author Yong Zhu + * @since 10.0 + */ +@SuppressWarnings("all") +public class Cells { + public static int GENE_NUMBERS = 0; + private static int zeros = 0; + public static boolean[] display_gene = new boolean[64]; //脑最多有64个基因,这里用来控制哪些基因需要显示在脑图上 + + public static long EXIST = mask(1, true); // 细胞存在否,1为存在,0为不存在, true表示显示在脑图上 + public static long MOVE_UP = mask(1, true); //如此点为1,则此细胞如有能量,青蛙向上移动 + public static long MOVE_DOWN = mask(1, true); //如此点为1,则此细胞如有能量,青蛙向下移动 + public static long MOVE_LEFT = mask(1, true); //如此点为1,则此细胞如有能量,青蛙向左移动 + public static long MOVE_RIGHT = mask(1, true); //如此点为1,则此细胞如有能量,青蛙向右移动 + public static long ZT_LONG = mask(3, false); //轴突长度 + public static long ZT_LONG0 = zeros; //如果参数由多位组成,用同名+0变量表示有几个0,移位运算时用来去除0。下同 + public static long ZT = mask(1, true);//axon exist 轴突是否存在 + public static long ZTX = mask(1, false);//axon x offset, 轴突x方向, 轴突方向由x,y,z三个方向的参数组合决定 + public static long ZTX0 = zeros; //x方向暂定1位,如果2位也可以,角度更细,但出结果的时间会比较长 + public static long ZTY = mask(1, false); //轴突y方向 + public static long ZTY0 = zeros; + public static long ZTZ = mask(1, false); //轴突z方向 + public static long ZTZ0 = zeros; + public static long ZT_MINUS = mask(1, false);//细胞信号,1为正信号,0为负(抑制)信号 + +// public static long RANDOM_ACTIVE = mask(1, true);//这个基因控制细胞随机产生能量,对结果影响不大,会让静止的青蛙颤抖 + +// public static long ST_LONG = mask(2, false); //dendrite radius, 树突长度半径,待后继版本用到 +// public static long ST_LONG0 = zeros; +// public static long HAPPY = mask(1, false); //吃食奖励信号,待后继版本用到 + + public static long mask(int n, boolean display) { //返回基因掩码,高位由n个1组成,低位是当前GENE_NUMBERS个0,这个方法执行后GENE_NUMBERS会加n + for (int i = GENE_NUMBERS; i < GENE_NUMBERS + n; i++) { + display_gene[i] = display; + } + + String one = ""; + String zero = ""; + for (int i = 1; i <= n; i++) + one += "1"; + for (int i = 1; i <= GENE_NUMBERS; i++) + zero += "0"; + zeros = GENE_NUMBERS; + GENE_NUMBERS += n; + if (GENE_NUMBERS >= 64) {// + System.out.println("目前基因位数不能超过64"); + System.exit(-1); + } + return Long.parseLong(one + zero, 2); //将"111000"这种字符串转换为长整 + } + + public static void active(Animal a) {//这个方法的功能是根据细胞的参数,在细胞间传输能量(即信息的载体) + for (int z = Env.BRAIN_CUBE_SIZE - 1; z >= 0; z--) + for (int y = Env.BRAIN_CUBE_SIZE - 1; y >= 0; y--) + for (int x = Env.BRAIN_CUBE_SIZE - 1; x >= 0; x--) { + long cell = a.cells[x][y][z]; + + if ((cell & EXIST) == 0) //如细胞不存在, + continue; + +// if ((cell & RANDOM_ACTIVE) > 0) //随机产生细胞能量,会让青蛙颤抖 +// if (RandomUtils.percent(5)) +// a.energys[x][y][z] = 1; + + float e = a.energys[x][y][z]; + if (e > 0 && ((cell & ZT) > 0)) { //如有轴突基因,则当前细胞如存在能量,会输送到轴突端点处 + int x_ = (int) ((cell & ZTX) >> ZTX0); //把掩码转为坐标偏移量,因为暂定只有1位,所以只有1,-1 + if (x_ == 0) + x_ = -1; + int y_ = (int) ((cell & ZTY) >> ZTY0); + if (y_ == 0) + y_ = -1; + int z_ = (int) ((cell & ZTZ) >> ZTZ0); + if (z_ == 0) + z_ = -1; + int zt_long = (int) ((cell & ZT_LONG) >> ZT_LONG0) + 1; //轴突长度, 大小为1~8 + int xx = x + x_ * zt_long; + int yy = y + y_ * zt_long; + int zz = z + z_ * zt_long; + if (Env.insideBrain(xx, yy, zz)) { + if (a.energys[xx][yy][zz] < 10) { + if ((cell & ZT_MINUS) > 0) //如果轴空是负信号 + a.energys[xx][yy][zz]--; + else + a.energys[xx][yy][zz]++; + if (a.energys[x][y][z] > 0) + a.energys[x][y][z]--; + } + } + } + + e = a.energys[x][y][z]; + if ((e > 0) && (z < Env.BRAIN_ZSIZE - 1)) { //如当前细胞有能量,且不和眼睛在同一层,且有移动细胞,则青蛙移动 + if ((cell & MOVE_UP) > 0) {//向上y是减,屏幕y的0点在上方 + a.energys[x][y][z] = 0; + a.y++; + } + if ((cell & MOVE_DOWN) > 0) { + a.energys[x][y][z] = 0; + a.y--; + } + if ((cell & MOVE_LEFT) > 0) { + a.energys[x][y][z] = 0; + a.x--; + } + if ((cell & MOVE_RIGHT) > 0) { + a.energys[x][y][z] = 0; + a.x++; + } + } + + } + } + +}