-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscores.c
171 lines (134 loc) · 4.26 KB
/
scores.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* Tornado - Two player weather action game
*
* Copyright (c) 2000 Rene Puls ([email protected])
* Copyright (c) 2001-2002 Oliver Feiler ([email protected])
*
* scores.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <stdio.h>
#include <string.h>
#include "scores.h"
struct highscore_entry {
char player[MAX_PLAYER_LEN];
int score;
};
/* Read the score file into an array of highscore_entry.
* The array must be large enough to hold ten (10) entries.
*/
static int read_score_file(struct highscore_entry scores[]) {
FILE *scorefile;
char line[128];
char *tmp;
int i;
scorefile = fopen(SCOREFILE_NAME, "r");
if (scorefile == NULL) {
/* error opening score file */
return -1;
}
fgets(line, sizeof(line), scorefile);
fgets(line, sizeof(line), scorefile);
for (i=0; i < 10; ++i) {
if (fgets(line, sizeof(line), scorefile) == NULL) {
/* error reading file */
return -1;
}
line[strlen(line)-1] = '\0'; /* remove trailing newline */
/* We now need to split the line at the \t character. */
tmp = strchr(line, '\t');
if (tmp == NULL) /* Abort if there is no \t */
return -1;
/* Split the strings and advance tmp so that it points to the second
part (the actual highscore number). */
*tmp = '\0';
tmp++;
if (*tmp == '\0') /* Abort if there is no score... */
return -1;
/* check if the player name is not too long, otherwise truncate it */
if (strlen(line) > MAX_PLAYER_LEN-1)
line[MAX_PLAYER_LEN-1] = '\0';
strcpy(scores[i].player, line);
sscanf(tmp, "%d", &scores[i].score);
}
fclose(scorefile);
return 0;
}
/* Writes a highscore_entry[10] array to the score file on disk. */
static int write_score_file(struct highscore_entry scores[]) {
FILE *scorefile;
char line[128];
int i;
scorefile = fopen(SCOREFILE_NAME, "w");
if (scorefile == NULL) {
/* error opening score file */
return -1;
}
fprintf(scorefile, "# Tornado highscores file - do not edit! Editing voids the file's warranty! ;-)\n\n");
for (i=0; i<10; ++i) {
sprintf(line, "%s\t%d\n", scores[i].player, scores[i].score);
fputs(line, scorefile);
}
fclose(scorefile);
return(0);
}
/* Add a new high score to the score file.
*
* This function checks if the score deserves to get into the score file,
* and adds it if necessary.
*/
int highscore_add(char const *player, int const score)
{
struct highscore_entry scores[11];
struct highscore_entry temp;
int i;
if (read_score_file(scores) == -1) {
/* error reading score file */
return -1;
}
/* add the new score at the bottom */
strncpy(scores[10].player, player, MAX_PLAYER_LEN-1);
scores[10].score = score;
/* now sort the table */
for (i = 10; i > 0; --i) {
if (scores[i].score > scores[i-1].score) {
/* switch the highscore entries */
memcpy(&temp, &scores[i-1], sizeof(scores[i-1]));
memcpy(&scores[i-1], &scores[i], sizeof(scores[i]));
memcpy(&scores[i], &temp, sizeof(temp));
}
}
if (write_score_file(scores) == -1) {
/* error reading score file */
return -1;
}
return 0;
}
/* Returns the highscore from the given rank on table. */
int highscore_get(int const rank, char *player, int *score)
{
struct highscore_entry scores[10];
/* FIXME: this should probably be done only once, not for every call */
if (read_score_file(scores) == -1) {
/* error reading score file */
*score = -1;
player = NULL;
return -1;
}
strcpy(player, scores[rank-1].player);
*score = scores[rank-1].score;
return 0;
}