【问题标题】:Trying to make a Tents and Trees game in C [closed]尝试在 C 中制作帐篷和树木游戏 [关闭]
【发布时间】:2014-12-07 05:03:15
【问题描述】:

我开始学习 C 并且我正在尝试制作一个帐篷和树木游戏,我正在使用一些矩阵 (4x4,5x5,6x6,7x7) 进行关卡设计,例如,数字 8 代表一棵树,数字 4 代表一顶帐篷,数字 0 是一个空白区域,但是我试图通过随机树 (8) 位置来制作关卡,以使每次打开游戏时都不同。

http://www.brainbashers.com/tentshelp.asp

我需要关于你们如何为树木制作验证系统的提示,一棵树分配了一个帐篷,但我对如何使其工作感到困惑,我的意思是创建了树木 (8) 个数字通过矩阵上的随机位置,所有的树 (8) 数字都需要一个帐篷 (4) 数字,但帐篷不能永远彼此相邻(垂直、水平或对角线),它们总是水平或垂直靠近一棵树,这就是我为生成的树设置帐篷而感到困惑的部分。

希望你们明白我的意思,我真的在努力学习,所以我只需要提示请提前谢谢你们,祝你有美好的一天。

【问题讨论】:

  • 你已经有什么代码了?如果您还没有任何实际代码,也许有一些关于如何尝试解决问题的伪代码?

标签: c algorithm tree


【解决方案1】:

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

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

       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,via;

    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]
  1. 树的放置相当简单,如果我们使用 n x n 数组,那么我们知道我们的索引从 [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);
    
  2. 在哪里放置帐篷也很容易。考虑二维数组与内存模型之间的关系,如果一棵树位于给定索引 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
    

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

  1. 帐篷限制实际上只是说明八个相邻单元中的任何一个都不能有帐篷。考虑下图,我们在单元格中用 T 标记了一个帐篷。如果这个单元格的索引是 n,那么周围的单元格显示我们需要检查的索引。

            +---+---------+-----+----------+---+
            |   |         |     |          |   |
            +---+---------+-----+----------+---+
            |   | n-C - 1 | n-C | n-C + 1  |   |
            +---+---------+-----+----------+---+
            |   | n-1     | T   | n +1     |   |
            +---+---------+-----+----------+---+
            |   | n+C -1  | n+C | n+C +1   |   |
            +---+---------+-----+----------+---+
    
  2. 让我们把 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 数组上为每棵树创建一个排列。)

【讨论】:

  • 哇老兄,谢谢!这真的帮助了我!我已经完成了哈哈谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
  • 2011-08-06
相关资源
最近更新 更多