【问题标题】:Unity - C#: How to fill up a 2D array with a spread of 1's or 0'sUnity - C#:如何用 1 或 0 的分布填充二维数组
【发布时间】:2017-09-30 05:28:27
【问题描述】:

我正在统一构建一个游戏,该游戏(理论上)通过使用 2D 布尔元素数组来工作,然后对其进行处理以确定游戏中该空间是否应该有块,但是我在使用时遇到问题统一实际创建所述数组。目前我的代码是:

void Start () {
    System.Random rnd = new System.Random ();
    int MapCol = 9;
    int MapRow = 9;
    int [,] MapArray = new int [MapCol, MapRow];
    foreach (int i in MapArray)
        MapArray ["{0} ", i] = rnd.Next (0, 2);
    }

之所以出现我的问题,是因为微软官方对这个问题的回答只解释了如何在二维数组上使用 foreach 来查看单个文本元素,而不是整数。

我还尝试将指南推送到后期生成的地图上,这似乎不起作用,因为可能会生成不符合这些指南的无限地图,并且地图可能永远不会完成。目前这些准则是一个块必须接触两个相邻的块,一个块不能接触同一个角落的三个块,即

  • 1 1 0
  • 1 1 0 不允许此展示位置
  • 0 0 0

同时

  • 0 1 0
  • 1 1 1 允许此展示位置。
  • 0 0 0

我们将不胜感激!

编辑: 所以,要进一步说明生成条件。我希望每个“1”都接触到另外两个 1 的最小值,这里考虑的接触是在 4 个基本方向上,上、下、左和右。与另一个 1 的对角线接触很好,除非该对角线被另外 2 个“1”包围。因此,不应将 4 个块组合在一起的安排。所以模式:

1 1
1 1

不应出现在网格内

【问题讨论】:

  • @ChuckSavage 您永远不应该假设未定义的变量将“默认为”。这不是好的编程习惯,而且在速度上节省的时间可能不值得冒险。
  • 另外,Unity3d 提供了一个 Random 类。使用Random.Range(0,N)
  • @8protons C# Programming Guide The default values of numeric array elements are set to zero, and reference elements are set to null.
  • @Kevin hamill,您希望代码为给定的二维数组大小生成一个单一的解决方案还是所有可能的解决方案?
  • @Mukesh Saini 只有一个随机解决方案,但所有解决方案都是一个非常有趣的概念。两者都会很高兴知道,但我现在正在寻找一个单一的解决方案

标签: c# unity3d multidimensional-array


【解决方案1】:

在处理多维数组时,最好坚持使用嵌套的for 循环,如下所示:

for (int i = 0; i < MapArray.GetLength(0); i++) {
    for (int j = 0; j < MapArray.GetLength(1); j++) {
        MapArray[i, j] = rnd.Next(0, 2);
    }           
}

关于你的第二个问题,你能详细说明一下条件吗?完全没看懂。

【讨论】:

  • 谢谢!我添加了对条件的简短说明,如果现在更有意义,请随时尝试满足它们!
【解决方案2】:

这是满足准则并根据提供的种子生成一种可能的解决方案的算法 -

// 2D array Map
var blocks = [];
// size of 2D array Map
var sizeX = 9,
    sizeY = 9;
// seed - as a starting point in 2d array within range of array size-1. eg. (2,1) , (5,5)
var seedX = 8,
    seedY = 8;
// used to hold 2D array elements to be processed
var processX = [];
var processY = [];
// string used for output
var str = "";

// initialize 2D array with value 2 and set seed to block as 1
function initializeMap() {
    for (var row = 0; row < sizeX; row++) {
        blocks[row] = [];
        for (var col = 0; col < sizeY; col++) {
            blocks[row][col] = 2;
        }
    }
    blocks[seedX][seedY] = 1;
}

// print the 2D array map with guidelines
function printMap() {
    str = "1. Every 1 is surrounded by atleast two 1s.<br/>";
    str += "2. No 1 is surrounded by three 1s in the same corner.<br/><br/>";
    for (var row = 0; row < sizeX; row++) {
        for (var col = 0; col < sizeY; col++) {
            str += blocks[row][col] + " ";
        }
        str += "\n<br/>";
    }
    document.getElementById("result").innerHTML = str;
}

// Add current element's unprocessed siblings to processing stack and set its value to -1
function pushSiblingsToProcess(x, y) {
    for (var row = x - 1; row <= x + 1; row++) {
        if (row >= 0 && row < sizeY) {
            for (var col = y - 1; col <= y + 1; col++) {
                if (col >= 0 && col < sizeX && blocks[row][col] > 1) {
                    processX.push(row);
                    processY.push(col);
                    blocks[row][col] = -1;
                }
            }
        }
    }
}

// sets the current element to make is either block as 1 or empty as 0
function setBlock(x, y) {
    var totalAdj = 0;
    var prev = false;
    if ((x - 1) >= 0 && blocks[x - 1][y] == 1) {
        totalAdj += 1;
        prev = true;
    }
    if ((y - 1) >= 0 && blocks[x][y - 1] == 1) {
        totalAdj += 1;
        if (prev && (x - 1) >= 0 && blocks[x - 1][y - 1] == 1) {
            blocks[x][y] = 0;
            return;
        }
        prev = true;
    } else {
        prev = false;
    }
    if ((x + 1) < sizeX && blocks[x + 1][y] == 1) {
        totalAdj += 1;
        if (prev && (y - 1) >= 0 && blocks[x + 1][y - 1] == 1) {
            blocks[x][y] = 0;
            return;
        }
        prev = true;
    } else {
        prev = false;
    }
    if ((y + 1) < sizeY && blocks[x][y + 1] == 1) {
        totalAdj += 1;
        if (prev && (x + 1) <= sizeX && blocks[x + 1][y + 1] == 1) {
            blocks[x][y] = 0;
            return;
        }
        prev = true;
    } else {
        prev = false;
    }
    if (prev && (x - 1) >= 0 && (y + 1) < sizeY && blocks[x - 1][y + 1] == 1 && blocks[x - 1][y] == 1) {
        blocks[x][y] = 0;
        return;
    }
    blocks[x][y] = 1;
}

// called recursively to set blocks until processing stack has elements to process
function generateMap() {
    if (processX.length <= 0) {
        return;
    } else {
        var currX = processX.pop();
        var currY = processY.pop();
        setBlock(currX, currY);
        pushSiblingsToProcess(currX, currY);
        generateMap();
    }
}

initializeMap();
pushSiblingsToProcess(seedX, seedY);
generateMap();
printMap();

Working JSFiddle

【讨论】:

  • 所以,一旦我阅读了更多内容并且有更多需要澄清的事情,我可能会稍后再次发表评论,但首先;我假设随机化seedX和seedY会使它得到不同的值,而现在它总是给我相同的值?
  • 在 JSFiddle 中,您可以更改 seedX 和 seedY 值,它将通过将该种子块创建为 1 来启动该过程,并为您提供不同的解决方案。 :)
  • 是的,随机化种子会给你不同的结果。
  • 好的,这太棒了!感谢您抽出宝贵时间,但我注意到有些种子不符合准则。在使用 3、3 作为种子块的 9*9 网格上,出现不接触两个相邻块(特别是右下角的块)的种子块,并且有一个指向该块的链接也不会打印种子会很方便,即使我绝对可以自己摆脱打印。
  • 当种子为 (3,3) 时,右下角块的左上角和左上角有 1。 Fiddle
猜你喜欢
  • 2016-03-11
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 2016-02-22
  • 2014-12-23
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多