游戏使用文件输入/输出,高分存储和文件读取问题

时间:2016-01-01 21:42:55

标签: c file file-io io

这是一个使用文件输入输出的基础轰炸游戏。高分存储器存储在二进制文件中,但是当再次播放游戏时,先前的高分数在执行时显示为零。每次新玩家成为高分文件时,文件中的二进制数据会根据他的分数和名称进行更改。

我在显示高分辨名称时也遇到了问题。 如果有人收到使用fopen_s而不是fopen的错误,那么转到项目属性并在预处理器定义中添加_CRT_SECURE_NO_WARNINGS;

/*

* BASE BOMBER: A Simple Computer Game

* Created by Muhammad Kaab and Muhammad irteza khan, 1/1/2016

*/

#include <stdio.h>             /* for printf() and file I/O functions */ 

#include <stdlib.h>            /* for rand() function */

#include <ctype.h>             /* for toupper() function */

#include<conio.h>              /* for getch() function */ 

#include<time.h>               /* for time(NULL) function */ 

#include <math.h>              /* for sqrt() function */ 

#include <string.h>            /* for strcmp() function */                                      




#define HIGHSCOREFILE "hiscore.txt"

#define CHEATCODE "Cheater"

#define GRIDSIZE_X 150

#define GRIDSIZE_Y 150

#define MAXBOMBS 100

#define TIMELIMIT 500

#define MAXBUFFLEN 50

#define MAXNAMELEN 50




/* Data structure for grid coordinates */


struct coordinates

{
int x;
int y;

};


/* Data structure for the player's name and score */


struct player

{
char name[MAXNAMELEN];
unsigned long score;

};


void get_coordinates(struct coordinates  *guess)

