我有一个在 C 代码上运行的贪吃蛇游戏,我想看看是否有办法让它在不同的编译器上更易于访问

问题描述 投票:0回答:0

对于一个班级项目,我的小组制作了一个在 C 代码上运行的贪吃蛇游戏,但它使用了非标准的库。除了我正在使用的 Code::Blocks 之外,还有什么方法可以让游戏在更多平台上运行吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <conio.h>
#include <ctype.h>

void setup();       //Initialized all the functions
void draw();
void input();
void updateGame();
void logic();
void clearScreen();
void gotoxy(int x, int y);
void newHighscore();

int gameover = 0;       //Initialized all the variables
int x, y;
int fruitx, fruity;
int score;
int height, width;
char mode[10];
int snakeLength = 1;
int* snakeBody;
int dx = 0;
int dy = 0;
int highScore;

void setup() {  // Setup Function used to get Map Size and snake head location
    printf("Enter Map Size (Small, Medium, Large): ");
    scanf("%s", mode);
    for (int i = 0; i < 10; i++){
    mode[i] = tolower(mode[i]);  //tolower makes all the inputs scanned into lower case so any input, "LARGE", or "large" will work
    }
    if (strcmp(mode, "small") == 0) {
        height = 10;
        width = 20;
    } else if (strcmp(mode, "medium") == 0) {
        height = 20;
        width = 40;
    } else if (strcmp(mode, "large") == 0) {
        height = 30;
        width = 60;
    }
    x = height / 2;
    y = width / 2;
    score = 0;
    snakeBody = malloc(sizeof(int) * 2 * (height * width)); //creates dynamic array to hold the x and y coordinates of
    snakeBody[0] = x;                                       //the x and y of the snake body ex: [segment 1: 1, segment 1: 1, segment 2: 1, segment 2: 2]
    snakeBody[1] = y;                                       //                                              x,            y,            x,            y

    srand(time(NULL));
    do {
        fruitx = rand() % (height - 2) + 1;  //do while loop that gets a random
        fruity = rand() % (width - 2) + 1;   //x and y coordinates for a fruit
    } while (fruitx == x || fruity == y);    //if the x and y equals the snake head then it tries again
}

void draw() {  //Draw function to draw all the borders, snake parts, fruits, and empty space
    gotoxy(1, 1);   //sends cursor to the coordinates 1,1

    printf("\033[?25l"); // ASCII to hide the cursor so when its printing the game it is not flashing across the screen

    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            if (i == 0 || i == height - 1 || j == 0 || j == width - 1){
                printf("#");
            } else if (i == fruitx && j == fruity) {
                printf("b");                                //For loop that draws different aspects determined by different conditions
            } else if (i == x && j == y) {
                    printf("O");
            } else {
                int isBody = 0;
                for (int k = 1; k < snakeLength; k++) {
                    if (i == snakeBody[2 * k] && j == snakeBody[2 * k + 1]) {
                        printf("0");
                        isBody = 1;
                        break;
                }
            }
            if (!isBody) {
                printf(" ");
                }
            }
        }
        printf("\n");
    }
    if (strcmp(mode, "small") == 0) {                   //separate print statements for each map size to
    printf("Score: %d Press X to Quit\n", score);       //make appearance of score and quit statment fit cleanly
    }
    if (strcmp(mode, "medium") == 0) {
    printf("Score: %d                 Press X to Quit\n", score);
    }
    if (strcmp(mode, "large") == 0) {
    printf("Score: %d                                     Press X to Quit\n", score);
    }
    fflush(stdout); //removes buffer so it immediately shows the printing


}

void input() {      //Input Function to get keyboard hits
    if (kbhit()) {
        switch (getch()) {
            case 'w':       //When "w" is clicked it sets x coordinate to go -1
                if (dx != 1) {  //if statement so only when your not going down
                    dx = -1;    //are you allowed to go up
                    dy = 0;     //applies to all directions where you cannot go opposite the direction currently going
                }
                break;
            case 's':       //When "s" is clicked it sets x coordinate to go +1
                if (dx != -1) {
                    dx = 1;
                    dy = 0;
                }
                break;
            case 'a':       //When "a" is clicked it sets y coordinate to go -1
                if (dy != 1) {
                    dx = 0;
                    dy = -1;
                }
                break;
            case 'd':       //When "d" is clicked it sets y coordinate to go +1
                if (dy != -1) {
                    dx = 0;
                    dy = 1;
                }
                break;
            case 'x':       //When "x" is clicked it sets game over to 1 and ends the game
                gameover = 1;
                break;
        }
    }
}

