【问题标题】:Map for a snake video game in CC语言中的蛇视频游戏的地图
【发布时间】:2019-01-18 17:11:04
【问题描述】:

所以我正在尝试为我的蛇游戏打印地图。这是代码:

#define WIDTH 20
#define HEIGHT 20

struct coordinate {
    int x;
    int y;
};

typedef struct coordinate coordinate;
coordinate map[HEIGHT][WIDTH];

void init_map(){ // Function initializes the map with the corresponding coordinates
for(int i = 0; i < HEIGHT; i++){
    for(int j = 0; j < WIDTH; j++){
        map[i][j].y = i;
        map[i][j].x = j;
    }
  }
} /* init_map */

// Function initializes the first snake with the corresponding coordinates
void init_snake1(coordinate snake1[], int snake1_length){ 
  snake1[0].x = WIDTH/2;
  snake1[0].y = HEIGHT/2;
  snake1[1].x = snake1[0].x;
  snake1[1].y = snake1[0].y+1;
} /* init_snake1 */

void print_map(coordinate snake1[], int snake1_length){
  for(int i = 0; i < HEIGHT; i ++){
    for(int j = 0; j < WIDTH; j++){
      if(map[i][j].x == 0 && map[i][j].y == 0){
        printf("#");
      }else if(map[i][j].x == WIDTH-1 && map[i][j].y == HEIGHT-1){
       printf("#");
      }else if(map[i][j].y == 0 || map[i][j].y == HEIGHT-1){
        printf("#");
      }else if(map[i][j].x == 0 || map[i][j].x == WIDTH-1){
        printf("#");
      }else if(map[i][j].x > 0 && map[i][j].x < WIDTH-1 && map[i][j].y > 0 || map[i][j].y < HEIGHT-1){
        for(int k = 0; k < snake1_length; k++){
          if(map[i][j].x == snake1[k].x && map[i][j].y == snake1[k].y){
            printf("x");
          }else{
            printf(" ");
          }
        }
      }
    }
    printf("\n");
  }
}/* print_map */

我的问题是,当打印地图时,似乎在地图内打印了许多空格,因此当顶部或底部边框结束时,右边框不会开始。除了蛇尾也移动了,只有蛇头似乎在正确的位置。为了更好地理解我在这里提供的问题Console Output

【问题讨论】:

  • 您根本不需要map - 只需使用ij 计算出您要打印的y 和x 坐标。
  • 最后一个 if 语句看起来很可疑 - 你正在混合 ||&amp;&amp; 并且可能需要一些额外的括号(gcc 报告这是对我的警告)

标签: c for-loop output console-application


【解决方案1】:

我不确定您为什么要为此存储坐标。您可以只使用蛇列表和已知的边框大小来做到这一点。如果您愿意,您可以“打印”到您的二维数组中以便稍后进行碰撞检查,然后将该数组打印为字符串列表,但现在:

// These should be "int" types should be "bool", but am using old-school int values for old C standards

#define WIDTH 20
#define HEIGHT 20

struct coordinate {
  int x;
  int y;
};

typedef struct coordinate coordinate;

int isBorder(int x, int y)
{
    return x == 0 || x == WIDTH-1 || y == 0 || y == HEIGHT - 1;
}

int isSnake(int x, int y, coordinate snake[], int snake_length)
{
  for(int i = 0; i < snake_length; i++)
  {
    if(x == snake[i].x && y == snake[i].y)
    {
      return 1;
    }
  }

  return 0;
}

void print_map(coordinate snake1[], int snake1_length)
{
  for(int y = 0; y < HEIGHT; y++)
  {
    for(int x = 0; x < WIDTH; x++)
    {
      if(isBorder(x, y))
      {
        printf("#");
      }
      else if(isSnake(x, y, snake1, snake1_length))
      {
        printf("x");
      }
      else
      {
        printf(" ");
      }
    }

    printf("\n");
  }
}

int main(void) 
{
  coordinate snake1[2] = {{3,3},{3,4}};
  print_map(snake1, 2);
  return 0;
}

请注意,在工作中使用函数如何使其阅读起来更加清晰明了。这也使得将来添加更多蛇变得微不足道 - 只需更改 isSnake() 函数以获取更多数组。如果您绝对必须使用全局映射进行存储,则可以更改所有 printf() 值以打印到该数组。尽管让您的地图成为列表二维坐标数组,但我认为没有任何好处 - 它应该是类型。我想你可能误解了那部分的说明。

  int map[HEIGHT][WIDTH];

  if(isBorder(x, y))
  {
    map[y][x] = BorderType;
  }
  else if(isSnake(x, y, snake1, snake1_length))
  {
    map[y][x] = SnakeType;
  }
  else
  { 
    map[y][x] = EmptyType;
  }

