-
Notifications
You must be signed in to change notification settings - Fork 0
/
scoreboard.c
106 lines (100 loc) · 2.94 KB
/
scoreboard.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
#include "scoreboard.h"
#include "fatal.h"
#include <stdlib.h>
#include <stdbool.h>
Scoreboard CreateScoreboard(int size)
{
Scoreboard sc;
if ((sc = (Scoreboard)malloc(sizeof(struct __scoreboard))) == NULL)
FatalError("Out of space!");
Record *rs;
if ((rs = (Record *)malloc(sizeof(Record) * size)) == NULL)
FatalError("Out of space!");
for (int i = 0; i < size; i++)
if ((rs[i] = (Record)malloc(sizeof(struct _record))) == NULL)
FatalError("Out of space!");
sc->records = rs;
sc->size = size;
return sc;
}
FILE *OpenScoreboardFile(void)
{
FILE *fp = fopen("score.txt", "r");
return fp;
}
void ReadScoreboard(Scoreboard sc)
{
FILE *fp_sc_r = OpenScoreboardFile();
int size = 0;
while (size < RECORD_MAX_NUM)
{
int status = ReadRecord(sc->records[size], fp_sc_r);
if (status != 2)
if (status != EOF)
FatalError("Incomplete data");
else
break;
size++;
}
sc->size = size;
if (fp_sc_r != NULL)
fclose(fp_sc_r);
}
/* 遍历后全部重新打印 */
unsigned int ShowScoreboardWithCurrentRecord(Scoreboard sc, Record cr, int y, int x)
{
bool showed = false;
unsigned int i, number = 0;
for (i = 0; i < sc->size; i++)
{
if (!showed && cr->score > sc->records[i]->score)
{
number = i + 1;
if (i < SHOWED_MAX_NUM)
ShowRecord(cr, number, y + i, x);
showed = true;
}
if (i + showed < SHOWED_MAX_NUM)
ShowRecord(sc->records[i], i + 1 + showed, y + i + showed, x);
}
if (!showed)
{
number = i + 1;
if (i < SHOWED_MAX_NUM)
ShowRecord(cr, number, y + i, x);
}
return number;
}
/* 1. 逻辑有些复杂(为了保持有序性、以及指定的一些规则)
* 2. 完全覆盖之前的文件内容
* 3. 没有加密
* 4. 效率还好吧(Ω(n))
*/
void WriteScoreboard(Scoreboard sc, Record cr, int found)
{
if (sc->size > RECORD_MAX_NUM)
FatalError("Records are full");
FILE *fp_sc_w = fopen("score.txt", "w");
bool written = false;
for (int i = 0; i < sc->size; i++)
{
/* 只写一次 && 合适的条件(原来没有记录 || 该记录比原记录大) && 合适的位置 */
if (!written && (found == -1 || cr->score > sc->records[found]->score ) && cr->score > sc->records[i]->score)
{
fprintf(fp_sc_w, "%s %u\n", cr->name, cr->score);
written = true;
}
if (i != found || cr->score <= sc->records[found]->score)
fprintf(fp_sc_w, "%s %u\n", sc->records[i]->name, sc->records[i]->score);
}
if (!written && found == -1)
fprintf(fp_sc_w, "%s %u\n", cr->name, cr->score);
fclose(fp_sc_w);
}
void DestroyScoreboard(Scoreboard sc)
{
for (int i = 0; i < sc->size; i++)
free(sc->records[i]);
free(sc->records);
free(sc);
}