c-使用文件输入/输出的游戏,文件中的高核心存储和读取问题



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

我在显示highscorer的名称时也遇到了问题。如果有人错误地使用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)ntand 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("*********************************nn");

/* 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] != ''; i++)
{
    if (player.name[i] == 'n')
    {
        player.name[i] = '';
    }
}
/* 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 theirntradio communications.n");
printf(" Every time a bomb is dropped, they report the distance of bomb from 
theirntbase to their HQ by radio.n");
printf(" We will intercept and tell you this information so that you can 
decidentwhere 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!nn");
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).nn", 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 %lfnn", 
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);
}

您正在以不同的方式读取和写入数据:

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

最新更新