康威生命游戏实现疑问:为何多数Tile邻居为Null?
问题原因
你创建的newGeneration是引用类型数组,初始化后所有元素默认都是null。而循环是按从上到下、从左到右的顺序逐个创建Tile,在创建当前Tile时,它的多数邻居(比如上方、左上方的Tile,或是循环还未遍历到的右侧、下方Tile)还没被实例化,从数组里取到的自然是空引用——引用类型的“引用”必须指向已实例化的对象,没创建对象之前,数组对应的位置就是null。
解决方案
分两步处理,先创建所有Tile实例,再为每个Tile收集已存在的邻居:
private static Tile[,] GenerateGeneration(int rowLength, int colLength) { // 第一步:先初始化所有Tile实例,暂不设置邻居 Tile[,] newGeneration = new Tile[rowLength, colLength]; for (int row = 0; row < rowLength; row++) { for (int column = 0; column < colLength; column++) { newGeneration[row, column] = new Tile(new List<Tile>(), row, column); } } // 第二步:遍历每个Tile,收集并设置已存在的邻居 for (int row = 0; row < rowLength; row++) { for (int column = 0; column < colLength; column++) { List<Tile> neighbors = new() { newGeneration[row, CalculateIndexOverOrUnderflow(column - 1, colLength)], // 左 newGeneration[CalculateIndexOverOrUnderflow(row - 1, rowLength), CalculateIndexOverOrUnderflow(column - 1, colLength)], // 左上 newGeneration[CalculateIndexOverOrUnderflow(row - 1, rowLength), column], // 上 newGeneration[CalculateIndexOverOrUnderflow(row - 1, rowLength), CalculateIndexOverOrUnderflow(column + 1, colLength)], // 右上 newGeneration[row, CalculateIndexOverOrUnderflow(column + 1, colLength)], // 右 newGeneration[CalculateIndexOverOrUnderflow(row + 1, rowLength), CalculateIndexOverOrUnderflow(column + 1, colLength)], // 右下 newGeneration[CalculateIndexOverOrUnderflow(row + 1, rowLength), column], // 下 newGeneration[CalculateIndexOverOrUnderflow(row + 1, rowLength), CalculateIndexOverOrUnderflow(column - 1, colLength)] // 左下 }; // 假设Tile类提供修改邻居的属性或方法 newGeneration[row, column].Neighbors = neighbors; // 如果Tile构造后不允许修改字段,也可以重新实例化: // newGeneration[row, column] = new Tile(neighbors, row, column); } } return newGeneration; }
补充说明
- 如果你的
Tile类没有开放修改邻居的接口,第二步可以直接重新创建Tile实例,此时所有邻居都已存在,能拿到有效的引用。 - 你的
CalculateIndexOverOrUnderflow边界处理逻辑是没问题的,只要它能正确返回合法数组索引即可。
内容的提问来源于stack exchange,提问作者Schmo
相关产品推荐
相关产品推荐

