score.c revision 1.1
1/*	$NetBSD: score.c,v 1.3 1995/04/22 10:09:12 cgd Exp $	*/
2
3/*
4 * Copyright (c) 1980, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by the University of
18 *	California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)score.c	8.1 (Berkeley) 5/31/93";
39#else
40static char rcsid[] = "$NetBSD: score.c,v 1.3 1995/04/22 10:09:12 cgd Exp $";
41#endif
42#endif /* not lint */
43
44# include	"robots.h"
45# include	<sys/types.h>
46# include	<pwd.h>
47# include	"pathnames.h"
48
49typedef struct {
50	int	s_uid;
51	int	s_score;
52	char	s_name[MAXNAME];
53} SCORE;
54
55typedef struct passwd	PASSWD;
56
57char	*Scorefile = _PATH_SCORE;
58
59int	Max_per_uid = MAX_PER_UID;
60
61static SCORE	Top[MAXSCORES];
62
63/*
64 * score:
65 *	Post the player's score, if reasonable, and then print out the
66 *	top list.
67 */
68score()
69{
70	register int	inf;
71	register SCORE	*scp;
72	register int	uid;
73	register bool	done_show = FALSE;
74	static int	numscores, max_uid;
75
76	Newscore = FALSE;
77	if ((inf = open(Scorefile, 2)) < 0) {
78		perror(Scorefile);
79		return;
80	}
81
82	if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
83		read(inf, Top, sizeof Top);
84	else {
85		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
86			scp->s_score = -1;
87		max_uid = Max_per_uid;
88	}
89
90	uid = getuid();
91	if (Top[MAXSCORES-1].s_score <= Score) {
92		numscores = 0;
93		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
94			if (scp->s_score < 0 ||
95			    (scp->s_uid == uid && ++numscores == max_uid)) {
96				if (scp->s_score > Score)
97					break;
98				scp->s_score = Score;
99				scp->s_uid = uid;
100				set_name(scp);
101				Newscore = TRUE;
102				break;
103			}
104		if (scp == &Top[MAXSCORES]) {
105			Top[MAXSCORES-1].s_score = Score;
106			Top[MAXSCORES-1].s_uid = uid;
107			set_name(&Top[MAXSCORES-1]);
108			Newscore = TRUE;
109		}
110		if (Newscore)
111			qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
112	}
113
114	if (!Newscore) {
115		Full_clear = FALSE;
116		close(inf);
117		return;
118	}
119	else
120		Full_clear = TRUE;
121
122	for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
123		if (scp->s_score < 0)
124			break;
125		move((scp - Top) + 1, 15);
126		if (!done_show && scp->s_uid == uid && scp->s_score == Score)
127			standout();
128		printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
129		if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
130			standend();
131			done_show = TRUE;
132		}
133	}
134	Num_scores = scp - Top;
135	refresh();
136
137	if (Newscore) {
138		lseek(inf, 0L, 0);
139		write(inf, &max_uid, sizeof max_uid);
140		write(inf, Top, sizeof Top);
141	}
142	close(inf);
143}
144
145set_name(scp)
146register SCORE	*scp;
147{
148	register PASSWD	*pp;
149
150	if ((pp = getpwuid(scp->s_uid)) == NULL)
151		pp->pw_name = "???";
152	strncpy(scp->s_name, pp->pw_name, MAXNAME);
153}
154
155/*
156 * cmp_sc:
157 *	Compare two scores.
158 */
159cmp_sc(s1, s2)
160register SCORE	*s1, *s2;
161{
162	return s2->s_score - s1->s_score;
163}
164
165/*
166 * show_score:
167 *	Show the score list for the '-s' option.
168 */
169show_score()
170{
171	register SCORE	*scp;
172	register int	inf;
173	static int	max_score;
174
175	if ((inf = open(Scorefile, 0)) < 0) {
176		perror(Scorefile);
177		return;
178	}
179
180	for (scp = Top; scp < &Top[MAXSCORES]; scp++)
181		scp->s_score = -1;
182
183	read(inf, &max_score, sizeof max_score);
184	read(inf, Top, sizeof Top);
185	close(inf);
186	inf = 1;
187	for (scp = Top; scp < &Top[MAXSCORES]; scp++)
188		if (scp->s_score >= 0)
189			printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
190}
191