映射C中的蛇电子游戏

时间:2019-01-18 17:11:05

标签: c for-loop output console-application

因此,我正在尝试为蛇游戏打印地图。这是代码:

#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

2 个答案:

答案 0 :(得分:1)

我不太确定为什么要为此存储坐标。您可以仅使用蛇形列表和已知的边框大小来执行此操作。如果需要,您可以“打印”到2D数组中以便以后进行碰撞检查,只是将数组打印为字符串列表,但是现在:

// 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;
  }

拥有此地图将使以后进行碰撞检测和杀死蛇更容易。在这种情况下,您只需要打印一次边框,并检查蛇的新方块是否已经空了-我猜您将在几周内达到目的。

答案 1 :(得分:0)

The logic for printing a board is ok.... but will cause scaling issues if you arent careful with the math/spacing. Also you have a snake printing problem. I had to run it a couple times to see what was happening. I altered it to use the 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;
 }

As a reminder provide an Minimal, Complete, and Verifiable example