1 #include <stdio.h>
2 #include <signal.h>
3 #include "sokoban.h"
4
5 extern FILE *fopen();
6
7 extern char *username;
8 extern short scorelevel, scoremoves, scorepushes;
9
10 static short scoreentries;
11 static struct {
12 char user[MAXUSERNAME];
13 short lv, mv, ps;
14 } scoretable[MAXSCOREENTRIES];
15
16 static FILE *scorefile;
17 static int sfdbn;
18
outputscore()19 short outputscore() {
20
21 short ret;
22
23 while( access(LOCKFILE,0) != -1); /* lock the score file */
24 creat(LOCKFILE,0666);
25 if( (ret = readscore()) == 0)
26 showscore();
27 unlink( LOCKFILE);
28 return( (ret == 0) ? E_ENDGAME : ret);
29 }
30
newscore()31 short newscore() {
32
33 short ret = 0;
34
35 while( access(LOCKFILE) != -1) ;
36 creat(LOCKFILE,0666);
37 scoreentries = 0;
38 if( (scorefile = fopen( SCOREFILE, "w")) == NULL)
39 ret = E_FOPENSCORE;
40 else {
41 sfdbn = fileno( scorefile);
42 if( write( sfdbn, &scoreentries, 2) != 2) ret = E_WRITESCORE;
43 fclose( scorefile);
44 }
45 unlink( LOCKFILE);
46 return( (ret == 0) ? E_ENDGAME : ret);
47 }
48
getuserlevel(lv)49 short getuserlevel( lv)
50 short *lv;
51 {
52 short ret = 0, pos;
53
54 while( access( LOCKFILE) != -1);
55 creat(LOCKFILE,0666);
56 if( (scorefile = fopen( SCOREFILE, "r")) == NULL)
57 ret = E_FOPENSCORE;
58 else {
59 if( (ret = readscore()) == 0)
60 *lv = ( (pos = finduser()) > -1) ? scoretable[pos].lv+1 : 1;
61 }
62 unlink( LOCKFILE);
63 return( ret);
64 }
65
score()66 short score() {
67
68 short ret;
69
70 while( access( LOCKFILE) != -1);
71 creat(LOCKFILE,0666);
72 if( (ret = readscore()) == 0)
73 if( (ret = makescore()) == 0)
74 if( (ret = writescore()) == 0)
75 showscore();
76 unlink( LOCKFILE);
77 return( (ret == 0) ? E_ENDGAME : ret);
78 }
79
readscore()80 readscore() {
81
82 short ret = 0;
83 int tmp;
84
85 if( (scorefile = fopen( SCOREFILE, "r")) == NULL)
86 ret = E_FOPENSCORE;
87 else {
88 sfdbn = fileno( scorefile);
89 if( read( sfdbn, &scoreentries, 2) != 2) ret = E_READSCORE;
90 else {
91 tmp = scoreentries * sizeof( scoretable[0]);
92 if( read( sfdbn, &(scoretable[0]), tmp) != tmp) ret = E_READSCORE;
93 }
94 fclose( scorefile);
95 }
96 return( ret);
97 }
98
makescore()99 makescore() {
100
101 short ret = 0, pos, i, build = 1, insert;
102
103 if( (pos = finduser()) > -1) { /* user already in score file */
104 insert = (scorelevel > scoretable[pos].lv)
105 || ( (scorelevel == scoretable[pos].lv) &&
106 (scoremoves < scoretable[pos].mv)
107 )
108 || ( (scorelevel == scoretable[pos].lv) &&
109 (scoremoves == scoretable[pos].mv) &&
110 (scorepushes < scoretable[pos].ps)
111 );
112 if( insert) { /* delete existing entry */
113 for( i = pos; i < scoreentries-1; i++)
114 cp_entry( i, i+1);
115 scoreentries--;
116 }
117 else build = 0;
118 }
119 else if( scoreentries == MAXSCOREENTRIES)
120 ret = E_TOMUCHSE;
121 if( (ret == 0) && build) {
122 pos = findpos(); /* find the new score position */
123 if( pos > -1) { /* score table not empty */
124 for( i = scoreentries; i > pos; i--)
125 cp_entry( i, i-1);
126 }
127 else pos = scoreentries;
128
129 strcpy( scoretable[pos].user, username);
130 scoretable[pos].lv = scorelevel;
131 scoretable[pos].mv = scoremoves;
132 scoretable[pos].ps = scorepushes;
133 scoreentries++;
134 }
135 return( ret);
136 }
137
finduser()138 finduser() {
139
140 short i, found = 0;
141
142 for( i = 0; (i < scoreentries) && (! found); i++)
143 found = (strcmp( scoretable[i].user, username) == 0);
144 return( (found) ? i-1 : -1);
145 }
146
findpos()147 findpos() {
148
149 short i, found = 0;
150
151 for( i = 0; (i < scoreentries) && (! found); i++)
152 found = (scorelevel > scoretable[i].lv)
153 || ( (scorelevel == scoretable[i].lv) &&
154 (scoremoves < scoretable[i].mv)
155 )
156 || ( (scorelevel == scoretable[i].lv) &&
157 (scoremoves == scoretable[i].mv) &&
158 (scorepushes < scoretable[i].ps)
159 );
160 return( (found) ? i-1 : -1);
161 }
162
writescore()163 writescore() {
164
165 short ret = 0;
166 long tmp;
167
168 if( (scorefile = fopen( SCOREFILE, "w")) == NULL)
169 ret = E_FOPENSCORE;
170 else {
171 sfdbn = fileno( scorefile);
172 if( write( sfdbn, &scoreentries, 2) != 2) ret = E_WRITESCORE;
173 else {
174 tmp = scoreentries * sizeof( scoretable[0]);
175 if( write( sfdbn, &(scoretable[0]), tmp) != tmp) ret = E_WRITESCORE;
176 }
177 fclose( scorefile);
178 }
179 return( ret);
180 }
181
showscore()182 showscore() {
183
184 register short lastlv = 0, lastmv = 0, lastps = 0, i;
185
186 fprintf( stdout, "Rank User Level Moves Pushes\n");
187 fprintf( stdout, "==============================================\n");
188 for( i = 0; i < scoreentries; i++) {
189 if( (scoretable[i].lv == lastlv)&&
190 (scoretable[i].mv == lastmv) &&
191 (scoretable[i].ps == lastps))
192 fprintf( stdout, " ");
193 else {
194 lastlv = scoretable[i].lv;
195 lastmv = scoretable[i].mv;
196 lastps = scoretable[i].ps;
197 fprintf( stdout, "%4d ", i+1);
198 }
199 fprintf( stdout, "%10s %8d %8d %8d\n", scoretable[i].user,
200 scoretable[i].lv, scoretable[i].mv, scoretable[i].ps);
201 }
202 }
203
cp_entry(i1,i2)204 cp_entry( i1, i2)
205 register short i1, i2;
206 {
207 strcpy( scoretable[i1].user, scoretable[i2].user);
208 scoretable[i1].lv = scoretable[i2].lv;
209 scoretable[i1].mv = scoretable[i2].mv;
210 scoretable[i1].ps = scoretable[i2].ps;
211 }
212