这是一个使用文件输入输出的基础轰炸游戏。高分存储器存储在二进制文件中,但是当再次播放游戏时,先前的高分数在执行时显示为零。每次新玩家成为高分文件时,文件中的二进制数据会根据他的分数和名称进行更改。
我在显示高分辨名称时也遇到了问题。
如果有人收到使用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);
}
答案 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;
};