#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <string.h>
#define WIDTH 60
#define HEIGHT 20
typedef struct Food {
int x;
int y;
} Food;
typedef struct Snakenode {
int x;
int y;
struct Snakenode* next;
} Snakenode;
typedef struct PlayerRecord {
char username[50];
int totalScore;
int totalTime;
int gameCount;
} PlayerRecord;
// 全局变量
Snakenode* head = NULL;
Food food;
time_t start;
char username[50];
int direction = 1;
int playAgain = 0;
int snakeBody[WIDTH * HEIGHT][2];
int bodyCount = 0;
PlayerRecord records[100];
int recordCount = 0;
// 函数声明(修复核心问题)
void moveCursor(int x, int y);
void sortRecordsByUsername();
void loadAllRecords();
void showSortedRecords();
void init();
void makefood();
void move();
int alive();
void endGame();
int Score();
void saveData();
void showMap();
void viewData();
// 函数实现
void moveCursor(int x, int y) {
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
cursorInfo.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
void sortRecordsByUsername() {
for (int i = 0; i < recordCount - 1; i++) {
for (int j = 0; j < recordCount - i - 1; j++) {
if (strcmp(records[j].username, records[j + 1].username) > 0) {
PlayerRecord temp = records[j];
records[j] = records[j + 1];
records[j + 1] = temp;
}
}
}
}
void loadAllRecords() {
FILE* fp = fopen("score_and_time_and_username.txt", "r");
if (!fp) return;
char line[200];
char currentUser[50] = { 0 };
int currentScore = 0;
int currentTime = 0;
recordCount = 0;
while (fgets(line, sizeof(line), fp) != NULL) {
if (strstr(line, "用户名: ") == line) {
sscanf(line, "用户名: %s", currentUser);
}
else if (strstr(line, "分数: ") == line) {
sscanf(line, "分数: %d", ¤tScore);
}
else if (strstr(line, "时间: ") == line) {
sscanf(line, "时间: %d", ¤tTime);
int found = 0;
for (int i = 0; i < recordCount; i++) {
if (strcmp(records[i].username, currentUser) == 0) {
records[i].totalScore += currentScore;
records[i].totalTime += currentTime;
records[i].gameCount++;
found = 1;
break;
}
}
if (!found && recordCount < 100) {
strcpy(records[recordCount].username, currentUser);
records[recordCount].totalScore = currentScore;
records[recordCount].totalTime = currentTime;
records[recordCount].gameCount = 1;
recordCount++;
}
}
}
fclose(fp);
}
void showSortedRecords() {
system("cls");
loadAllRecords();
sortRecordsByUsername();
printf("===== 玩家总战绩(按用户名排序) =====\n");
printf("%-15s %-10s %-10s %-10s\n", "用户名", "总分数", "总时间", "游戏次数");
for (int i = 0; i < recordCount; i++) {
printf("%-15s %-10d %-10d %-10d\n", records[i].username, records[i].totalScore, records[i].totalTime, records[i].gameCount);
}
printf("\n按任意键返回...");
_getch();
}
void init() {
head = (Snakenode*)malloc(sizeof(Snakenode));
head->x = WIDTH / 2;
head->y = HEIGHT / 2;
head->next = NULL;
makefood();
start = time(NULL);
snakeBody[0][0] = head->x;
snakeBody[0][1] = head->y;
bodyCount = 1;
}
void makefood() {
food.x = rand() % WIDTH;
food.y = rand() % HEIGHT;
Snakenode* p = head;
while (p) {
if (p->x == food.x && p->y == food.y) {
makefood();
return;
}
p = p->next;
}
}
void move() {
int x = head->x;
int y = head->y;
switch (direction) {
case 0: y--; break;
case 1: x++; break;
case 2: y++; break;
case 3: x--; break;
}
Snakenode* newhead = NULL;
if (x == food.x && y == food.y) {
newhead = (Snakenode*)malloc(sizeof(Snakenode));
newhead->x = x;
newhead->y = y;
newhead->next = head;
head = newhead;
makefood();
snakeBody[bodyCount][0] = x;
snakeBody[bodyCount][1] = y;
bodyCount++;
}
else {
newhead = (Snakenode*)malloc(sizeof(Snakenode));
newhead->x = x;
newhead->y = y;
newhead->next = head;
head = newhead;
for (int i = bodyCount - 1; i > 0; i--) {
snakeBody[i][0] = snakeBody[i - 1][0];
snakeBody[i][1] = snakeBody[i - 1][1];
}
snakeBody[0][0] = x;
snakeBody[0][1] = y;
Snakenode* q = head;
while (q->next->next) {
q = q->next;
}
free(q->next);
q->next = NULL;
}
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT || alive()) {
endGame();
}
}
int alive() {
Snakenode* p = head->next;
while (p) {
if (p->x == head->x && p->y == head->y) {
return 1;
}
p = p->next;
}
return 0;
}
void endGame() {
system("cls");
time_t end = time(NULL);
int gameduration = (int)difftime(end, start);
printf("Game Over!\n");
printf("用户名:%s\n", username);
printf("分数: %d\n", Score());
printf("时间: %d 秒\n", gameduration);
printf("重新开始游戏请选择:\n");
printf("1. 重新开始\n");
printf("2. 查看保存的战绩\n");
saveData();
int choice;
scanf("%d", &choice);
if (choice == 1) {
playAgain = 1;
Snakenode* p = head;
while (p) {
Snakenode* temp = p;
p = p->next;
free(temp);
}
head = NULL;
head = (Snakenode*)malloc(sizeof(Snakenode));
head->x = WIDTH / 2;
head->y = HEIGHT / 2;
head->next = NULL;
makefood();
start = time(NULL);
bodyCount = 0;
}
else if (choice == 2) {
system("cls");
viewData();
printf("是否重新开始?(1. 重新开始,其他键退出)");
scanf("%d", &choice);
if (choice == 1) {
playAgain = 1;
Snakenode* p = head;
while (p) {
Snakenode* temp = p;
p = p->next;
free(temp);
}
head = NULL;
head = (Snakenode*)malloc(sizeof(Snakenode));
head->x = WIDTH / 2;
head->y = HEIGHT / 2;
head->next = NULL;
makefood();
start = time(NULL);
bodyCount = 0;
}
else {
exit(0);
}
}
else {
exit(0);
}
}
int Score() {
int score = 0;
Snakenode* p = head;
while (p) {
score++;
p = p->next;
}
return score - 1;
}
void saveData() {
int score = Score();
time_t end = time(NULL);
int gameDuration = (int)difftime(end, start);
FILE* fp = fopen("score_and_time_and_username.txt", "a");
if (fp) {
fprintf(fp, "用户名: %s\n", username);
fprintf(fp, "分数: %d\n", score);
fprintf(fp, "时间: %d 秒\n", gameDuration);
fclose(fp);
}
}
void showMap() {
moveCursor(0, 0);
for (int i = 0; i < WIDTH + 4; i++) {
printf("#");
}
printf("\n");
for (int j = 0; j < HEIGHT; j++) {
printf("##");
for (int i = 0; i < WIDTH; i++) {
if (i == head->x && j == head->y) {
printf("@");
}
else if (i == food.x && j == food.y) {
printf("$");
}
else {
int isSnake = 0;
for (int k = 0; k < bodyCount; k++) {
if (i == snakeBody[k][0] && j == snakeBody[k][1]) {
printf("@");
isSnake = 1;
break;
}
}
if (!isSnake) {
printf(" ");
}
}
}
printf("##\n");
}
for (int i = 0; i < WIDTH + 4; i++) {
printf("#");
}
moveCursor(WIDTH + 5, 0);
printf("用户: %s", username);
moveCursor(WIDTH + 5, 1);
printf("得分: %d", Score());
moveCursor(WIDTH + 5, 2);
printf("时间: %d 秒", (int)difftime(time(NULL), start));
printf("\n");
}
void viewData() {
FILE* fp = fopen("score_and_time_and_username.txt", "r");
if (fp) {
char line[200];
printf("保存的数据如下:\n");
while (fgets(line, sizeof(line), fp) != NULL) {
printf("%s", line);
}
fclose(fp);
}
else {
printf("没有保存的数据可查看。\n");
}
printf("\n1. 按用户名排序查看总战绩\n");
printf("2. 返回\n");
int choice;
scanf("%d", &choice);
if (choice == 1) {
showSortedRecords();
}
}
int main() {
char choice;
printf("菜单:\n");
printf("x - 进入游戏\n");
printf("c - 退出游戏\n");
scanf(" %c", &choice);
if (choice == 'x') {
printf("请输入用户名:");
scanf("%s", username);
srand((unsigned int)time(NULL));
do {
init();
while (1) {
showMap();
move();
if (_kbhit()) {
char key = _getch();
switch (key) {
case 'w': if (direction != 2) direction = 0; break;
case 'd': if (direction != 3) direction = 1; break;
case 's': if (direction != 0) direction = 2; break;
case 'a': if (direction != 1) direction = 3; break;
}
}
Sleep(100);
}
saveData();
} while (playAgain);
}
else if (choice == 'c') {
printf("已退出游戏。\n");
return 0;
}
else {
printf("无效的选择,请重新运行程序。\n");
return 0;
}
return 0;
}
添加每一行的注释