Closed. This question is off-topic。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
                        
                        5年前关闭。
                                                                                            
                
        
我开始学习C,并且尝试制作帐篷和树木游戏,我正在用一些矩阵(4x4,5x5,6x6,7x7)进行关卡设计,例如数字8代表一棵树,一个数字4代表一个帐篷,一个数字0代表一个空白,但是我正尝试通过随机树(8)的位置进行关卡,以使游戏每次打开时都与众不同。

http://www.brainbashers.com/tentshelp.asp
我需要有关如何为树木建立验证系统的提示,一棵树已分配了一个帐篷,但是我对如何使其工作感到困惑,我的意思是树木(8)的数字是由随机生成的位置,并且所有树木(8)的编号都需要一个帐篷(4)的编号,但是这些帐篷永远不能彼此相邻(垂直,水平或对角线),并且它们始终水平或垂直于一棵树,这就是我为生成的树设置帐篷时感到困惑的部分。

希望你们明白我的意思,我真的是在努力学习,所以我只需要提示,请提前谢谢您。

最佳答案

以下是一些随机的想法,可能会帮助您安排事情:


在C / C ++中,二维数组实际上是一维结构(一块连续的内存)。在C和C ++中,二维数组以行优先形式存储,这意味着我们将整个第一行存储在内存中,然后将整个第二行存储在内存中,依此类推。例如,如果我们有以下内容
二维阵列

   0  1  2 <--- columns
0  a  b  c
1  d  e  f
2  g  h  i
^
+-- rows



它会在内存中表示(假设我们使用char作为基础数据类型)为:

    +---+---+---+---+---+---+---+---+---+
    | a | b | c | d | e | f | g | h | i |
    +---+---+---+---+---+---+---+---+---+


这种安排很有用,因为我们可以轻松地在一维存储阵列中的索引与二维数组的概念之间进行转换。在以下等式中,R代表二维数组中的最大行数(在此示例中为3),C代表二维数组中的最大列数(在本示例中为3)。最后一点,我们对行和列使用零基。因此,元素“ a”位于第0行第0行,在后面的行中缩写为[0,0]。

因此,如果我们对[r,c]中的内容感兴趣,则需要通过以下方法生成索引n:

    n = r * C + c


例如,如果我们对[1,1]感兴趣,我们将计算:

    n = 1 * 3 + 1 = 4


换句话说,[1,1]处的元素位于第四个索引处(再次记住数组是从零开始的)。

我们也可以通过使用索引将索引n隐式转换为行列符号。

    r = n / C  and c = n % C


例如,第六个存储位置(索引= 5)的元素为

    r = 5 / 3  and c = 5 % 3  or [1,2]



树的放置是相当简单的,因为如果我们正在使用anxn数组,那么我们知道索引从[0,n $ ^ 2 $ -1]开始运行,因此我们只需生成该范围内的随机数即可,不要两次使用相同的号码。一些伪代码可能用于排列t树:

 // assume that our game board is in a data-structure called `world'
 len <-   n*n;                   // maximum number in our range
 trees <- t;                     // number of trees to place
 do
     ndx <- rand() % len         // generate random number in range [0,len-1]
     if ( world[ndx] == 0)       // picked an empty space
         world[ndx] = 8;         // plant a tree
         trees -= 1;             // decrement tree's remaining
 while (trees > 0);

在哪里放置帐篷也很容易。考虑到二维数组与内存模型之间的关系,如果一棵树位于给定索引ndx处,则可能的帐篷位置列表为:

   L = ndx - 1;             // this is due left of the tree
   R = ndx + 1;             // this is due right of the tree
   B = ndx + C;             // this is below the tree
   A = ndx - C;             // this is above the tree



当然,我们必须确保我们没有离开世界。我个人将这些存储在一个数组中,而不是四个变量中。


帐篷约束实际上只是说明八个相邻单元中的任何一个都没有帐篷。考虑下图,其中在单元格中有一个T标记的帐篷。如果该单元格的索引为n,则周围的单元格将显示我们需要检查的索引。

        +---+---------+-----+----------+---+
        |   |         |     |          |   |
        +---+---------+-----+----------+---+
        |   | n-C - 1 | n-C | n-C + 1  |   |
        +---+---------+-----+----------+---+
        |   | n-1     | T   | n +1     |   |
        +---+---------+-----+----------+---+
        |   | n+C -1  | n+C | n+C +1   |   |
        +---+---------+-----+----------+---+

让我们把3和4放在一起。我们首先创建一个函数placeTents,该函数采用树放置位置的索引数组。这是一个简单的函数,它会按照{top,left,right,bottom}的顺序创建一个潜在树位置数组,如果这些位置中的任何一个超出范围,我们就在数组中设置一个负数。最后,我们尝试为
函数placeTent(P)中的帐篷;如果placeTent失败,我们将无法满足约束条件,并且根据您的问题描述,目前尚不清楚您要执行的操作,在此讨论中,我只是指出程序已退出

placeTents(trees):
    max <- R * C -1               // max index
    for each tree in trees
        if (tree - C) > 0 then P[0] = tree - C else P[0] = -1;
        if (tree - 1) > 0 then P[1] = tree - 1 else P[1] = -1;
        if (tree + 1) < max then P[2] = tree + 1 else P[2] = -1;
        if (tree + C) < max then P[3] = tree + C else P[3] = -1;
        if (!placeTent(P))
             exitError;



对于placeTent,我们需要检查所有八个邻居(可能不存在),为简单起见,我们仅在第一个可用位置放置一个帐篷。再次记住,placeTent接受可能放置帐篷的列表,然后检查每个位置的可行性。同样,我们假设游戏板位于名为world的数组中

     bool placeTent(P)
         ret <- false;
         max <- R * C - 1;
         for each loc in P
             if loc == -1 continue;
             // calculate indexes we want to look at....
             trial[0] <- loc - Col - 1;
             trial[1] <- loc - Col;
                   .....
             trial[6] <- loc + Col;
             trial[7] <- loc + Col + 1;
             for each t in trial
                 if ((t < 0) || (t > max)) continue; // we fell of the world.....splat!
                 if (world[t] == 0)
                     world[t] = 4;
                     return true;
         return false;                               // failed to find a place to pitch our tent


最后,真正的挑战是找到一个可行的帐篷位置,为此,我希望进行递归操作,以便当我找不到可行的位置时,我们可以放松这些位置并尝试其他方法。

并看到它旋转的长度....对不起,可能是乱七八糟的,太多了。...我将把递归部分留给以后。

编辑/添加:

我忘了提及的另一件事是,上述内容是确定性的,即我们允许尝试将帐篷放在树上,然后逆时针移动。在某些时候,人们会发现这一点,因此您可能希望随机检查位置(即,在P数组上为每棵树创建一个排列)。

09-25 22:09