new copyright notice
[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
b7647a4b
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3783acaf
KM
16 */
17
18#ifndef lint
1a9aa6eb 19static char sccsid[] = "@(#)score.c 5.5 (Berkeley) %G%";
4cd7a139 20#endif /* not lint */
3783acaf
KM
21
22# include "robots.h"
678dc652 23# include <sys/types.h>
3783acaf 24# include <pwd.h>
1a9aa6eb 25# include "pathnames.h"
3783acaf
KM
26
27typedef struct {
28 int s_uid;
29 int s_score;
30 char s_name[MAXNAME];
31} SCORE;
32
33typedef struct passwd PASSWD;
34
1a9aa6eb 35char *Scorefile = _PATH_SCORE;
3783acaf
KM
36
37int Max_per_uid = MAX_PER_UID;
38
39static SCORE Top[MAXSCORES];
40
41/*
42 * score:
43 * Post the player's score, if reasonable, and then print out the
44 * top list.
45 */
46score()
47{
48 register int inf;
49 register SCORE *scp;
50 register int uid;
51 register bool done_show = FALSE;
52 static int numscores, max_uid;
53
54 Newscore = FALSE;
55 if ((inf = open(Scorefile, 2)) < 0) {
56 perror(Scorefile);
57 return;
58 }
59
60 if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
61 read(inf, Top, sizeof Top);
62 else {
63 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
64 scp->s_score = -1;
65 max_uid = Max_per_uid;
66 }
67
68 uid = getuid();
69 if (Top[MAXSCORES-1].s_score <= Score) {
70 numscores = 0;
71 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
72 if (scp->s_score < 0 ||
73 (scp->s_uid == uid && ++numscores == max_uid)) {
74 if (scp->s_score > Score)
75 break;
76 scp->s_score = Score;
77 scp->s_uid = uid;
78 set_name(scp);
79 Newscore = TRUE;
80 break;
81 }
82 if (scp == &Top[MAXSCORES]) {
83 Top[MAXSCORES-1].s_score = Score;
84 Top[MAXSCORES-1].s_uid = uid;
85 set_name(&Top[MAXSCORES-1]);
86 Newscore = TRUE;
87 }
88 if (Newscore)
89 qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
90 }
91
92 if (!Newscore) {
93 Full_clear = FALSE;
94 close(inf);
95 return;
96 }
97 else
98 Full_clear = TRUE;
99
100 for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
101 if (scp->s_score < 0)
102 break;
103 move((scp - Top) + 1, 15);
104 if (!done_show && scp->s_uid == uid && scp->s_score == Score)
105 standout();
106 printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
107 if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
108 standend();
109 done_show = TRUE;
110 }
111 }
112 Num_scores = scp - Top;
113 refresh();
114
115 if (Newscore) {
116 lseek(inf, 0L, 0);
117 write(inf, &max_uid, sizeof max_uid);
118 write(inf, Top, sizeof Top);
119 }
120 close(inf);
121}
122
123set_name(scp)
124register SCORE *scp;
125{
126 register PASSWD *pp;
127
128 if ((pp = getpwuid(scp->s_uid)) == NULL)
129 pp->pw_name = "???";
130 strncpy(scp->s_name, pp->pw_name, MAXNAME);
131}
132
133/*
134 * cmp_sc:
135 * Compare two scores.
136 */
137cmp_sc(s1, s2)
138register SCORE *s1, *s2;
139{
140 return s2->s_score - s1->s_score;
141}
142
143/*
144 * show_score:
145 * Show the score list for the '-s' option.
146 */
147show_score()
148{
149 register SCORE *scp;
150 register int inf;
151 static int max_score;
152
153 if ((inf = open(Scorefile, 0)) < 0) {
154 perror(Scorefile);
155 return;
156 }
157
158 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
159 scp->s_score = -1;
160
161 read(inf, &max_score, sizeof max_score);
162 read(inf, Top, sizeof Top);
163 close(inf);
164 inf = 1;
165 for (scp = Top; scp < &Top[MAXSCORES]; scp++)
166 if (scp->s_score >= 0)
167 printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
168}