0

我是 c 新手,正在尝试创建扫雷游戏。我认为我的代码在数据类型转换方面存在一些问题,但我不明白为什么。检查了这个链接

如何在 C 中将 unsigned int 转换或转换为 int?

并尝试在我的代码中实现信息。

我正在尝试实现一个函数,该函数返回具有地雷的 ax,y 协调二维数组的相邻位置的数量。

int neighbours(const Field *f, unsigned int x, unsigned int y)
{
    int z = 0;
    int i,j;
    unsigned int a = y-1;
    j =(int)a;
    unsigned int b =x-1;
    i = (int)b;

    for(; j<=(a+2); j++){
        if(j>=0 && j<=f->ysize){
            for (; i<=(b+2); i++){
                if ( i>=0 && i<=f->xsize && (f->places[j][i] == UNKNOWN_MINE ||f->places[j][i] == KNOWN_MINE)){
                    z++;
                 }

             }
            i = b;
        }  
    }
    return z;
 }
4

1 回答 1

0

编码

unsigned a = y-1;

如果 y == 0,给你一个 == UINT_MAX

条件

  j >= 0

只是说“如果这个非负整数不是负数”,所以不是很有帮助。

一个好主意是使用一些填充来存储数据,其中矩形映射在每一侧填充一个宽度的整数,所有这些都有一个唯一的值,你可以称之为 PADDING_FIELD

这样你的功能会更简单,更有效:

int neighbours(const Field *f, unsigned int x, unsigned int y)
{
  int z = 0;

  assert(x > 0 && x < UINT_MAX);
  assert(y > 0 && y < UINT_MAX);

  for(unsigned int j = y-1; j <= y+1); j++) {
        for (unsigned int i = x-1; i <= x+1; i++) {
            if ((f->places[j][i] == UNKNOWN_MINE ||f->places[j][i] == KNOWN_MINE)){
                z++;
            }
        }
  }
  return z;
}

这样您就不需要检查是否超出范围,如果您要解决外部问题,您只会得到 f->places[j][i] == PADDING_FIELD ,它不匹配任何内容。类型转换也没有问题,您知道 x 或 y 不能为零或 UINT_MAX。

编辑

如果您仔细选择 UKNOWN_MINE 和 KNOWN_MINE 的值,您还可以消除小循环中的一项检查。可以做类似的事情:

    static const field mine = 4;
    static const field known = 8;

    inline bool is_mine(field f)
    {
            return (f & mine) != 0;
    }

    inline bool is_knownmine(field f)
    {
            return (f & mine & known) != 0;
    }

    inline bool is_unknownmine(field f)
    {
            return is_mine(f) && !is_knownmine(f);
    }

    int neighbors(....)
    {
     .....
      if (is_mine(f->places[j][i]) {
          ++z;
      }
     .....
    }
于 2014-03-22T14:11:13.243 回答