Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
#include <stdio.h>
#include <stdlib.h>


// Constants for the map characters
const char MAP_BORDER = '*';
const char PLAYER_CHAR = 'P';
const char GOAL_CHAR = 'G';
const char COLLAPSED_CHAR = 'X';
const char EMPTY_CHAR = ' ';

int main(int argc, char *argv[]) {
    // Check if the correct number of arguments was provided
    if (argc != 7) {
        printf("Error: Invalid number of arguments\n");
        return 1;
    }

    // Convert the arguments to integers and check for invalid values
    int row_map = atoi(argv[1]);
    int col_map = atoi(argv[2]);
    int row_player = atoi(argv[3]);
    int col_player = atoi(argv[4]);
    int row_goal = atoi(argv[5]);
    int col_goal = atoi(argv[6]);

    if (row_map < 5 || col_map < 5 ||
        row_player < 1 || col_player < 1 || row_goal < 1 || col_goal < 1 ||
        row_player > row_map - 2 || col_player > col_map - 2 ||
        row_goal > row_map - 2 || col_goal > col_map - 2) {
        printf("Error: Invalid argument values\n");
        return 1;
    }

    // Allocate memory for the 2D array
    int **map = malloc(row_map * sizeof(int *));
    for (int i = 0; i < row_map; i++) {
        map[i] = malloc(col_map * sizeof(int));
    }

    // Initialize the map with empty spaces
    for (int i = 0; i < row_map; i++) {
        for (int j = 0; j < col_map; j++) {
            map[i][j] = 0;
        }
    }

    // Set the borders of the map
    for (int i = 0; i < col_map; i++) {
        map[0][i] = 1;
        map[row_map - 1][i] = 1;
    }
    for (int i = 1; i < row_map - 1; i++) {
        map[i][0] = 1;
        map[i][col_map - 1] = 1;
    }

    // Set the player and goal locations in the map
    map[row_player][col_player] = 2;
    map[row_goal][col_goal] = 3;

    // Print the initial map
    system("clear"); // clear the terminal screen
    for (int i = 0; i < row_map; i++) {
        for (int j = 0; j < col_map; j++) {
            if (map[i][j] == 1) {
                printf("%c", MAP_BORDER);
            } else if (map[i][j] == 2) {
                printf("%c", PLAYER_CHAR);
            } else if (map[i][j] == 3) {
                printf("%c", GOAL_CHAR);
            } else if (map[i][j] == 4) {
                printf("%c", COLLAPSED_CHAR);
            } else {
                printf("%c", EMPTY_CHAR);
            }
        }
        printf("\n");
    }

    // Wait for user input and move the player accordingly
    char input;
    while (1) {
        scanf(" %c", &input);

        // Move the player based on the input
        int new_row_player = row_player;
        int new_col_player = col_player;
        if (input == 'w') {
            new_row_player--;
        } else if (input == 'a') {
            new_col_player--;
        } else if (input == 's') {
            new_row_player++;
    } else if (input == 'd') {
        new_col_player++;
    } else {
        printf("Error: Invalid input\n");
        continue;
    }

    // Check if the new player location is valid
    if (new_row_player < 1 || new_row_player > row_map - 2 ||
        new_col_player < 1 || new_col_player > col_map - 2 ||
        map[new_row_player][new_col_player] == 1) {
        printf("Invalid move\n");
        continue;
    }

    // Update the player location in the map
    map[row_player][col_player] = 0;
    if (map[new_row_player][new_col_player] == 3) {
        // Player reached the goal
        printf("Congratulations, you reached the goal!\n");
        break;
    } else {
        map[new_row_player][new_col_player] = 2;
    }

    // Update the player coordinates
    row_player = new_row_player;
    col_player = new_col_player;

    // Print the updated map
    system("clear"); // clear the terminal screen
    for (int i = 0; i < row_map; i++) {
        for (int j = 0; j < col_map; j++) {
            if (map[i][j] == 1) {
                printf("%c", MAP_BORDER);
            } else if (map[i][j] == 2) {
                printf("%c", PLAYER_CHAR);
            } else if (map[i][j] == 3) {
                printf("%c", GOAL_CHAR);
            } else if (map[i][j] == 4) {
                printf("%c", COLLAPSED_CHAR);
            } else {
                printf("%c", EMPTY_CHAR);
            }
        }
        printf("\n");
    }
}

// Free the memory allocated for the map
for (int i = 0; i < row_map; i++) {
    free(map[i]);
}
free(map);

return 0;
}


