Карта для игры со змеей в C - PullRequest
0 голосов
/ 18 января 2019

Итак, я пытаюсь напечатать карту для моей игры со змеями. Вот код:

#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 */

Моя проблема в том, что при печати карты кажется, что многие пустые пространства печатаются внутри карты, поэтому правая граница не начинается, когда заканчивается верхняя или нижняя граница. Кроме того, что хвост змеи также смещен, только голова змеи, кажется, находится в правильном месте. Для лучшего понимания проблемы я поставлю здесь Консольный вывод

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Логика для печати доски в порядке .... но вызовет проблемы с масштабированием, если вы не будете осторожны с математикой / интервалом. Также у вас есть проблема печати змей. Мне пришлось запустить его пару раз, чтобы увидеть, что происходит. Я изменил это, чтобы использовать теорему Пифагора

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

В качестве напоминания укажите минимальный, полный и проверяемый пример

0 голосов
/ 18 января 2019

Я не совсем уверен, почему вы храните координаты для этого. Вы можете сделать это только с помощью списка (ей) змей и известного размера границы. Если вы хотите, вы можете «напечатать» в своем 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;
  }

Наличие этой карты поможет в будущем обнаруживать столкновения и убивать змей. В этом случае вы захотите напечатать границу только один раз и проверить, не был ли новый квадрат для змеи уже пуст - думаю, вы доберетесь до этого через несколько недель.

...