【解決方法】グリッドベースのゲームでプレーヤーが道路を通過するときに道路が消えるのを防ぐにはどうすればよいですか? – Cプログラミング

プログラミングQA

[ad_1]

私は現在、C でグリッドベースのゲームに取り組んでいます。道路はドット (「.」) で表され、プレーヤーは「P」で表されます。 プレーヤーの目標は、目的地 (「G」) に到達することです。 ただし、プレイヤーが道路を移動するときに道路を表示し続けるという課題に直面しています。

問題の説明:

グリッドは道路と境界線で初期化されますが、プレーヤーが道路の上を移動すると道路は消えます。
movePlayer 関数でプレーヤーの移動中に道路セルを保持しようとしましたが、それでも道路は消えてしまいます。

#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>
#include "traffic.h"

void initializeGame(char **grid, int rows, int cols) {
    int i, j;  /* Declare loop control variables */
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if (i == 0 || i == rows - 1 || j == 0 || j == cols - 1) {
                grid[i][j] = '*'; /* Set border cells to "*" */
            } else if ((i % 2 == 0) && (j > 0 && j < cols - 1)) {
                grid[i][j] = '.'; /* Set road cells to "." on even rows */
            } else {
                grid[i][j] = ' '; /* Set other cells inside borders to empty */
            }
        }
    }

    /* Place the player at the top-left corner and the goal at the bottom-right corner */
    grid[1][1] = 'P';
    grid[rows - 2][cols - 2] = 'G';
}


/* Function to display the game grid with borders */
void displayGame(char **grid, int rows, int cols, int prevPlayerRow, int prevPlayerCol) {
    int i, j;  /* Declare loop control variables */
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            /* Move the cursor to the current cell */
            move(i, j);

            /* Print the content of the grid */
            printw("%c", grid[i][j]);
        }
    }

    mvprintw(rows, 0, "Press 'w' to move up");
    mvprintw(rows + 1, 0, "Press 'a' to move left");
    mvprintw(rows + 2, 0, "Press 's' to move down");
    mvprintw(rows + 3, 0, "Press 'd' to move right");

    refresh(); /* Refresh the screen using ncurses */
}

void movePlayer(char **grid, int rows, int cols, int move, int *win, int *prevPlayerRow, int *prevPlayerCol) {
    int i, j, playerRow, playerCol;  /* Declare loop control variables */

    /* Find the current position of the player */
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            if (grid[i][j] == 'P') {
                playerRow = i;
                playerCol = j;
            }
        }
    }

    /* Clear the player's previous position */
    grid[*prevPlayerRow][*prevPlayerCol] = ' ';

    /* Move the player based on the user's input */
    switch (move) {
        case 'w':
            if (playerRow > 1) {
                playerRow--;
            }
            break;
        case 'a':
            if (playerCol > 1) {
                playerCol--;
            }
            break;
        case 's':
            if (playerRow < rows - 2) {
                playerRow++;
            }
            break;
        case 'd':
            if (playerCol < cols - 2) {
                playerCol++;
            }
            break;
        default:
            /* Invalid move */
            break;
    }

    /* Set the player's new position */
    grid[playerRow][playerCol] = 'P';

    /* Update the previous player position */
    *prevPlayerRow = playerRow;
    *prevPlayerCol = playerCol;

    /* Check if the player reached the goal */
    if (playerRow == rows - 2 && playerCol == cols - 2) {
        *win = 1; /* Set win flag to 1 */
    }
}



/* Main function, entry point of the program */
int main(int argc, char *argv[]) {
    /* Check the number of command-line arguments */
    if (argc != 3) {
        printf("Usage: %s <map_row> <map_col>\n", argv[0]);
        return 1;
    }

    /* Parse command-line arguments */
    int mapRows = atoi(argv[1]);
    int mapCols = atoi(argv[2]);

    /* Check for valid map size */
    if (mapRows < 3 || mapRows % 2 == 0 || mapCols < 5) {
        printf("Invalid map size. Please ensure <map_row> is an odd number >= 3 and <map_col> is >= 5.\n");
        return 1;
    }

    /* Dynamically allocate memory for the 2D char array */
    char **gameGrid = (char **)malloc(mapRows * sizeof(char *));
    int i;  /* Declare loop control variable */
    for (i = 0; i < mapRows; i++) {
        gameGrid[i] = (char *)malloc(mapCols * sizeof(char));
    }

    /* Initialize the game grid with "*" and place the player and goal inside borders */
    initializeGame(gameGrid, mapRows, mapCols);

    initscr(); /* Initialize ncurses */

    timeout(0); /* Set non-blocking input */

    char move;
    int win = 0; /* Win flag */
    int prevPlayerRow = 1; /* Initialize with player's initial row */
    int prevPlayerCol = 1; /* Initialize with player's initial column */

    do {
        /* Display the updated game grid with borders */
        displayGame(gameGrid, mapRows, mapCols, prevPlayerRow, prevPlayerCol);

        /* Get user input for player movement */
        move = getch(); /* Get the key without waiting for 'Enter' */

        /* Move the player based on user input */
        movePlayer(gameGrid, mapRows, mapCols, move, &win, &prevPlayerRow, &prevPlayerCol);

        /* Check if the player has won */
        if (win) {
            clear(); /* Clear the screen */
            printw("Congratulations! You have cleared the level.\n");
            printw("Press any key to exit.\n");
            refresh(); /* Refresh the screen to display the message */
            getch(); /* Wait for a key press before ending the program */
        }

    } while (move != 'q' && !win); /* Loop until the user enters 'q' or wins */

    endwin(); /* End ncurses */

    /* Free the dynamically allocated memory */
    for (i = 0; i < mapRows; i++) {
        free(gameGrid[i]);
    }
    free(gameGrid);
    

    return 0; /* Properly reach the end of the main function */
}

私が試したこと:

movePlayer 関数を見直して、プレーヤー中に道路セルが変更されないようにしました。
道路セルとプレイヤーの移動のロジックを分離しようとしましたが、依然として道路が消える問題に直面しています。

解決策 1

というグローバル変数を作成します。 lastSurfaceType それを「道路」に初期化します。
プレイヤーを移動するときは、プレイヤーがいるマス目を設定します。 lastSurfaceType 移動を行う前に、プレーヤーが移動しようとしているタイプに変数を設定します。

そうすれば、次回プレーヤーを移動するときに、移動しようとしている「P」を置き換える適切なサーフェス タイプが用意されます。

解決策 2

引用:

グリッドベースのゲームでプレーヤーが道路を通過するときに道路が消えるのを防ぐにはどうすればよいですか? – Cプログラミング

交換する

C++
/* Clear the player's previous position */
grid[*prevPlayerRow][*prevPlayerCol] = ' ';

C++
/* Clear the player's previous position */
grid[*prevPlayerRow][*prevPlayerCol] = '.';

プレイヤーをセルから削除するときは、セルを空にするのではなく、道路にします。

[ad_2]

コメント

タイトルとURLをコピーしました