拥有这张地图可以更轻松地进行未来的碰撞检测和杀死蛇。在这种情况下,您只需打印一次边框并检查蛇的新方块是否已经为空 - 我猜您将在几周内完成此操作。

【讨论】:

  • 除了最后一段代码,我都明白了。我不知道例如map[y[x] = BorderType; 做了什么。什么是“边框类型”?
  • 这些将是您编写的一些值 - 一个表示该位置存储内容的常量 - 比如说 BorderType = 1, SnakeType = 2; EmptyType = 0;
  • 额外的好处是上面的代码现在实际上是按原样工作的,所以你可以调试它,看看它是如何工作的。
  • 来自 swift 和 Objective-c 以及一些 node-js 背景以及我对直接 c 代码相当陌生。显然你有超凡的天赋,并且长期使用 c/c++ 和汇编。我的问题是,随着大型 c 应用程序开始扩展,是否值得进入并进行所有次要优化(例如循环展开、按位操作、更少的方法调用),或者它是否倾向于自然地发展成更高级别的概念。 (显然可以有堆/堆栈权衡)像你展示的类型。
  • 老实说,您首先为可维护性编写代码。编译器擅长将函数和小东西转化为局部优化。您调用的微优化往往只是最常调用的代码部分中的问题。使用分析器会指出这些。所以是的,如果正确完成,更高级别的概念是建立在小构建块上的,这些小块的性能在整体方案中很少重要,但是当它们这样做时,分析器会告诉你在哪里。
【解决方案2】:

打印电路板的逻辑没问题....但如果您不小心计算/间距,会导致缩放问题。你也有蛇打印问题。我不得不运行它几次才能看到发生了什么。我将其更改为使用pythagorean theorem

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define WIDTH 10
#define HEIGHT 10

struct coordinate {
     int x;
     int y;
};

typedef struct coordinate coordinate;

struct snake {
    coordinate head;
    coordinate tail;
};

typedef struct snake snake;

coordinate map[HEIGHT][WIDTH];  
int init_snake(snake *s, coordinate snake_head, coordinate snake_tail){
    //Add param error checking
    s->head = snake_head;
    s->tail = snake_tail;
    return 0;
} /* init_snake1 */

int print_map(snake *s){
    int snake_length;
    int head;
    int tail;

    if ((head = pow(s->head.x - s->tail.x, 2)) < 0) {
        perror("print_map(): pow():");
        return -1;
    }

    if ((tail = pow(s->head.y - s->tail.y, 2)) < 0) {
        perror("print_map(): pow():\n");
        return -1;
    }

    if ((snake_length = sqrt(head + tail)) < 0) {
        perror("print_map(): sqrt():\n");
        return -1;
    }

    for(int i = 0; i < HEIGHT; i++){
       for(int j = 0; j < WIDTH; j++){
           if(map[i][j].x == 0 && map[i][j].x < WIDTH){
               printf("#");
           } else if(map[i][j].y == 0 && map[i][j].y < HEIGHT){
               printf("#");
           } else if(map[i][j].x == HEIGHT - 1 && map[i][j].x > 0){
               printf("#");
           } else if(map[i][j].y == WIDTH - 1 && map[i][j].y > 0){
               printf("#");
           } else if (s->head.x == map[i][j].x && s->tail.x == map[i][j].x && snake_length > 0) {
               printf("x");
               snake_length -= 1;
           } else if (s->head.y == map[i][j].y && s->tail.y == map[i][j].y && snake_length > 0) {
               printf("x");
               snake_length -= 1;
            } else {
               printf(" ");
            }
            printf("\n");
         }
    return 0;
 }/* print_map */

int main(int argc, char **argv) {
    init_map();
    snake *s = malloc(sizeof(snake));;
    coordinate h;
    h.x = 3;
    h.y = 4;
    coordinate t;
    t.x = 7;
    t.y = 4;
    if ((init_snake(s, h, t)) == -1) {
            fprintf(stderr, "init_snake(): failed initialization'\n");
            free(s);
            s = NULL;
            exit(1);
    }
    print_map(s);
    free(s);
    s = NULL;
    return 0;
 }

提醒provide an Minimal, Complete, and Verifiable example

【讨论】:

  • 为什么要用二维数组来存储蛇,它应该是什么样子?您将如何在其中存储坐标?
  • 除此之外,蛇所在行的边界仍然向右移动。
  • 调整/对齐
猜你喜欢
  • 1970-01-01
  • 2014-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多