{
char buffer[MAXBUFFLEN];
enum { FALSE, TRUE } outofrange;

do {

    /* Ask the player for the bomb coordinates in the required format */

    printf("Enter bomb coordinates: ");
    fgets(buffer, MAXBUFFLEN, stdin);
    sscanf(buffer, "(%u,%u)", &guess->x, &guess->y);

    /* Check whether the player entered some valid coordinates */

    if (guess->x > GRIDSIZE_X)
    {
        outofrange = TRUE;
    }

    else if (guess->y > GRIDSIZE_Y)
    {
        outofrange = TRUE;
    }

    else
    {
        outofrange = FALSE;
    }

    /* If the entered values are invalid then tell the player to reenter 
them in the correct format */

    if (outofrange == TRUE)
    {
        printf("Those coordinates not valid.\n");
        printf("Please enter some valid coordinates like this: (%u,%u)\n", 
rand() % GRIDSIZE_X, rand() % GRIDSIZE_Y);
        printf("The top left corner of the grid is (0,0)\n\tand the bottom 
right corner is (%u,%u).\n", GRIDSIZE_X - 1, GRIDSIZE_Y - 1);
    }
} while (outofrange == TRUE);


}



int main()

{
FILE *scorefile;
char buffer[MAXBUFFLEN];
struct coordinates    target, guess;
struct  player        player, highscore;
double distance;
int bombs, starttime, timeleft, timelimit, i;
timelimit = 0;



printf("\n*********************************\n");
printf("***                          ***\n");
printf("***   Welcome to BASE BOMBER    ***\n");
printf("***                          ***\n");
printf("*********************************\n\n");


/* Choose the target base location */

srand(time(NULL));
target.x = rand() % GRIDSIZE_X;
target.y = rand() % GRIDSIZE_Y;
bombs = MAXBOMBS;

/* Ask the player for their name and store it in the player structure */

printf("Please tell me your name, Captain.\n");
printf("Your name: ");
fgets(player.name, MAXNAMELEN, stdin);

/* Remove the newline character stored by fgets by replacing it with a null 
*/
for (i = 0; player.name[i] != '\0'; i++)
{
    if (player.name[i] == '\n')
    {
        player.name[i] = '\0';
    }
}

/* Convert the first character of the player's name into uppercase */

player.name[0] = toupper(player.name[0]);
printf("\nNice to meet you, Captain %s.\n", player.name);

/* set the player's score to zero */

player.score = 0;

/* If a previous high score was saved, retrieve and store it in the 
highscore structure */
highscore.score = 0;
scorefile = fopen(HIGHSCOREFILE, "r");

/* Only read the highscore if the highscore file could be opened */

if (scorefile != 0)
{
    if (fread(&highscore, sizeof(struct player), 1, scorefile) != 0)
    {
        fclose(scorefile);
    }
}

/* Display the game rules and objective */

printf("\nYour mission:\n");
printf(" You have %u seconds to locate and bomb the target base.\n", 
TIMELIMIT);
printf(" The target base is located on a %u x %u grid.\n", GRIDSIZE_X, 
GRIDSIZE_Y);
printf(" We do not know where exactly the target base is, but we can 
intercept their\n\tradio communications.\n");
printf(" Every time a bomb is dropped, they report the distance of bomb from 
their\n\tbase to their HQ by radio.\n");
printf(" We will intercept and tell you this information so that you can 
decide\n\twhere to drop the next bomb.\n");
printf(" Enter the (x,y) coordinates of the target like this: (%u,%u)\n", 
rand() % GRIDSIZE_X, rand() % GRIDSIZE_Y);
printf(" We only have %u bombs and each bomb is expensive, so try not to 
waste bombs.\n", bombs);
printf(" Good luck!\n\n");
printf("Press ENTER to start the mission. The timer will start 
immediately.\n");

fgets(buffer, MAXBUFFLEN, stdin);

/* Get the current time in seconds and calculate the game expiry time */

starttime = time(NULL);
timelimit = starttime + TIMELIMIT;

/* If the user entered the cheatcode, inform them of the target base 
coordinates */

if (strcmp(player.name, CHEATCODE) == 0)
{
    printf("Good news! Our spy just reported that the target base is at 
(%u,%u).\n\n", target.x, target.y);
}


/* This is the main game loop */

while (true)
{
    /* Calculate the time remaining and tell the player */

    timeleft = timelimit - time(NULL);
    printf("Countdown until mission ends: %u minutes", timeleft / 60);

    if ((timeleft % 60) != 0)
    {
        printf(", %u seconds.\n", (timeleft % 60));
    }
    else
        printf(" exactly.\n");

    /* Tell the player how many bombs are remaining */
    /* We display "There are n bombs left." if n > 1, otherwise we display 
"There is only 1 bomb left." */

    printf("There %s %u bomb%s left.\n", (bombs>1) ? "are" : "is", bombs, 
(bombs>1) ? "s" : "");

    /* Get the coordinates from the player */

    get_coordinates(&guess);

    /* Check that the time has not passed the expiry time */

    timeleft = timelimit - time(NULL);

    if (timeleft <= 0)
    {
        printf("\nSorry, Captain %s, you ran out of time!\n", player.name);
        printf("Mission failed.\n");
        break;
    }

    /* Calculate the Euclidean distance of the bomb from the target base 
using Pythagorus's theorem */

    distance = (((double)target.x - (double)guess.x)*((double)target.x - 
(double)guess.x)) + ((((double)target.y - (double)guess.y)*((double)target.y 
- (double)guess.y)));
    distance = sqrt(distance);

    /* Check whether the player hit the target */

    if (distance == 0)
    {
        printf("\nCongratulations, Captain %s! You successfully bombed the 
target base!\n", player.name);
        printf("Mission accomplished!\n");

        /* Calculate the player's final score */

        player.score = timeleft + 50 * bombs;
        break;
    }

    else
    {
        printf("The bomb was dropped at (%u,%u)\n", guess.x, guess.y);
        printf("The distance of the bomb from the target base was %lf\n\n", 
distance);
    }

    /* Decrement the number of bombs and end the game if there are no bombs 
left */

    bombs--;

    if (bombs == 0)
    {
        printf("Sorry, Captain %s, there are no more bombs left!\n", 
player.name);
        printf("Mission failed.\n");
        break;
    }
}

/* Display the player's score */

printf("\nYou scored %u points!\n", player.score);

/* If a highscore has been previously saved, then tell the player what it 
was */

if (highscore.name != 0)
{
    printf("The highest score earned was %u points by Major %s.\n", 
highscore.score, highscore.name);

}
/* If the player has beaten the highscore and did not cheat, then save the 
player's name and score in the highscore file */

if (((player.score > highscore.score) && strcmp(player.name, CHEATCODE)) != 
0)
{
    printf("You have beaten the highest score and earned a promotion!\n");
    printf("Well done, Major %s!\n", player.name);

    /* Try to open the highscore file for writing, overwriting it if it 
already exists */

    scorefile = fopen(HIGHSCOREFILE, "w");

    /* Only save the player's name and score if the highscore file could be 
opened */

    if (scorefile != NULL)
    {
        fwrite(&player, sizeof(char), MAXBUFFLEN, scorefile);
        fclose(scorefile);
    }
}
_getch();

return (0);

}

1 个答案:

答案 0 :(得分:1)

您正在以不同的方式阅读和编写数据:

if (fread(&highscore, sizeof(struct player), 1, scorefile) != 0)
{
    fclose(scorefile);
}

此处,会读入struct player(您还需要将fclose()置于此区域之外。

scorefile = fopen(HIGHSCOREFILE, "w");

if (scorefile != NULL)
{
    fwrite(&player, sizeof(char), MAXBUFFLEN, scorefile);
    fclose(scorefile);
}

此处,MAXBUFFLEN == 50,这也是名称的长度,因此没有存储分数。你还必须在这里写一个struct player

fwrite(&player, sizeof(struct player), 1, scorefile);

请参阅:

#define MAXBUFFLEN 50
#define MAXNAMELEN 50

struct player
{
    char name[MAXNAMELEN];
    unsigned long score;
};