xref: /original-bsd/games/robots/score.c (revision 23c6a147)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
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.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)score.c	5.5 (Berkeley) 05/02/90";
20 #endif /* not lint */
21 
22 # include	"robots.h"
23 # include	<sys/types.h>
24 # include	<pwd.h>
25 # include	"pathnames.h"
26 
27 typedef struct {
28 	int	s_uid;
29 	int	s_score;
30 	char	s_name[MAXNAME];
31 } SCORE;
32 
33 typedef struct passwd	PASSWD;
34 
35 char	*Scorefile = _PATH_SCORE;
36 
37 int	Max_per_uid = MAX_PER_UID;
38 
39 static SCORE	Top[MAXSCORES];
40 
41 /*
42  * score:
43  *	Post the player's score, if reasonable, and then print out the
44  *	top list.
45  */
46 score()
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 
123 set_name(scp)
124 register 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  */
137 cmp_sc(s1, s2)
138 register 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  */
147 show_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 }
169