xref: /original-bsd/games/robots/score.c (revision e1db577d)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)score.c	5.6 (Berkeley) 06/01/90";
10 #endif /* not lint */
11 
12 # include	"robots.h"
13 # include	<sys/types.h>
14 # include	<pwd.h>
15 # include	"pathnames.h"
16 
17 typedef struct {
18 	int	s_uid;
19 	int	s_score;
20 	char	s_name[MAXNAME];
21 } SCORE;
22 
23 typedef struct passwd	PASSWD;
24 
25 char	*Scorefile = _PATH_SCORE;
26 
27 int	Max_per_uid = MAX_PER_UID;
28 
29 static SCORE	Top[MAXSCORES];
30 
31 /*
32  * score:
33  *	Post the player's score, if reasonable, and then print out the
34  *	top list.
35  */
36 score()
37 {
38 	register int	inf;
39 	register SCORE	*scp;
40 	register int	uid;
41 	register bool	done_show = FALSE;
42 	static int	numscores, max_uid;
43 
44 	Newscore = FALSE;
45 	if ((inf = open(Scorefile, 2)) < 0) {
46 		perror(Scorefile);
47 		return;
48 	}
49 
50 	if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
51 		read(inf, Top, sizeof Top);
52 	else {
53 		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
54 			scp->s_score = -1;
55 		max_uid = Max_per_uid;
56 	}
57 
58 	uid = getuid();
59 	if (Top[MAXSCORES-1].s_score <= Score) {
60 		numscores = 0;
61 		for (scp = Top; scp < &Top[MAXSCORES]; scp++)
62 			if (scp->s_score < 0 ||
63 			    (scp->s_uid == uid && ++numscores == max_uid)) {
64 				if (scp->s_score > Score)
65 					break;
66 				scp->s_score = Score;
67 				scp->s_uid = uid;
68 				set_name(scp);
69 				Newscore = TRUE;
70 				break;
71 			}
72 		if (scp == &Top[MAXSCORES]) {
73 			Top[MAXSCORES-1].s_score = Score;
74 			Top[MAXSCORES-1].s_uid = uid;
75 			set_name(&Top[MAXSCORES-1]);
76 			Newscore = TRUE;
77 		}
78 		if (Newscore)
79 			qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
80 	}
81 
82 	if (!Newscore) {
83 		Full_clear = FALSE;
84 		close(inf);
85 		return;
86 	}
87 	else
88 		Full_clear = TRUE;
89 
90 	for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
91 		if (scp->s_score < 0)
92 			break;
93 		move((scp - Top) + 1, 15);
94 		if (!done_show && scp->s_uid == uid && scp->s_score == Score)
95 			standout();
96 		printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
97 		if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
98 			standend();
99 			done_show = TRUE;
100 		}
101 	}
102 	Num_scores = scp - Top;
103 	refresh();
104 
105 	if (Newscore) {
106 		lseek(inf, 0L, 0);
107 		write(inf, &max_uid, sizeof max_uid);
108 		write(inf, Top, sizeof Top);
109 	}
110 	close(inf);
111 }
112 
113 set_name(scp)
114 register SCORE	*scp;
115 {
116 	register PASSWD	*pp;
117 
118 	if ((pp = getpwuid(scp->s_uid)) == NULL)
119 		pp->pw_name = "???";
120 	strncpy(scp->s_name, pp->pw_name, MAXNAME);
121 }
122 
123 /*
124  * cmp_sc:
125  *	Compare two scores.
126  */
127 cmp_sc(s1, s2)
128 register SCORE	*s1, *s2;
129 {
130 	return s2->s_score - s1->s_score;
131 }
132 
133 /*
134  * show_score:
135  *	Show the score list for the '-s' option.
136  */
137 show_score()
138 {
139 	register SCORE	*scp;
140 	register int	inf;
141 	static int	max_score;
142 
143 	if ((inf = open(Scorefile, 0)) < 0) {
144 		perror(Scorefile);
145 		return;
146 	}
147 
148 	for (scp = Top; scp < &Top[MAXSCORES]; scp++)
149 		scp->s_score = -1;
150 
151 	read(inf, &max_score, sizeof max_score);
152 	read(inf, Top, sizeof Top);
153 	close(inf);
154 	inf = 1;
155 	for (scp = Top; scp < &Top[MAXSCORES]; scp++)
156 		if (scp->s_score >= 0)
157 			printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
158 }
159