Java 如何计算单元格';带包围的元胞自动机中的s邻域
所以我正在制作一个模拟生命的细胞自动机的程序,但是我在计算细胞活邻居的方法上遇到了一些问题。问题是我希望能够改变网格的缠绕方式——也就是说,它是从左到右缠绕(即圆柱形),从上到下缠绕,还是从左到右缠绕(即环形),或者完全不缠绕(即扁平)--我不知道该如何用我的方法来解释这一点。以下是我目前掌握的情况:Java 如何计算单元格';带包围的元胞自动机中的s邻域,java,cellular-automata,Java,Cellular Automata,所以我正在制作一个模拟生命的细胞自动机的程序,但是我在计算细胞活邻居的方法上遇到了一些问题。问题是我希望能够改变网格的缠绕方式——也就是说,它是从左到右缠绕(即圆柱形),从上到下缠绕,还是从左到右缠绕(即环形),或者完全不缠绕(即扁平)--我不知道该如何用我的方法来解释这一点。以下是我目前掌握的情况: public int getLiveNeighbors(int row, int col) { int count = 0; // "topology" is an int th
public int getLiveNeighbors(int row, int col)
{
int count = 0;
// "topology" is an int that represents wraparound:
// 0 = flat; 1 = cylindrical; 2 = toroidal
int top = topology != 2 ? row - 1 : (row + ROWS - 1) % ROWS;
int bottom = topology != 2 ? row + 1 : (row + 1) % ROWS;
int left = topology != 0 ? (col + COLS - 1) % COLS : col - 1;
int right = topology != 0 ? (col + 1) % COLS : col + 1;
for (int r = top; r < bottom + 1; r++)
for (int c = left; c < right + 1; c++)
if (!(r == row && c == col) && getCell(r, c).equals(LIVE))
count++;
}
public int getlivenextries(int行,int列)
{
整数计数=0;
//“topology”是一个整数,表示环绕:
//0=平面;1=圆柱形;2=环形
int top=拓扑!=2?行-1:(行+行-1)%ROWS;
int bottom=拓扑!=2?行+1:(行+1)%ROWS;
int left=拓扑!=0?(列+列-1)%COLS:col-1;
int right=拓扑!=0?(列+1)%COLS:col+1;
对于(int r=top;r
我认为,关键是for
-循环中的if
-语句——必须有某种方法来检查r
和c
是否在网格的边界内,同时要记住,“边界”的定义将根据网格是否缠绕/如何缠绕而有所不同。在过去,我通过使用八个不同的if
-语句的三个不同集合(每个环绕设置一个)来解决这个问题,分别检查组成原始单元格邻域的八个单元格中的每一个;正如你所能想象的,它不是很漂亮,但至少它起作用了
我不太擅长解释我自己的代码,所以我希望这不会太让人困惑——我自己也觉得有点不对劲(哈)。如果有任何问题,请随时提问 您可能已经有了一个类似于
Board
的类,其方法类似于getCell(x,y)
(您的代码中至少存在一个此类方法)
从某种意义上说,我只是想让这个方法变得宽松,它可以接受负的x
和y
或x
和y
大于或等于COLS
和行
。因此,您可以只迭代col-1
到col+1
和row-1
到row+1
(减去col
和row
),而不关心这些坐标是否“在板上”。板的任务是正确地进行坐标查找
使您的代码更难的另一个原因是您在一个地方处理不同的拓扑。这很难理解
通过实现Board
的不同子类,例如CylindricalBoard
、ToroidalBoard
和FlatBoard
,您可以使它变得更简单。每个子类实现的getCell
都不同,但是在子类的上下文中,它是可以清楚理解的。您可能已经有了一个类似Board
的类,其方法类似于getCell(x,y)
(您的代码中至少存在这种方法)
从某种意义上说,我只是想让这个方法变得宽松,它可以接受负的x
和y
或x
和y
大于或等于COLS
和行
。因此,您可以只迭代col-1
到col+1
和row-1
到row+1
(减去col
和row
),而不关心这些坐标是否“在板上”。板的任务是正确地进行坐标查找
使您的代码更难的另一个原因是您在一个地方处理不同的拓扑。这很难理解
通过实现Board
的不同子类,例如CylindricalBoard
、ToroidalBoard
和FlatBoard
,您可以使它变得更简单。每个子类实现的getCell
都不同,但是在子类的上下文中,它是可以清楚理解的。您正在寻找:
当类只在行为上有所不同时,存在一些常见情况。对于这种情况,最好将算法隔离在单独的类中,以便能够在运行时选择不同的算法
在这种情况下,您可能需要这样的内容(为了清晰起见,缩写为):
类点{
int x;
int-y;
}
接口包装策略{
点向上移动(点p);
点向下移动(点p);
点向左移动(点p);
向右移动点(p点);
}
class Cylinder包装实现包装策略{
内部高度;
整数周长;
点向上移动(点p){
如果(p.y=高度-1)
返回null;//不能向下移动
返回新点(p.x,p.y+1);
}
点向左移动(点p){
如果(p.x=周长-1)
返回新点(0,p.y);
返回新点(p.x+1,p.y);
}
}
您正在寻找:
当类只在行为上有所不同时,存在一些常见情况。对于这种情况,最好将算法隔离在单独的类中,以便能够在运行时选择不同的算法
在这种情况下,您可能需要这样的内容(为了清晰起见,缩写为):
类点{
int x;
int-y;
}
接口包装策略{
点向上移动(点p);
点向下移动(点p);
点向左移动(点p);
向右移动点(p点);
}
class Cylinder包装实现包装策略{
内部高度;
整数周长;
点向上移动(点p){
如果(p.y=高度-1)
返回null;//canno
import java.awt.Point;
public class Neighbours {
public static void main(String[] args) {
Neighbours inst=new Neighbours();
int r=3;//<ROWS
int c=3;//<COLS
for(int i :new int[]{0,1,2}){
inst.type=i;
System.out.format("There are %d neighbours of point (%d,%d), topography type %d\n", inst.countLiveNeighbours(r, c), c, r,i);
}
}
int ROWS=4;
int COLS=4;
int type=0;//0=flat, 1=cylinder, 2=toroid
/**
* Is x,y a neighbour of r,c?
* @return coordinates of neighbour or null
*/
Point neighbour(int x, int y, int r, int c){
if((x==c)&&(y==r))
return null;
switch (type){
/*this is wrong for the reasons explained below
case 0: return ((x<COLS)&&(y<ROWS)) ? new Point (x,y) : null;
case 1: return y<ROWS ? new Point(x%COLS,y) : null;
case 2: return new Point(x%COLS,y%ROWS);
*/
//replacement statements produce the correct behaviour
case 0: return ((x<COLS)&&(x>-1)&&(y<ROWS)&&(y>-1)) ? new Point (x,y) : null;
case 1: return ((y<ROWS)&&(y>-1)) ? new Point(Math.floorMod(x,COLS),y) : null;
case 2: return new Point(Math.floorMod(x,COLS),Math.floorMod(y,ROWS));
}
return null;
}
int countLiveNeighbours(int r, int c){
int result=0;
for(int x=c-1; x<c+2; x++)
for(int y=r-1; y<r+2; y++){
Point p=neighbour(x,y,r,c);
if(live(p)){
System.out.format("\tpoint (%d,%d)\n",(int)p.getX(),(int)p.getY());
result++;
}
}
return result;
}
boolean live(Point p){
boolean result=true;
if(p==null)
return false;
//perform tests for liveness here and set result
return result;
}
}