What I have tried:

So what I wanted to happen was make one of the empty floor grids to "collapse" every time the player moved. But the collapse had to happen in a way that a single empty grid would collapse and be represented as an "X" on the game terminal. It needed to work in a way that the floor grid would collapse in a new position every time. Not where the player is, where the goal is, or where a a collapsed floor already exists.

void move_player(char board[][SIZE], int *player_row, int *player_col, int move_row, int move_col) {
    int new_row = *player_row + move_row;
    int new_col = *player_col + move_col;

    if (new_row < 0 || new_row >= SIZE || new_col < 0 || new_col >= SIZE) {
        printf("Invalid move\n");
        return;
    }

    if (board[new_row][new_col] == EMPTY) {
        // Check if the empty space can collapse
        if (board[new_row][new_col] != COLLAPSED && (new_row != *player_row || new_col != *player_col) && (new_row != GOAL_ROW || new_col != GOAL_COL)) {
            printf("A grid collapses!\n");
            board[new_row][new_col] = COLLAPSED;
        }
        else {
            printf("Invalid move\n");
            return;
        }
    }

    if (new_row == GOAL_ROW && new_col == GOAL_COL) {
        printf("Congratulations! You have reached the goal.\n");
        exit(0);
    }

    board[*player_row][*player_col] = EMPTY;
    board[new_row][new_col] = PLAYER;
    *player_row = new_row;
    *player_col = new_col;
}


I wrote this function and tried importing it to the main file but I would keep getting an unknown type name error. The unknown name type error is for "import collapse" where collapse.c is the name of the secondary file that I wanted to import into the main file.
Posted
Updated 24-Feb-23 11:34am
v2
Comments
Rick York 24-Feb-23 10:32am    
Every compiler of any worth will tell you the line number where the error is. Do you expect us to guess where it is?

The definition of the grid does not match at first sight:
C
int** map
char board[][SIZE]

Since both row and col are specified by the user at startup, the constant SIZE will not work well either.
C
int row_map = atoi(argv[1]);
int col_map = atoi(argv[2]);

Further constants like EMPTY, COLLAPSED, GOAL_ROW, GOAL_COL as well as PLAYER are not defined.

If you don't use C++ you could at least improve the handling of the grid by collecting all parameters needed for it in a structure.

For example:
C
typedef struct {
  int rows, cols;
  int** map;
} Grid;

And then use it like this:
C
Grid mygrid;
mygrid.rows = row_map;
mygrid.cols = col_map;
mygrid.map = malloc(mygrid.rows  * sizeof(*mygrid.map));
....


//void move_player(char board[][SIZE], int* player_row, int* player_col, int move_row, int move_col)
BOOL move_player(Grid* board, Point* player, Point* move)
{
    int new_row = player->row + move->row;
    int new_col = player->col + move->col;

    if (new_row < 0 || new_row >= board->rows || new_col < 0 || new_col >= board->cols) {
        printf("Invalid move\n");
        return FALSE;
    }

    if (board->map[new_row][new_col] != EMPTY) {
        printf("Invalid move\n");
        return FALSE;
    }

    // ....
}

With e.g. this definitions
C
typedef struct { int row, col; } Point;
typedef enum { FALSE, TRUE } BOOL;
typedef enum {NONE, EMPTY, GOAL, P1, P2} gidstate;
 
Share this answer
 
v2
Your error description isn't helpful: we have no idea where the error is. If I had to guess, I'd say that from the indentation you have ended the main method too early - immediately above the for loop freeing up the memory.

You should expect to get syntax errors every day, probably many times a day while you are coding - we all do regardless of how much experience we have! Sometimes, we misspell a variable, or a keyword; sometimes we forget to close a string or a code block. Sometimes the cat walks over your keyboard and types something really weird. Sometimes we just forget how many parameters a method call needs.

We all make mistakes.

And because we all do it, we all have to fix syntax errors - and it's a lot quicker to learn how and fix them yourself than to wait for someone else to fix them for you! So invest a little time in learning how to read error messages, and how to interpret your code as written in the light of what the compiler is telling you is wrong - it really is trying to be helpful!

So read this: How to Write Code to Solve a Problem, A Beginner's Guide Part 2: Syntax Errors[^] - it should help you locate the error and hopefully the reason for it. And if it doesn't do that it will at least tell you what information we need!
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900