date and time created 88/06/01 18:32:07 by bostic
[unix-history] / usr / src / games / robots / score.c
CommitLineData
3783acaf
KM
1/*
2 * Copyright (c) 1980 Regents of the University of California.
4cd7a139
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that this notice is preserved and that due credit is given
7 * to the University of California at Berkeley. The name of the University
8 * may not be used to endorse or promote products derived from this
9 * software without specific prior written permission. This software
10 * is provided ``as is'' without express or implied warranty.
3783acaf
KM
11 */
12
13#ifndef lint
4cd7a139
KB
14static char sccsid[] = "@(#)score.c 5.2 (Berkeley) %G%";
15#endif /* not lint */
3783acaf
KM
16
17# include "robots.h"
18# include <pwd.h>
19
20typedef struct {
21 int s_uid;
22 int s_score;
23 char s_name[MAXNAME];
24} SCORE;
25
26typedef struct passwd PASSWD;
27
28char *Scorefile = SCOREFILE;
29
30int Max_per_uid = MAX_PER_UID;
31
32static SCORE Top[MAXSCORES];
33
34/*
35 * score:
36 * Post the player's score, if reasonable, and then print out the
37 * top list.
38 */
39score()
40{
41 register int inf;
42 register SCORE *scp;
43 register int uid;
44 register bool done_show = FALSE;
45 static int numscores, max_uid;
46
47 Newscore = FALSE;
48 if ((inf = open(Scorefile, 2)) < 0) {
49 perror(Scorefile);
50 return;
51 }
52
53 if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
54 read(inf, Top, sizeof Top);
55 else {
56 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
57 scp->s_score = -1;
58 max_uid = Max_per_uid;
59 }
60
61 uid = getuid();
62 if (Top[MAXSCORES-1].s_score <= Score) {
63 numscores = 0;
64 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
65 if (scp->s_score < 0 ||
66 (scp->s_uid == uid && ++numscores == max_uid)) {
67 if (scp->s_score > Score)
68 break;
69 scp->s_score = Score;
70 scp->s_uid = uid;
71 set_name(scp);
72 Newscore = TRUE;
73 break;
74 }
75 if (scp == &Top[MAXSCORES]) {
76 Top[MAXSCORES-1].s_score = Score;
77 Top[MAXSCORES-1].s_uid = uid;
78 set_name(&Top[MAXSCORES-1]);
79 Newscore = TRUE;
80 }
81 if (Newscore)
82 qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
83 }
84
85 if (!Newscore) {
86 Full_clear = FALSE;
87 close(inf);
88 return;
89 }
90 else
91 Full_clear = TRUE;
92
93 for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
94 if (scp->s_score < 0)
95 break;
96 move((scp - Top) + 1, 15);
97 if (!done_show && scp->s_uid == uid && scp->s_score == Score)
98 standout();
99 printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
100 if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
101 standend();
102 done_show = TRUE;
103 }
104 }
105 Num_scores = scp - Top;
106 refresh();
107
108 if (Newscore) {
109 lseek(inf, 0L, 0);
110 write(inf, &max_uid, sizeof max_uid);
111 write(inf, Top, sizeof Top);
112 }
113 close(inf);
114}
115
116set_name(scp)
117register SCORE *scp;
118{
119 register PASSWD *pp;
120
121 if ((pp = getpwuid(scp->s_uid)) == NULL)
122 pp->pw_name = "???";
123 strncpy(scp->s_name, pp->pw_name, MAXNAME);
124}
125
126/*
127 * cmp_sc:
128 * Compare two scores.
129 */
130cmp_sc(s1, s2)
131register SCORE *s1, *s2;
132{
133 return s2->s_score - s1->s_score;
134}
135
136/*
137 * show_score:
138 * Show the score list for the '-s' option.
139 */
140show_score()
141{
142 register SCORE *scp;
143 register int inf;
144 static int max_score;
145
146 if ((inf = open(Scorefile, 0)) < 0) {
147 perror(Scorefile);
148 return;
149 }
150
151 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
152 scp->s_score = -1;
153
154 read(inf, &max_score, sizeof max_score);
155 read(inf, Top, sizeof Top);
156 close(inf);
157 inf = 1;
158 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
159 if (scp->s_score >= 0)
160 printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
161}