void updateGame() { //Update Game Function
    input(); //Calls input function to update direction

    // Move the head
    x += dx;
    y += dy;

    // Continuously make body segments take the place of the earlier body part. This makes the snake look like it is following the snake head
    for (int k = snakeLength - 1; k > 0; k--) {
        snakeBody[2 * k] = snakeBody[2 * (k - 1)];
        snakeBody[2 * k + 1] = snakeBody[2 * (k - 1) + 1];
    }

    // Update the position of the first body segment
    snakeBody[0] = x;
    snakeBody[1] = y;

}
int FruitBody (int fruitx, int fruity) { //Function so the fruit does not spawn in a body segment
    for (int k = 0; k < snakeLength; k++) {
    if (fruitx == snakeBody[2 * k] && fruity == snakeBody[2 * k + 1]) {
        return 1;
        }
    }
return 0;
}

void logic() {
    if (x == 0 || x == height - 1 || y == 0 || y == width - 1) {
        gameover = 1; // Snake hits the wall
        return;
    }
    for (int k = 1; k < snakeLength; k++){
    if (x == snakeBody[2 * k] && y == snakeBody[2 * k + 1]) {
        gameover = 1; // Snake hits its own body
        return;
        }
    }

    if (x == fruitx && y == fruity) {
        score++; //When the snake eats a fruit it increases body and score
        snakeLength++;

        do {  //Fruit spawn that happens when fruit is eaten, includes the function FruitBody so it does not spawn in snake body
            fruitx = rand() % (height - 2) + 1;
            fruity = rand() % (width - 2) + 1;
        } while (fruitx == x || fruity == y || FruitBody(fruitx, fruity));
    }
}

void clearScreen() {
    system("cls"); //Used to clear the screen after setup
}

void gotoxy(int x, int y) {
    printf("\033[%d;%dH", x, y); //goto function for moving cursor to the x and y coordinates. (ASCII for cursor)
}

void newHighscore () { // High Score File to store the information on the high score as well as read and write a new score if it is higher than previous
    FILE * highscore = fopen ("highscore.txt", "r");
    fscanf(highscore, "%d", &highScore);
    fclose(highscore);
    if (score > highScore) {
    highscore = fopen ("highscore.txt", "w");
    fprintf (highscore, "%d", score);
    fclose(highscore);
    highscore = fopen ("highscore.txt", "r");
    fscanf(highscore, "%d", &highScore);
    }


    fclose(highscore);
}

int main() { //Main used to call all the functions
    char playAgain; //character for playing again
    do {
    setup(); //do while loop so it loops the game if play again is chosen
    clearScreen();

    while (!gameover) {  //while loop that runs as long as game over is not equal to 1
        draw();  //First run draw function
        logic(); //Then check logic
        updateGame(); //Then update game accordingly
        usleep(100000); // Used to slow down the process so it is playable
    }

    newHighscore(); //Calls newHighscore function to check if there is a new high score

    printf("\033[?25h"); //Reveals cursor so you can see where you are writing to

    clearScreen(); //Clears screen of Game

    printf("Game Over! Final Score: %d  High Score: %d\n", score, highScore);
    printf("  Play Again? (y/n)   "); //Prints the GAMEOVER statement and asks if you want to play again
    scanf(" %c", &playAgain);
    playAgain = tolower(playAgain); //tolower makes all the inputs scanned into lower case so any input, "Y", or "y" will work

    clearScreen(); //Clears the print statements

    gameover = 0; //Resets all the variables that were changed in previous game
    snakeLength = 1;
    dx = 0;
    dy = 0;

    } while (playAgain == 'y'); //Do while loop so if they want to play again it goes through the whole game main function

    free(snakeBody); //If they do not want to play the game anymore then it frees the snakebody memory

    return 0;
}

这是到目前为止的代码。

我是编码新手,所以我不确定我到底应该更改什么以使其更易于访问。我喜欢现在的一些代码,比如 kbhit 和获取方向输入,但 conio.h 不是标准的,不能在 unix 系统上工作

c portability
© www.soinside.com 2019 - 2024. All rights reserved.